SSH, iptables und dynamische Adressen – So Sicher will ich es

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.

Schreibe einen Kommentar