Wie im Blogartikel SSH Zugang limitieren mit GeoIP und hosts.deny aus 2017 bereits beschrieben, kann der Zugang zu Diensten mithilfe von /etc/hosts.deny eingeschränkt werden.
Das funktioniert für alle Services, die tcpwrap unterstützen.
Da inzwischen die GeoLite Legacy nicht mehr weiter gepflegt wird, sollte nur mehr die aktuelle GeoLite2 von MaxMind verwendet werden. Das erfordert ein angepasstes Skript.
Darauf, wie man die GeoLite2-Country.mmdb aktuell halten kann, gehe ich hier nicht ein. Das funktioniert einfach mit geoipupdate, einer dazugehörenden /etc/GeoIP.conf und einem monatlichen Cronjob. Aktuelle Linux-Distris liefern geoipupdate und mmdblookup üblicherweise als Paket.
Die Ausgabe von mmdblookup unterscheidet sich sehr von der Ausgabe geoiplookup.
Das Skript musste entsprechend geändert werden.
checkcountry2.sh:
#!/bin/bash
# Requires mmdblookup and the new db type "mmdb".
# exit 1 = allow (false)
# exit 0 = block (true)
# use with tcpwrap in /etc/hosts.deny
GEODB='/usr/local/share/GeoIP/GeoLite2-Country.mmdb'
ALLOW=('AT' 'DE' 'CH' 'FL')
if [ $# -ne 1 ]
then
exit 1
fi
if [ ! -f $GEODB ]
then
exit 1
fi
IP4PAT='^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$'
IP6PAT='^[0-9a-f]{1,4}:[0-9a-f]{1,4}:[0-9a-f]{1,4}:[0-9a-f]{1,4}:[0-9a-f:]+$'
VALID=$(echo $1 | grep -E "(${IP4PAT}|${IP6PAT})")
if [ -z "$VALID" ]
then
exit 1
fi
CNTRY=$(mmdblookup -f $GEODB -i $1 country iso_code 2>/dev/null| grep utf8_string | cut -d '"' -f 2)
if [ -z "$CNTRY" ]
then
exit 1
fi
for i in "${ALLOW[@]}"
do
if [ "$i" == "$CNTRY" ]
then
logger -t 'CheckCountry' "Permitting $1 ($CNTRY) to authenticate."
exit 1
fi
done
# allowed and unknown got sortet out, slow down and block the rest
sleep 1
exit 0
Sehr wahrscheinlich müsst ihr die beiden Variablen GEODB und ALLOW anpassen.