
This script creates automatically firewall rules for iptables based on GeoIP informations. This script can be useful if you cannot use or build from source the Xtables addons for iptables.
The script allows you to authorize network trafic on a specific tcp port for a/multiple countr(y/ies). It is exclusive : if a tcp port/country has been defined with this script, only this country subnet address will be able to reach the tcp port.
The script performs these steps :
- Download the file http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip
- Unzip the file above
- Check if the country code is valid or not
- Create an iptables custom chain for each Country Code-TCP port to allow
- Create a DROP rule in the INPUT chain to drop all traffic that is not defined in the rule above
Script syntax :
Authorize on port TCP 999 only network subnet from XX Country code
./scriptname "XX" 999
Authorize on port TCP 999 only network subnet from XX, YY and ZZ Country code
./scriptname "XX|YY|ZZ" 999
Script :
#!/bin/bash COUNTRY=$1 COUNTRY=$(echo $COUNTRY | tr 'a-z' 'A-Z') TCPPORT=$2 # function to create iptables entries ipt_create() { file="$1" pattern="$2" tcpport="$3" if cat $file | cut -f5 -d, | grep $pattern >/dev/null ; then echo $pattern "is valid. Creating iptables custom chain DROP_EXCEPT_"$pattern"..." if ! iptables -L | grep "Chain DROP_EXCEPT_"$pattern >/dev/null ; then sudo iptables -N DROP_EXCEPT_$pattern'_ONPORT_'$tcpport fi if ! iptables -L INPUT | grep DROP_EXCEPT_$pattern >/dev/null ; then sudo iptables -t filter -I INPUT -j DROP_EXCEPT_$pattern'_ONPORT_'$tcpport fi cat $file | grep -E $pattern | sed 's/"//g' | sort | uniq > $file.$pattern while IFS=, read -r ip_begin ip_end f3 f4 f5 f6 do echo "for "$f6" : sudo iptables -A DROP_EXCEPT_"$pattern" -p tcp -m tcp -m iprange --src-range "$ip_begin"-"$ip_end" --dport "$tcpport" -j ACCEPT" sudo iptables -A DROP_EXCEPT_$pattern'_ONPORT_'$tcpport -p tcp -m tcp -m iprange --src-range $ip_begin-$ip_end --dport $tcpport -j ACCEPT done < $file.$pattern else echo $pattern "is invalid. Skipping." fi } cd /geoip ZIP="GeoIPCountryCSV.zip" if [ -f $ZIP ]; then mv -f $ZIP $ZIP.bkp fi /usr/bin/wget -P . http://geolite.maxmind.com/download/geoip/database/$ZIP CSV=$(unzip -l $ZIP | grep -i "\.csv" | awk '{print $4}') if [ -f $CSV ]; then mv -f $CSV $CSV.bkp fi unzip -o $ZIP # create iptables chain for each country if [[ $COUNTRY == *\|* ]] then for XX in ${COUNTRY//\|/ } ; do if ! iptables -L | grep "Chain DROP_EXCEPT_"$XX >/dev/null ; then ipt_create $CSV $XX $TCPPORT else echo "iptables chain for "$XX" already exists. Skipping." fi done else if ! iptables -L | grep "Chain DROP_EXCEPT_"$COUNTRY >/dev/null ; then ipt_create $CSV $COUNTRY $TCPPORT else echo "iptables chain for "$COUNTRY" already exists. Skipping." fi fi if ! iptables -L INPUT | grep "tcp dpt:"$TCPPORT >/dev/null ; then sudo iptables -A INPUT -p tcp -m tcp --dport $TCPPORT -j DROP fi
Create GeoIP firewall rules for iptables