-
-
Save angelflo/e33bde4a71554d3a486fd520d344af12 to your computer and use it in GitHub Desktop.
Block countries using iptables + ipset + ipdeny.com
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# ipset-country | |
# Block countries using iptables + ipset + ipdeny.com | |
# run this script from cron, e.g. /etc/cron.daily | |
# to run on boot you can also add it to e.g. /etc/rc.local | |
# please note: this script will insert an iptables REJECT | |
# rule as second to last in the INPUT chain for ipset | |
# specify countries to block as ISOCODE,Name | |
# multiple entries should be seperated by semicolon | |
# For example: "CN,China; United States,US Russia,RU" | |
# alternative script: https://github.com/tokiclover/dotfiles/blob/master/bin/ips.bash | |
country="CN,China" | |
iptables="/etc/iptables/rules.v4" | |
# using aggregated block zone files which are smaller | |
# ( full zone files: ".../data/countries/<iso>.zone" ) | |
urlipdeny="http://www.ipdeny.com/ipblocks/data/aggregated" | |
log="/var/log/ipset-country.log" | |
#log="/dev/null 2>&1" | |
# ipset cmds: "ipset list", ipset test setname <ip>", "ipset flush" "destroy" | |
IFS=";" | |
for c in $country; do | |
iso="$( echo "$c" | tr '[:upper:]' '[:lower:]' | cut -d"," -f 1 | sed -e 's/\(^ \+\| \+$\)//g' )" | |
cname="$( echo "$c" | tr '[:upper:]' '[:lower:]' | cut -d"," -f 2 | sed -e 's/\(^ \+\| \+$\)//g' -e 's/ /_/g' )" | |
zfile="${iso}-aggregated.zone" | |
# create a new set using type hash | |
{ ipset list -terse "$cname" >/dev/null 2>&1 || ipset create "$cname" hash:net; } && ipsc="OK" || ipsc="NOK" | |
echo "$( date +%F\ %T ) ipset: create set \"$cname\" - $ipsc" | |
# download zone file and verify using md5sum | |
wget -q -O "/tmp/$zfile.$$" "$urlipdeny/$zfile" | |
md5src="$( wget -q -O - "$urlipdeny/MD5SUM" | grep "$zfile" | cut -d" " -f 1 )" | |
md5chk="$( md5sum "/tmp/$zfile.$$" | cut -d" " -f 1 )" | |
if [ "$md5src" = "$md5chk" ]; then | |
mv "/tmp/$zfile.$$" "/etc/iptables/$zfile" && zf="OK" || zf="NOK" | |
echo "$( date +%F\ %T ) zonefile: get \"$zfile\" - $zf" | |
# add blocks to ipset | |
c=0; while read l; do ipset -A -exist -quiet "$cname" "$l" && c=$((co+1)); done < "/etc/iptables/$zfile" >/dev/null 2>&1 && \ | |
ipsa="OK" || ipsa="NOK" | |
echo "$( date +%F\ %T ) ipset: add \"$zfile\" to \"$cname\" - $ipsa - $c entries" | |
# restore iptables and insert rules for ipset | |
/sbin/iptables-restore < "$iptables" && ipr="OK" || ipr="NOK" | |
echo "$( date +%F\ %T ) iptables: restore - $ipr" | |
# rulenum=$(( $(iptables -S INPUT|wc -l) - 1 )) | |
# if [ "$rulenum" -gt "0" ] && | |
rulenum=3 | |
if [ "$cname" != "" ]; then | |
[ ! /sbin/iptables -n -L LOGIPS >/dev/null 2>&1 ] && { /sbin/iptables -N LOGIPS && iptn="OK" || iptn="NOK"; } || iptn="already exists" | |
/sbin/iptables -A LOGIPS -m limit --limit 10/min -j LOG --log-prefix "IPS REJECT: " --log-level 6 && iptl="OK" || iptl="NOK" | |
/sbin/iptables -A LOGIPS -j REJECT --reject-with icmp-port-unreachable && iptr="OK" || iptr="NOK" | |
/sbin/iptables -I INPUT "$rulenum" -p tcp -m set --match-set "$cname" src -j LOGIPS && ipti="OK" || ipti="NOK" | |
if ! iptables -n -L LOGIPS >/dev/null 2>&1; then | |
/sbin/iptables -I INPUT "$rulenum" -p tcp -m set --match-set "$cname" src -j REJECT --reject-with icmp-port-unreachable && \ | |
ipti="OK" || ipti="NOK"; iptn="disabled"; iptl="disabled"; iptr="disabled"; fi | |
echo "$( date +%F\ %T ) iptables: create log chain - $iptn" | |
echo "$( date +%F\ %T ) iptables: append log rule - $iptl, append reject rule - $iptr" | |
echo "$( date +%F\ %T ) iptables: insert ipset rule - $ipti" | |
fi | |
fi | |
[ -f "/tmp/$zfile.$$" ] && rm "/tmp/$zfile.$$" | |
done >>"$log" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment