Okt
13
2011

iptables Laender blocken, China aussperren

Wer von euch häufig Spam oder andere Zugriffe aus dem Reich der Mitte auf seinem Server hat, dem kann das helfen.

Ich habe nach einer automatiserten Möglichkeit gesucht, Zugriffe aus China und anderen Ländern per iptables zu blocken. Dazu habe ich folgendes Script angelegt (Quelle: bananasoft.org):

#!/bin/bash
### Block all traffic from AFGHANISTAN (af) and CHINA (CN). Use ISO code ###
ISO=“af cn“

### Set PATH ###
IPT=/sbin/iptables
WGET=/usr/bin/wget
EGREP=/bin/egrep

### No editing below ###
CBLIST=“countrydrop“
ZONEROOT=“/var/iptables“
IPTCBRESTORE=“/etc/sysconfig/iptables.cb“
ALLOWPORTS=1
MAXZONEAGE=7
DLROOT=“http://www.ipdeny.com/ipblocks/data/countries“

cleanOldRules(){
$IPT -L $CBLIST > /dev/null 2>&1
if [ $? = 0 ] ; then
$IPT -D INPUT -j $CBLIST
$IPT -D OUTPUT -j $CBLIST
$IPT -D FORWARD -j $CBLIST
fi
TOPIP=`$IPT -L -n | grep Chain | cut -f 2 -d ‚ ‚ | grep ‚\-$CBLIST’`
for i  in $TOPIP
do
$IPT -F ${i}
$IPT -X ${i}
done
$IPT -X $CBLIST
}

updateZoneFiles() {
ZONEARCH=${ZONEROOT}/arch
mkdir -p ${ZONEARCH}
find ${ZONEROOT} -maxdepth 1 -mindepth 1 -ctime +${MAXZONEAGE} -exec mv {} ${ZONEARCH} \;

for c  in $ISO
do
# local zone file
tDB=$ZONEROOT/$c.zone

if [ -f $tDB ] ; then
printf „Zone file %s is new enough – no update required.\n“ $tDB
else
# get fresh zone file if it is newer than MAXZONEAGE days
$WGET -O $tDB $DLROOT/$c.zone
fi
done
oldzones=`find ${ZONEROOT} -mindepth 1 -maxdepth 1 -type f -exec basename {} \; | cut -f 1 -d ‚.’`
# Archive old zones no longer blocked
for z in $oldzones ; do
archme=${c}
for c  in $ISO ; do
if [ $c = $z ] ; then archme=“X“; fi
done
if [ $archme = $z ] ; then
mv ${archme} ${ZONEARCH}
else
printf „Working from previous zone file for %s\n“ ${z}
fi
done
}

createIPTLoadFile() {
printf „# Generated by %s on“ $0 > ${IPTCBRESTORE}
printf „%s “ `date` >> ${IPTCBRESTORE}
printf „\n*filter\n“ >> ${IPTCBRESTORE}
# Create CBLIST chain
printf „:$CBLIST – [0:0]\n“ >> ${IPTCBRESTORE}
printf „%s INPUT -j $CBLIST\n“ „-I“ > ${IPTCBRESTORE}.tmp
printf „%s OUTPUT -j $CBLIST\n“ „-I“ >> ${IPTCBRESTORE}.tmp
printf „%s FORWARD -j $CBLIST\n“ „-I“ >> ${IPTCBRESTORE}.tmp

if [ „Z${ALLOWPORTS}“ = „Z“ ] ; then
printf „Blocking all traffic from country – no ports allowed\n“
else
printf „%s $CBLIST -p tcp -m multiport ! –dports ${ALLOWPORTS} -j RETURN\n“ „-I“>> ${IPTCBRESTORE}.tmp
fi

for c  in $ISO
do
# local zone file
tDB=$ZONEROOT/$c.zone

# country specific log message
SPAMDROPMSG=“$c Country Drop“

# Create drop chain for identified packets
CBLISTDROP=${c}-${CBLIST}-DROP
printf „:${CBLISTDROP} – [0:0]\n“ >> ${IPTCBRESTORE}
printf „%s ${CBLISTDROP} -j LOG –log-prefix \“$SPAMDROPMSG\“\n“ „-A“ >> ${IPTCBRESTORE}.tmp
printf „%s ${CBLISTDROP} -j DROP\n“ „-A“ >> ${IPTCBRESTORE}.tmp

# Load IP ranges into chains correlating to first octet
BADIPS=$(egrep -v „^#|^$“ $tDB)
for ipblock in $BADIPS
do
topip=`echo $ipblock | cut -f 1 -d ‚.’`
chainExists=`grep -c :${topip}-${CBLIST} ${IPTCBRESTORE}`
if [ $chainExists = 0 ] ; then
printf „Creating chain for octet %s\n“ ${topip}
printf „:$topip-$CBLIST – [0:0]\n“ >> ${IPTCBRESTORE}
sip=${topip}.0.0.0/8
printf „%s $CBLIST -s ${sip} -j $topip-$CBLIST\n“ „-A“ >> ${IPTCBRESTORE}.tmp
fi
printf “  Adding rule for %s to chain for octet %s\n“ ${ipblock} ${topip}
printf „%s $topip-$CBLIST -s $ipblock -j ${CBLISTDROP}\n“ „-A“ >> ${IPTCBRESTORE}.tmp
done
done
cat ${IPTCBRESTORE}.tmp >> ${IPTCBRESTORE} && rm -f ${IPTCBRESTORE}.tmp
printf „COMMIT\n# Completed on “ >> ${IPTCBRESTORE}
printf „%s “ `date` >> ${IPTCBRESTORE}
printf „\n“ >> ${IPTCBRESTORE}
}

directLoadTables() {
# Create CBLIST chain
$IPT -N $CBLIST
$IPT -I INPUT -j $CBLIST
$IPT -I OUTPUT -j $CBLIST
$IPT -I FORWARD -j $CBLIST

if [ „Z${ALLOWPORTS}“ = „Z“ ] ; then
printf „Blocking all traffic from country – no ports allowed\n“
else
$IPT -I $CBLIST -p tcp -m multiport ! –dports ${ALLOWPORTS} -j RETURN
fi

for c  in $ISO
do
# local zone file
tDB=$ZONEROOT/$c.zone

# country specific log message
SPAMDROPMSG=“$c Country Drop“

# Create drop chain for identified packets
CBLISTDROP=${c}-${CBLIST}-DROP
$IPT -N ${CBLISTDROP}
$IPT -A ${CBLISTDROP} -j LOG –log-prefix „$SPAMDROPMSG“
$IPT -A ${CBLISTDROP} -j DROP

# Load IP ranges into chains correlating to first octet
BADIPS=$(egrep -v „^#|^$“ $tDB)
for ipblock in $BADIPS
do
topip=`echo $ipblock | cut -f 1 -d ‚.’`
$IPT -L $topip-$CBLIST > /dev/null 2>&1
if [ $? = 1 ] ; then
printf „Creating chain for octet %s\n“ ${topip}
$IPT -N $topip-$CBLIST
sip=${topip}.0.0.0/8
$IPT -A $CBLIST -s ${sip} -j $topip-$CBLIST
fi
printf “  Adding rule for %s to chain for octet %s\n“ ${ipblock} ${topip}
$IPT -A $topip-$CBLIST -s $ipblock -j ${CBLISTDROP}
done
done
}

loadTables() {
createIPTLoadFile
${IPT}-restore -n ${IPTCBRESTORE}
#directLoadTables
}

# create a dir
[ ! -d $ZONEROOT ] && /bin/mkdir -p $ZONEROOT

# clean old rules
cleanOldRules

# update zone files as needed
updateZoneFiles

# create a new iptables list
loadTables

exit 0

Weiterhin muss noch das Verzeichnis sysconfig angelegt werden, wenn es nicht vorhanden ist (Oder Pfad im Script anpassen): mkdir /etc/sysconfig
Die iptables.cb wird beim Ausführen des scripts automatisch angelegt. Welche Länder ihr sperren wollt könnt ihr im oberen Bereich hinter ISO=“ festlegen. Dazu einfach mit Leerzeichen getrennt den Ländercode angeben.
Das Script könnt ihr nun automatisiert per cron wöchentlich starten und somit die IP-Adressen immer aktuell halten.
Ich habe danach mal über http://just-ping.com/ einen Ping auf meinen Server gestartet und dieser wurde von verschiedenen Ländern versucht und bei den zuvor festgelegten war dieser nicht erfolgreich 😉

Viel Spaß und Ruhe auf dem Server…

 



Über den Autor:

2 Kommentare + Neuer Kommentar

  • Schön, dass das Skript Dir helfen konnte 🙂

  • Wirklich sehr gut. Genau danach habe ich gesucht, nachdem mir Google die letzten Wochen immer wieder berichtet hat, dass viele fehlgeschlagene Logins aus China stattgefunden hätten.
    Jetzt ist wenigstens auf’m Homeserver Ruhe!

    Danke dir dafür!

Kommentar schreiben