Nach ein paar Tagen mit meinen Server im Netz,sah ich wie beliebt Server als Angriffsziel sind. Jedesmal wenn ich mich per SSH einloggte, sah ich wieder missglückte Loginversuche.
SSH per Firewall zu blocken, kam natürlich nicht in frage, der Zugang sollte aber auf bestimmte IPs beschränkt sein. Ich suchte also ein Script um eine iptables Eintrag für eine dynamische IP anzulegen.
Dank Google wurde ich natürlich fündig:
#!/bin/bash
# filename: firewall-dynhosts.sh
#
# A script to update iptable records for dynamic dns hosts.
# Written by: Dave Horner (http://dave.thehorners.com)
# Released into public domain.
#
# Run this script in your cron table to update ips.
#
# You might want to put all your dynamic hosts in a sep. chain.
# That way you can easily see what dynamic hosts are trusted.
#
# create the chain in iptables.
# /sbin/iptables -N dynamichosts
# insert the chain into the input chain @ the head of the list.
# /sbin/iptables -I INPUT 1 -j dynamichosts
# flush all the rules in the chain
# /sbin/iptables -F dynamichosts
HOST=$1
HOSTFILE="/root/dynhosts/host-$HOST"
CHAIN="INPUT" # change this to whatever chain you want.
IPTABLES="/sbin/iptables"
# check to make sure we have enough args passed.
if [ "${#@}" -ne "1" ]; then
echo "$0 hostname"
echo "You must supply a hostname to update in iptables."
exit
fi
# lookup host name from dns tables
IP=`/usr/bin/dig +short $HOST | /usr/bin/tail -n 1`
if [ "${#IP}" = "0" ]; then
echo "Couldn't lookup hostname for $HOST, failed."
exit
fi
OLDIP=""
if [ -a $HOSTFILE ]; then
OLDIP=`cat $HOSTFILE`
# echo "CAT returned: $?"
fi
# has address changed?
if [ "$OLDIP" == "$IP" ]; then
echo "Old and new IP addresses match."
exit
fi
# save off new ip.
echo $IP>$HOSTFILE
echo "Updating $HOST in iptables."
if [ "${#OLDIP}" != "0" ]; then
echo "Removing old rule ($OLDIP)"
`$IPTABLES -D $CHAIN -s $OLDIP/32 -j ACCEPT`
fi
echo "Inserting new rule ($IP)"
`$IPTABLES -A $CHAIN -s $IP/32 -j ACCEPT`
Das Script benötigt die dig aus den bind-utils, welches nachinstalliert werden muss:
$ yum install bind-utils
Das Script liegt bei mir unter /root und benutzt /root/dynhosts um dort die IPs zun speichern. Es muss also für jeden dynamische Host noch eine Datei erzugt werden:
$ vi /root/dynhosts/host-dynhost1.dyndns.org
Das wiederholt man für jeden dynamischen Host.
Anschließend habe ich ein weiteres Script erstellt, damit jeder Host abgearbeitet wird.
$ cat dynamic-firewall
/root/firewall-dynhosts.sh dynhost1.anbieter.de
/root/firewall-dynhosts.sh dynhost2.dyndns.org
Damit nun die Regeln erzeigt werden, lasse ich das Script alle fünf Minuten über einen Cronjob starten.
$ crontab -e
*/5 * * * * /root/dynamic-firewall > /dev/null
Das > /dev/null verhindert, dass ich jedes Mal eine neue Mail in mein Postfach bekomme.
Damit läuft es. Ich habe jedoch noch eine Backdoor installiert, damit ich den Zugang wieder öffnen kann, falls ich mich doch ausschließe. Ich setzte meine Firewallregeln mittels einen Scripts. Ich habe nun zwei Scripte, eines für einen offenen Port 22 für alle und eines in denen Port 22 generell dicht ist, und mir das obige Script den Zugang für meinen dynamische IPs wieder frei macht. Nach Script 1. setzte ich immer noch ein iptables save ab, damit die Änderungen auch einen Boot überleben, jedoch nicht bei Script zwei. Bei Änderungen lasse ich erst Script eins durchlaufen, speicher ab und danach Script zwei. Sollte also irgend etwas schief gelaufen sein, dann kann ich durch den Neustart des Servers wieder den SSH-Zugang auf machen.