Here is a pretty fancy “trick” for the ones who wants to block certain parts of the world from accessing your VPS.
first of all you need to know the netblocks for the country you want to block, this information can be found at this page, each country has their own file in CIDR format.
Then we can add those netblocks to IPTABLES and “problem solved”.
Save below script as root user to “country.block.iptables.sh” and change the ISO variable to match the country name using ISO country codes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
#!/bin/bash ### Block all traffic from AFGHANISTAN (af) and CHINA (CN). Use ISO code ### ISO="af cn" ### Set PATH ### IPT=/sbin/iptables WGET=/usr/bin/wget EGREP=/bin/egrep ### No editing below ### SPAMLIST="countrydrop" ZONEROOT="/root/iptables" DLROOT="http://www.ipdeny.com/ipblocks/data/countries" cleanOldRules(){ $IPT -F $IPT -X $IPT -t nat -F $IPT -t nat -X $IPT -t mangle -F $IPT -t mangle -X $IPT -P INPUT ACCEPT $IPT -P OUTPUT ACCEPT $IPT -P FORWARD ACCEPT } # create a dir [ ! -d $ZONEROOT ] && /bin/mkdir -p $ZONEROOT # clean old rules cleanOldRules # create a new iptables list $IPT -N $SPAMLIST for c in $ISO do # local zone file tDB=$ZONEROOT/$c.zone # get fresh zone file $WGET -O $tDB $DLROOT/$c.zone # country specific log message SPAMDROPMSG="$c Country Drop" # get BADIPS=$(egrep -v "^#|^$" $tDB) for ipblock in $BADIPS do $IPT -A $SPAMLIST -s $ipblock -j LOG --log-prefix "$SPAMDROPMSG" $IPT -A $SPAMLIST -s $ipblock -j DROP done done # Drop everything $IPT -I INPUT -j $SPAMLIST $IPT -I OUTPUT -j $SPAMLIST $IPT -I FORWARD -j $SPAMLIST # call your other iptable script # /path/to/other/iptables.sh exit 0 |
When you are done, make sure it updates atleast weekly so it inludes recently added IP, this will be done by adding the following as a cron job.
first execute:
1 2 3 |
crontab -e |
add:
1 2 3 |
@weekly /path/to/country.block.iptables.sh |
close and save.
To start blocking immediately type:
1 2 3 |
# /path/to/country.block.iptables.sh |
Found this site via LET and glad I visited – hope you go from strength to strength. This script is brilliant and is now in use on my VPS. Saves me trying to ban via htaccess!!
Hello,
Nice tip, but you don’t say that this script will remove all iptables settings from your system. Because of that you need to add next to this script :
#This will remove your settings. Add your old rules. Ex. for SSH on port 22.
#Check -i settings too. Remove # befor iptabeles to use this rules.
# If you don’t have your own rules, don’t use this 😉
#iptables -I INPUT -p tcp –dport 22 -i eth0 -m state –state NEW -m recent –set
#iptables -I INPUT -p tcp –dport 22 -i eth0 -m state –state NEW -m recent –update –seconds 90 –hitcount 4 -j DROP
Hello,
thank you for the input.
If you take a closer look at the script it does say this:
# clean old rules
cleanOldRules
which run, among other things, IPTABLES -F
That will flush all your previous rules.
Easiest way to fix this is to find this in the script:
# call your other iptable script
# /path/to/other/iptables.sh
remove the # from the second line and update the path to your own iptables file. (which should not include an IPTABLES -F).
Hope it helps.
Hello again,
I agree with you. Your solution is good for advanced users, but most of VPS users will take care only about SSH security, because of that i wrote this part of script, but after all this is only for sys admins and use it only if you are sure what you are doing.
You need to know, that after this settings your system will use more server memory, and if you don’t have it, i propose you to learn how to use ipset framework.
Thanks and cheers !
That’s the beauty with it 🙂
There are never one specific solution, you can do something in a thousand ways and still manage to get the needed solution.
and thats why i wrote this little baby!
https://gist.github.com/anonymous/7415239
it uses ipset and does everything in 5 lines of code 🙂
Thanks for the great work!.
Ipdeny now offers aggregated IP blocks. Can I still use the script with the aggregated zone files?
Hi,
Just tried this script on a Centos 6.7 VPS and it fails with Memory allocation problem, so not usable.
ans to Stingray: ipsets are blocked on a VPS so cannot use that either.
You not need to use CleanOldRules
because if you already have good rule, not need to delete, then remove that line from script and just upload this script in your iptables
For those getting a syntax error please use this.
#!/bin/bash
### Block all traffic from AFGHANISTAN (af) and CHINA (CN). Use ISO code ###
ISO=”af cn”
### Set PATH ###
IPT=/sbin/iptables
WGET=/usr/bin/wget
EGREP=/bin/egrep
### No editing below ###
SPAMLIST=”countrydrop”
ZONEROOT=”/root/iptables”
DLROOT=”http://www.ipdeny.com/ipblocks/data/countries”
cleanOldRules(){
$IPT -F
$IPT -X
$IPT -t nat -F
$IPT -t nat -X
$IPT -t mangle -F
$IPT -t mangle -X
$IPT -P INPUT ACCEPT
$IPT -P OUTPUT ACCEPT
$IPT -P FORWARD ACCEPT
}
# create a dir
[ ! -d $ZONEROOT ] & /bin/mkdir -p $ZONEROOT
# clean old rules
cleanOldRules
# create a new iptables list
$IPT -N $SPAMLIST
for c in $ISO
do
# local zone file
tDB=$ZONEROOT/$c.zone
# get fresh zone file
$WGET -O $tDB $DLROOT/$c.zone
# country specific log message
SPAMDROPMSG=”$c Country Drop”
# get
BADIPS=$(egrep -v “^#|^$” $tDB)
for ipblock in $BADIPS
do
$IPT -A $SPAMLIST -s $ipblock -j LOG –log-prefix “$SPAMDROPMSG”
$IPT -A $SPAMLIST -s $ipblock -j DROP
done
done
# Drop everything
$IPT -I INPUT -j $SPAMLIST
$IPT -I OUTPUT -j $SPAMLIST
$IPT -I FORWARD -j $SPAMLIST
# call your other iptable script
# /path/to/other/iptables.sh
exit 0