Upline: Infos & Dokus Administration Linux

Firewall mit iptable


Nahezu jede Firewall unter Linux basiert auf iptable. Daher genügt es im Normalfall auch, sich nicht mit der Firewall sondern mit Ihrer Grundlage auszukennen. Ich verzichte in dieser Anleitung bewußt auf Erklärungen, da man diese zum einen überall im Netz findet und zum anderen teils auch aus meinen Beispielscripten ableiten kann. Das Script erwartet beim Aufruf Parameter und gibt bei fehlerhaftem Aufruf auch eine kurze Hilfe aus. Über diese Parameter kann entweder das Netzwerk komplett gesperrt oder mit den eingetragenen Ports geöffnet werden.
#!/bin/bash

iptunset(){

 # erst mal ordentlich aufräumen ...
 iptables -F
 iptables -P INPUT ACCEPT
 iptables -P OUTPUT ACCEPT
 iptables -P FORWARD ACCEPT

}

########################################################################

iptset(){

 # alles sperren
 iptables -P INPUT DROP
 iptables -P OUTPUT DROP
 iptables -P FORWARD DROP

 # Loopback wieder aktivieren
 iptables -A INPUT -i lo -j ACCEPT
 iptables -A OUTPUT -o lo -j ACCEPT

 # eth0 für ICMP freischalten
 iptables -A INPUT -i eth0 -p icmp -j ACCEPT
 iptables -A OUTPUT -o eth0 -p icmp -j ACCEPT

 # Anfragen von diesem Client an Nameserver erlauben
 iptables -A OUTPUT -o eth0 -p udp -s 192.168.0.10 --sport 1024:65535 -d 0/0 --dport 53 -j ACCEPT
 iptables -A INPUT -i eth0 -p udp -s 0/0 --sport 53 -d 192.168.0.10 --dport 1024:65535 -j ACCEPT

 # Port 80 freischalten (Anfragen an fremden Webserver)
 iptables -A OUTPUT -o eth0 -p tcp -s 192.168.0.10 --sport 1024:65535 -d 0/0 --dport 80 -j ACCEPT
 iptables -A INPUT -i eth0 -p tcp ! --syn -s 0/0 --sport 80 -d 192.168.0.10 --dport 1024:65535 -j ACCEPT

 # ssh freischalten (Port 22)
 iptables -A OUTPUT -o eth0 -p tcp -s 192.168.0.10 --sport 1024:65535 -d 0/0 --dport 22 -j ACCEPT
 iptables -A INPUT -i eth0 -p tcp ! --syn -s 0/0 --sport 22 -d 192.168.0.10 --dport 1024:65535 -j ACCEPT

 # Anfragen an entfernten ftp freischalten (Port 20/21/alle unpreviligierten)
 iptables -A OUTPUT -o eth0 -p tcp -s 192.168.0.10 --sport 1024:65535 -d 0/0 --dport 21 -j ACCEPT
 iptables -A INPUT -i eth0 -p tcp ! --syn -s 0/0 --sport 21 -d 192.168.0.10 --dport 1024:65535 -j ACCEPT
 
 iptables -A INPUT -i eth0 -p tcp -s 0/0 --sport 20 -d 192.168.0.10 --dport 1024:65535 -j ACCEPT
 iptables -A OUTPUT -o eth0 -p tcp ! --syn -s 192.168.0.10 --sport 1024:65535 -d 0/0 --dport 20 -j ACCEPT
 
 iptables -A OUTPUT -o eth0 -p tcp -s 192.168.0.10 --sport 1024:65535 -d 0/0 --dport 1024:65535 -j ACCEPT
 iptables -A INPUT -i eth0 -p tcp ! --syn -s 0/0 --sport 1024:65535 -d 192.168.0.10 --dport 1024:65535 -j ACCEPT
}

########################################################################

case "$1" in
s) iptset;;
u) iptunset;;
*) echo "Usage: iptbl s|u (set|unset)"
esac



Das folgende Script ist nahezu identisch mit dem obrigen, lediglich die IP und die Ports sind als Variablen ausgeführt, so daß eine Anpassung einfacher von statten geht.
#!/bin/bash
locip=192.168.0.10
aport=1024:65535

iptunset(){

 # erst mal ordentlich aufräumen ...
 iptables -F
 iptables -P INPUT ACCEPT
 iptables -P OUTPUT ACCEPT
 iptables -P FORWARD ACCEPT

}

########################################################################

iptset(){

 # alles sperren
 iptables -P INPUT DROP
 iptables -P OUTPUT DROP
 iptables -P FORWARD DROP

 # Loopback wieder aktivieren
 iptables -A INPUT -i lo -j ACCEPT
 iptables -A OUTPUT -o lo -j ACCEPT

 # eth0 für ICMP freischalten
 iptables -A INPUT -i eth0 -p icmp -j ACCEPT
 iptables -A OUTPUT -o eth0 -p icmp -j ACCEPT

 # Anfragen von diesem Client an Nameserver erlauben
 iptables -A OUTPUT -o eth0 -p udp -s $locip --sport $aport -d 0/0 --dport 53 -j ACCEPT
 iptables -A INPUT -i eth0 -p udp -s 0/0 --sport 53 -d $locip --dport $aport -j ACCEPT

 # Port 80 freischalten (Anfragen an fremden Webserver)
 iptables -A OUTPUT -o eth0 -p tcp -s $locip --sport $aport -d 0/0 --dport 80 -j ACCEPT
 iptables -A INPUT -i eth0 -p tcp ! --syn -s 0/0 --sport 80 -d $locip --dport $aport -j ACCEPT

 # Anfragen an entfernten ftp freischalten (Port 20/21/alle unpreviligierten)
 iptables -A OUTPUT -o eth0 -p tcp -s $locip --sport $aport -d 0/0 --dport 21 -j ACCEPT
 iptables -A INPUT -i eth0 -p tcp ! --syn -s 0/0 --sport 21 -d $locip --dport $aport -j ACCEPT

 iptables -A INPUT -i eth0 -p tcp -s 0/0 --sport 20 -d $locip --dport $aport -j ACCEPT
 iptables -A OUTPUT -o eth0 -p tcp ! --syn -s $locip --sport $aport -d 0/0 --dport 20 -j ACCEPT

 iptables -A OUTPUT -o eth0 -p tcp -s $locip --sport $aport -d 0/0 --dport $aport -j ACCEPT
 iptables -A INPUT -i eth0 -p tcp ! --syn -s 0/0 --sport $aport -d $locip --dport $aport -j ACCEPT
}

########################################################################

case "$1" in
s) iptset;;
u) iptunset;;
*) echo "Usage: iptbl s|u (set|unset)"
esac

Einzelne IPs oder Netze mit iptables sperren

Mitunter möchte man bestimmte einzelne IPs oder auch ganze IP-Bereiche komplett sperren. Gegen automatisierte Angriffe hilft oft bereits fail2ban, aber ein manuelles dauerhaftes Sperren bestimmter Adressbereiche bietet noch einiges mehr an Schutz. Vor allem ist es in der Regel für auf den deutschsprachigen Raum ausgerichtete (Web-)Server absolut unnötig, auf Anfragen aus Asien oder Afrika zu antworten, ja selbst Amerika ist für die meisten Dienste unwichtig. Dennoch sollte man hierbei Vorsicht walten lassen und eventuell nicht zu großzügig sperren. Portbasiert kann dabei durchaus sinnvoller sein, um z.B. für deutschsprachige Minderheiten und Touristen erreichbar zu bleiben. Erfahrungsgemäß kommt aber statistisch pro 10000 User mit etwas Glück vielleicht ein einziger (echter) User aus dem amerikanischen Raum und betrachtet man die Kontinente Afrika und Asien, so ist es höchstens noch jeder 20000.-30000. User, den man vergraulen würde. Auch aus dem osteuropäischen Raum kommen zwar unzählige Angriffe, aber kaum echte User.
Darauf kann man im Normalfall bedenkenlos verzichten und erreicht mit umfangreichen Sperren, dass auch nahezu alle Angriffsversuche bereits von der Firewall geblockt werden. Eine komplette Sperre erreicht man wie folgt:
iptables -I INPUT -s 192.168.1.10 -j DROP
iptables -I INPUT -s 183.0.0.0/10 -j DROP
In der ersten Zeile wird eine einzelne IP geblockt, in der zweiten Zeile ein /10er Netz.

Weiterführendes

Als besonders empfehlenswerte Lösung nenne ich an dieser Stelle das auf Linux From Scratch basierende ipcop , was natürlich wie alle guten Linuxprojekte OpenSource ist. Wer lieber ein Buch in der Hand hält, für den ist Linux Firewall Schnellkonfiguration mit Sicherheit die knapp 25 Euro wert. In dem Buch werden auch sämtliche wichtigen Grundlagen (Netzwerkprotokolle, VPN etc.) erklärt.