Workstation-Firewall (iptables)
Zielgruppe: Fortgeschrittene 
Dieses Script ist für den Einsatz auf Arbeitslatzrechnern gedacht.
Bei mir laufen diese Filterregeln auf einem Rechner hinter einem Router,
der auch als DNS-Server dient. Bei Verbindungen über ISDN/DSL mögen daher vielleicht
noch kleine Änderungen nötig sein. Es kommt als Paketfilter iptables zum Einsatz,
welches bei den 2.4er Kerneln verwendet wird. Es wird bei Debian mit dem Paket
"iptables" zur Verfügung gestellt. Um die Funktion des Scriptes zu
gewährleisten, ist das Laden von Kernel-Modulen notwendig, wie sie bei
vielen Standard-Kerneln gängiger Distributionen beiliegen. Unter Debian
woody kann man die Module dauerhaft mit dem Programm
modconf
ins System einbinden. Sie werden dann bei jedem Systemstart geladen.
Dazu gehören die Module
ipt_LOG
ipt_state
iptable_filter
ip_tables
ip_conntrack_ftp
ip_conntrack
die man unter kernel/net/ipv4/netfilter findet. Erst danach stehen
entsprechende Funktionen für das Filtern der Pakete zur Verfügung.
Darüber hinaus reicht es bei Debian aus, wenn man das nachstehende
Script einmal startet und dann die aktuellen Filterregeln durch Eingabe von
/etc/init.d/iptables save active
als root dauerhaft speichern. So gesehen ist das Script nur eine Hilfe bei der
Konfiguration und erspart das manuelle Eintippen der Filterregeln. Das Script
eignet sich weniger als typisches Start-/Stopp-Script unter /etc/init.d. Zumindest empfehle ich die Verwendung von /etc/init.d/iptables für diesen Zweck. Sollte der obige Speicherbefehl nicht funktionieren, weil zum Beispiel in Debian sarge das init-Script fehlt, der kann mit
iptables-save /var/lib/iptables/filterregeln
seine Filterregeln speichern und durch den Aufruf von
iptables-restore /var/lib/iptables/filterregeln
wieder rauskramen. Das entsprechende Verzeichnis /var/lib/iptables muss dabei ggf. noch angelegt werden. Dies ermöglicht das Ablegen von verschiedenen Firewall-Konfigurationen für unterschiedliche Situationen. Bitte beachte
auch, dass bei den NTP-Servern in der Regel nur die Namen angegeben werden. Deshalb ist eine Internet-Verbindung beim Starten des Scriptes nötig, damit automatisch die
IP-Adresse geholt werden kann. Wenn du das nicht willst, solltest du die IP-Adressen
angeben. Die Filterregeln der Firewall kannst du mit
iptables -n -L
als root anschauen. Um den Rechner dann per default mit dem
Paketfilter zu starten, muss man noch sicher stellen, dass entsprechende
Links unter /etc/rc*.d auf /etc/init.d/iptables erzeugt wurden. Dies
kann man aber leicht mit dem Tool "update-rc.d" nachholen. Dann werden
automatisch die unter dem Namen "active" gespeicherten Filterregeln geladen.
#!/bin/sh
# Funktion: Script zur Konfiguration einer Firewall für Arbeitsplatz-Rechner
# Lizenz: Frei für nicht-kommerzielle Nutzung. Dieser Kommentarblock
# muss erhalten bleiben und darf nicht verändert werden.
# Copyright: Jens-D. Neppe
# Inspririert von dem DSL-Router Firewall Script von Martin Rasp.
# Scriptname:fwrules.sh
# Aufruf: fwrules.sh [set|clear]
# Datum: 2002-10-08
# Änderung: 2002-12-19 (Fehlerausgabe an den Anfang gesetzt, Scriptname und
# Parameter umbenannt.)
# Haftung: Keine Haftung bei Schäden, die aus der direkten/indirekten
# Nutzung dieses Shell-Scripts entstehen können.
##############################################################################
IPTABLES=/sbin/iptables
IFCONFIG=/sbin/ifconfig
INTERNET=0/0
# Das externe Interface kann auch
# ippp0 sein für ISDN-Verbindungen.
# Habe ich aber nicht getestet.
EXT_IF=eth0
LO_IF=lo
case "$1" in
set)
EXT_IP=`$IFCONFIG $EXT_IF | grep inet | cut -d : -f 2 | cut -d " " -f 1`
EXT_MASK=`$IFCONFIG $EXT_IF | grep Mask | cut -d : -f 4`
EXT_NET="$EXT_IP/$EXT_MASK"
LO_IP=127.0.0.1
LO_MASK=255.255.255.255
LO_NET="$LO_IP/$LO_MASK"
;;
clear)
echo "Lösche Filterregeln."
;;
*)
echo "Usage: $0 {set|clear}"
exit 1
;;
esac
Flush_All()
{ # Paketfilterketten löschen
$IPTABLES -F INPUT
$IPTABLES -F FORWARD
$IPTABLES -F OUTPUT
}
Allow_All()
{ # Neue Policy setzen
$IPTABLES -P INPUT ACCEPT
$IPTABLES -P FORWARD ACCEPT
$IPTABLES -P OUTPUT ACCEPT
}
Deny_All()
{ # Neue Policy setzen
$IPTABLES -P INPUT DROP
$IPTABLES -P FORWARD DROP
$IPTABLES -P OUTPUT DROP
}
Enable_Connection_Tracking()
{ # Variablen für Connection-Tracking befüllen:
OTRACK="-m state --state NEW,RELATED,ESTABLISHED"
ITRACK="-m state --state RELATED,ESTABLISHED"
}
Disable_Connection_Tracking()
{ # Variablen für Connection-Tracking entleeren:
OTRACK=""
ITRACK=""
}
Enable_Log_Incoming()
{ # Wenn jemand versucht, von aussen eine Verbindung mit dem Rechner
# aufzubauen, dann wird das in die Log-Datei geschrieben.
$IPTABLES -A INPUT -d $EXT_IP -m state --state INVALID,NEW -j LOG --log-prefix "BOESES PAKET:" --log-level 7
}
Allow_DNS()
{ DNS1=`cat /etc/resolv.conf | grep ^nameserver | cut -d " " -f 2 | head -n 1`
DNS2=`cat /etc/resolv.conf | grep ^nameserver | cut -d " " -f 2 | tail -n 1`
# UDP-Abfragen. Hier wird berücksichtigt, dass man u.U. vielleicht nur einen DNS hat.
if [ -n $DNS1 ] ; then
$IPTABLES -A OUTPUT -p udp -s $EXT_IP -d $DNS1 --destination-port 53 $OTRACK -j ACCEPT
$IPTABLES -A INPUT -p udp -s $DNS1 --source-port 53 -d $EXT_IP $ITRACK -j ACCEPT
fi
if [ ! $DNS1 = $DNS2 ] && [ -n "$DNS2" ] ; then
$IPTABLES -A OUTPUT -p udp -s $EXT_IP -d $DNS2 --destination-port 53 $OTRACK -j ACCEPT
$IPTABLES -A INPUT -p udp -s $DNS2 --source-port 53 -d $EXT_IP $ITRACK -j ACCEPT
fi
}
Allow_lo_traffic()
{ # Traffic über das lo-Device erlauben
$IPTABLES -A OUTPUT -s $LO_IP -d $LO_IP -j ACCEPT
$IPTABLES -A INPUT -s $LO_IP -d $LO_IP -i $LO_IF -j ACCEPT
}
Allow_http()
{ # Port 80
$IPTABLES -A OUTPUT -p tcp -s $EXT_IP --destination-port 80 $OTRACK -j ACCEPT
$IPTABLES -A INPUT -p tcp -d $EXT_IP --source-port 80 $ITRACK -j ACCEPT
}
Allow_http_proxy()
{ # Port 8000
$IPTABLES -A OUTPUT -p tcp -s $EXT_IP --destination-port 8000 $OTRACK -j ACCEPT
$IPTABLES -A INPUT -p tcp -d $EXT_IP --source-port 8000 $ITRACK -j ACCEPT
}
Allow_cvs()
{ # Port 2401
$IPTABLES -A OUTPUT -p tcp -s $EXT_IP --destination-port 2401 $OTRACK -j ACCEPT
$IPTABLES -A INPUT -p tcp -d $EXT_IP --source-port 2401 $ITRACK -j ACCEPT
}
Allow_nntp()
{ # Port 119
$IPTABLES -A OUTPUT -p tcp -s $EXT_IP --destination-port 119 $OTRACK -j ACCEPT
$IPTABLES -A INPUT -p tcp -d $EXT_IP --source-port 119 $ITRACK -j ACCEPT
}
Allow_ntp()
{ NTP1=`cat /etc/ntp.conf | grep ^server | cut -d " " -f 2 | head -n 1`
NTP2=`cat /etc/ntp.conf | grep ^server | cut -d " " -f 2 | tail -n 1`
for ntpserver in $NTP1 $NTP2 ; do
for pakettype in udp tcp ; do
$IPTABLES -A OUTPUT -p $pakettype -s $EXT_IP -d $ntpserver --destination-port 123 $OTRACK -j ACCEPT
$IPTABLES -A INPUT -p $pakettype -d $EXT_IP -s $ntpserver --source-port 123 $ITRACK -j ACCEPT
done
done
}
Allow_https()
{ # Port 443
$IPTABLES -A OUTPUT -p tcp -s $EXT_IP --destination-port 443 $OTRACK -j ACCEPT
$IPTABLES -A INPUT -p tcp -d $EXT_IP --source-port 443 $ITRACK -j ACCEPT
}
Allow_POP3()
{ # Port 110
$IPTABLES -A OUTPUT -p tcp -s $EXT_IP --destination-port 110 $OTRACK -j ACCEPT
$IPTABLES -A INPUT -p tcp -d $EXT_IP --source-port 110 $ITRACK -j ACCEPT
}
Allow_SMTP()
{ # Port 25
$IPTABLES -A OUTPUT -p tcp -s $EXT_IP --destination-port 25 $OTRACK -j ACCEPT
$IPTABLES -A INPUT -p tcp -d $EXT_IP --source-port 25 $ITRACK -j ACCEPT
}
Allow_passive_ftp()
{ # FTP, Port 21-Kontolle, 1024:65535-Daten
$IPTABLES -A INPUT -p tcp -d $EXT_IP --sport 21 -m state --state ESTABLISHED -j ACCEPT
$IPTABLES -A OUTPUT -p tcp -s $EXT_IP --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT
# passiv - Daten - keine neue Verbindungen
$IPTABLES -A INPUT -d $EXT_IP -p tcp --sport 1024:65535 --dport 1024:65535 -m state --state ESTABLISHED -j ACCEPT
$IPTABLES -A OUTPUT -s $EXT_IP -p tcp --sport 1024:65535 --dport 1024:65535 -m state --state ESTABLISHED,RELATED -j ACCEPT
}
# Die nachfolgen Funktionsaufrufe können
# den eigenen Bedürfnissen entsprechend
# mit einem "#" auskommentiert werden.
case "$1" in
set)
Deny_All
Flush_All
Enable_Connection_Tracking
Enable_Log_Incoming
Allow_DNS
Allow_lo_traffic
Allow_http
Allow_https
Allow_http_proxy
Allow_POP3
Allow_SMTP
Allow_cvs
Allow_nntp
Allow_ntp
Allow_passive_ftp
;;
clear)
Deny_All
Flush_All
;;
esac
exit 0
|