
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
