Skip to content

Instantly share code, notes, and snippets.

@porjo
Last active June 8, 2023 12:49
Show Gist options
  • Save porjo/735dbee46d57649550059d60147b7fb0 to your computer and use it in GitHub Desktop.
Save porjo/735dbee46d57649550059d60147b7fb0 to your computer and use it in GitHub Desktop.
Create Geo fencing country blocks for use by iptables
#!/bin/bash
#
# Update the ipset that iptables references for allowing/blocking based on country.
# Takes 2 parameters: ipset name (no spaces), country name e.g. 'Australia'
#
# iptables should have an existing '--match-set' rule e.g
# $ iptables -I INPUT -p tcp --dport 22 -m set --match-set australia4 src -j ACCEPT
# $ ip6tables -I INPUT -p tcp --dport 22 -m set --match-set australia6 src -j ACCEPT
#
CHANGELOG="/var/log/ipset_changes.log"
IPSET="/sbin/ipset"
GEOIP_URL="http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country-CSV.zip"
#-----------------------------------------------------------------
if [ $# -ne 2 ]; then
echo "Usage $0 <ipset name> <country>"
exit
fi
SETNAME=$1
COUNTRY=$2
TMPDIR=/tmp/$$_tmp
GEOIP_FILE=${TMPDIR}/$$_geoip.zip
CIDR_FILE=${TMPDIR}/$$_${SETNAME}_CIDR.zone
mkdir $TMPDIR
function fail {
echo "FAILED: "$1
cleanup
exit 1
}
function cleanup {
rm -rf $TMPDIR
}
cd $TMPDIR
[ $? -ne 0 ] && fail "Problem using tmp directory $TMPDIR"
curlout=`/bin/curl $GEOIP_URL -o $GEOIP_FILE 2>&1`
[ $? -ne 0 ] && fail "Problem downloading GeoIP database: $curlout"
unzip -q $GEOIP_FILE
cd GeoLite2-Country-CSV*
GEOID=`egrep -i "${COUNTRY}\"?$" GeoLite2-Country-Locations-en.csv | cut -f1 -d,`
[ $? -ne 0 ] && fail "$COUNTRY not found in GeoIP file"
for IPvX in 4 6; do
SET=${SETNAME}${IPvX}
grep $GEOID GeoLite2-Country-Blocks-IPv${IPvX}.csv | cut -f1 -d, > $CIDR_FILE
if [ "$IPvX" -eq "4" ]; then
$IPSET -exist create ${SET} hash:net family inet
$IPSET create ${SET}-tmp hash:net family inet
else
$IPSET -exist create ${SET} hash:net family inet6
$IPSET create ${SET}-tmp hash:net family inet6
fi
[ $? -ne 0 ] && fail "Problem creating tmp ipset"
while read line; do
$IPSET add ${SET}-tmp $line;
[ $? -ne 0 ] && fail "Problem updating tmp ipset"
done < $CIDR_FILE
# Check for changes
if [ -n $CHANGELOG ]; then
$IPSET save ${SET} > ${TMPDIR}/$$_${SET}.ipset
$IPSET save ${SET}-tmp > ${TMPDIR}/$$_${SET}-tmp.ipset
echo `date`": Processing $COUNTRY..." >> $CHANGELOG
echo `wc -l $CIDR_FILE | cut -f1 -d' '`" blocks loaded" >> $CHANGELOG
diffout=`diff ${TMPDIR}/$$_${SET}.ipset ${TMPDIR}/$$_${SET}-tmp.ipset`
if [ $? -ne 0 ]; then
echo $diffout >> $CHANGELOG
else
echo "No changes" >> $CHANGELOG
fi
echo >> $CHANGELOG
fi
$IPSET swap ${SET}-tmp $SET
[ $? -ne 0 ] && fail "Problem updating live ipset"
$IPSET destroy ${SET}-tmp
[ $? -ne 0 ] && fail "Problem destroying tmp ipset"
done
cleanup
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment