Von Arne
Syntax: "xyz" ist eine Eingabe in der Kommandozeile
"{BEISPIEL}" ist eine Variable , die ihr ersetzen müsst.
"#" leitet einen Kommentar ein
Meine Konfiguration:
Interfaces:
{LAN_INTERFACE} = eth1
{ROUTER_LAN_IP} = 192.168.1.200
{EXT_INTERFACE} = eth0 oder ppp0
{LAN_IP_RANGE} = 192.168.1.0/24
zuerst kann man mal in der Console folgendes eingeben um die aktuelle konfiguration zu sehen
iptables --list
ist man per su root geworden, kann es sein, dass der Befehl iptables nicht gefunden wird, dann muss man entweder /sbin/iptables eingeben, oder seine PATH Variable um dem Pfad /sbin erweitern.
Man sollte dann in der standard einstellung folgendes sehen:
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Dies ist übrigens auch die standard Einstellung wenn man den service iptables startet, unter redhat mit:
service iptables start
In der Ausgabe oben sieht man folgendes: Es gibt drei Ketten : INPUT, FORWARD, OUTPUT für jede Kette gibt es eine Policy, also eine Standard Regel, die angewendet wird wenn keine andere Regel zutrifft hier: ACCEPT) Als Policy kann man ACCEPT oder DROP stellen, also Annehmen oder verwerfen. Außerdem sieht man oben, dass keine weiteren Regeln vorhaden sind, also ist das System komplett offen für alle Pakete.
Zu den Ketten:
INPUT: diese Kette prüft alle für den Rechner bestimmten Pakete vor dem annehmen
OUTPUT: diese Kette prüft alle ausgehenden Pakete bevor sie den Rechner verlassen
FORWARD: diese Kette prüft alle weitergeleiten (gerouteten) Pakete
Die Pakete die geroutet werden durchlaufen NICHT die INPUT/OUTPUT Kette,wie es bei ipchains noch der Fall war.
Sind schon Regeln für die Ketten definiert können diese mit
iptables -F
gelöscht werden
Zuerst machen wir den Rechner dicht, indem wir die Standad Policy für alle Ketten auf DROP setzen, so werden alle Pakete verworfen (das sollte man nicht über fernverwaltung tun, denn die Verbindung wird unterbrochen werden)
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
Jetzt gibt es keine Verbindungen mehr von bzw zu dem Rechner , nicht mal mehr pingen ist möglich.
Nun muss man nacheinander die einzelnen Verbindungen erlauben.
Zuerst das loopback interface. (wird von einigen Programmen benötigt)
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
Danach lassen wir erstmal SSH vebindungen aus dem LAN zu damit wir den Router fernverwalten können.
iptables -A INPUT -p tcp -i {LAN_INTERFACE} --dport 22 -d {ROUTER_LAN_IP} -s {LAN_IP_RANGE} -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -p tcp -o {LAN_INTERFACE} --sport 22 -s {ROUTER_LAN_IP} -d {LAN_IP_RANGE} -m state --state ESTABLISHED,RELATED -j ACCEPT
Jetzt geben wir den SAMBA Server fürs LAN frei:
iptables -A INPUT -p tcp -i {LAN_INTERFACE} --dport 137:139 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p udp -i {LAN_INTERFACE} --dport 137:139 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -p tcp -o {LAN_INTERFACE} --sport 137:139 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -p udp -o {LAN_INTERFACE} --sport 137:139 -m state --state ESTABLISHED,RELATED -j ACCEPT
Die oben genannten regeln ergeben folgendes Bild:
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT tcp -- 192.168.1.0/24 192.168.1.200 tcp dpt:ssh state NEW,RELATED,ESTABLISHED
ACCEPT tcp -- anywhere anywhere tcp dpts:netbios-ns:netbios-ssn state NEW,RELATED,ESTABLISHED
ACCEPT udp -- anywhere anywhere udp dpts:netbios-ns:netbios-ssn state NEW,RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
Chain FORWARD (policy DROP)
target prot opt source destination
Chain OUTPUT (policy DROP)
target prot opt source destination
ACCEPT tcp -- 192.168.1.200 192.168.1.0/24 tcp spt:ssh state RELATED,ESTABLISHED
ACCEPT tcp -- anywhere anywhere tcp spts:netbios-ns:netbios-ssn state RELATED,ESTABLISHED
ACCEPT udp -- anywhere anywhere udp spts:netbios-ns:netbios-ssn state RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
man sollte noch dem SAMBA Server erlauben einen Broadcast ins lokale Netz zu senden, um sich bekannt zu machen, andernfalls ist er zwar erreichbar, aber nicht in der Netzwerkumgebung zu sehen. Hier muss jedoch jeder selbst entscheiden ob er das will, auf großen LAN-Partys kann man unnötigen Traffic vermeiden, wenn man den Broadcast nicht zulässt.
iptables -A OUTPUT -p udp -o eth1 --sport 137:138 -d 192.168.1.255 -s 192.168.1.200 -j ACCEPT
nun sieht man den Server in der Windows-Netzwerkumgebung!
alle Eingaben die man gemacht hat kann man sichern mit:
service iptables save
die regeln werden dann in /etc/sysconfig/iptables gespeichert, leider ist die syntax in der Datei etwas anders, so dass ich ein direktes editieren der datei nicht empfehlen würde.
Danach kann man mit
chkconfig --list | grep iptables
nachschauen in welchen runleveln die iptables geladen werden, bei mir sieht es so aus:
iptables 0:Aus 1:Aus 2:Ein 3:Ein 4:Ein 5:Ein 6:Aus
also werden die regeln bei mir in Runleveln 2-5 geladen , das ist auch gut so, denn 0 ist HALT , fährt also den Rechner runter, 1 ist Single User(also auch ohne Netzwerkunterstützung) und 6 ist REBOOT...
sollten die regeln nicht geladen werden kann man mit z.B.
chkconfig --level 345 iptables on
die einstellungen bei jedem start in runlevel 3,4 und 5 laden.
Man kann natürlich auch ein script schreiben, mit dem man die Firewall lädt, das ersparrt viel Arbeit. Man benutzt dann nicht die "save" funktion des iptables services sondern schreibt die oben gennanten Regeln in ein Script. Diese Script lässt sich sehr einfach warten, besonders wenn es sehr viele Regeln werden, was mit der oben gennanten Methode eindeutig schwierig ist.
Ein Script mit oben genannten Regeln würde z.B. so aussehen:
#!/bin/bash
# Meine kleine Firewall
echo "Firewall starten... "
# ein paar Variablen deklarieren
IPTABLES=/sbin/iptables
MY_LAN_IP=192.168.1.200
LAN_INTERFACE=eth0
LAN_IP_RANGE=192.168.1.0/24
LAN_BROADCAST=192.168.1.255
WWW_INTERFACE=eth0
#Alles Regeln löschen
$IPTABLES -F
#Alles verbieten, was nicht erlaubt wird
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
$IPTABLES -P FORWARD DROP
# Loopback Interface freigeben
$IPTABLES -A INPUT -i lo -j ACCEPT
$IPTABLES -A OUTPUT -o lo -j ACCEPT
#SSH aus dem Lan erlauben
$IPTABLES -A INPUT -p tcp -i $LAN_INTERFACE --dport 22 -d $MY_LAN_IP -s $LAN_IP_RANGE -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A OUTPUT -p tcp -o $LAN_INTERFACE --sport 22 -s $MY_LAN_IP -d $LAN_IP_RANGE -m state --state ESTABLISHED,RELATED -j ACCEPT
#Samba ins Lan freigeben
$IPTABLES -A INPUT -p tcp -i $LAN_INTERFACE --dport 137:139 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A INPUT -p udp -i $LAN_INTERFACE --dport 137:139 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A OUTPUT -p tcp -o $LAN_INTERFACE --sport 137:139 -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A OUTPUT -p udp -o $LAN_INTERFACE --sport 137:139 -m state --state ESTABLISHED,RELATED -j ACCEPT
#Broadcast
$IPTABLES -A OUTPUT -p udp -o $LAN_INTERFACE --sport 137:138 -d $LAN_BROADCAST -s $MY_LAN_IP -j ACCEPT
echo "[fertig]"
exit 0
#end of file
Den obigen Text schreibt man mit seinem lieblings Editor in eine Datei und speichert sie z.B. als firewall, dann macht man die Datei mit
chmod 0700 firewall
nur noch fuer root lesbar, schreibbar und ausführbar. Ist man mit der Firewall komplett fertig würde ich die Datei als 0500 setzten, damit nicht ausversehen etwas geändert wird. Aber in der Test-Phase ist 0700 in Ordnung, da man öfter noch mal was ändern wird. Es ist auf jeden Fall sinnvoll nur root die Datei lesen zu lassen, erstens, weil root sowieso dieses script ausführen muss, denn nur root darf iptables Regeln setzten, zweitens, weil dann niemand die regeln lesen kann um Informationen ueber den Rechner zu bekommen auszunutzen.
Hat man dieses Script ist die Frage, wann man es ausführt. Ich persönlich würde es in der rc.local (RedHat,Mandrake,.. Bei Debian heißt die Datei anders..) aufrufen, um so bei systemstart die Regeln zu laden. Alternativ kann man auch einen ein eigenes Startscript benutzen, welches dann in die Ordner rc*.d gelinkt wird, oder aber man startet das script aus der ip-up.local beim verbinden zum internet. Es gibt viele Möglichkeiten, benutzt, die euch am besten gefällt (ihr könnt es auch jedesmal per Hand starten..).
Nachdem man mit
./firewall
oder wie auch sonst das script ausgeführt hat und keine Fehler aufgetaucht sind, man sollte nur
Firewall starten...
[fertig]
sehen, kann man mit
iptables --list
das Ergebnis begutachten, allerdings sollte man bedenken, dass hierbei nicht die Interfaces angezeigt werden, eine Zeile wie
z.B.
ACCEPT all -- anywhere anywhere
bedeutet nicht, dass alles Erlaubt wird, sondern es handelt sich z.B. um das Loopback Interface, auf welchem wir allen Verkehr erlaubt haben.
(Die Datei unter Windows zu schreiben und dann per Samba auf den Rechner zu übertragen führte bei mir zu fehlern, also lieber gleich unter Linux schreiben...)
Eines der Haupteinsatzgebiete fuer Firewalls sind sicherlich Router bzw. Gateways. Deshalb gehe ich hier noch darauf ein, wie man ein Script erstellt, welches sich fuer den Einsatz auf einem Router eignet. Ich gehe davon aus, dass man die Internetverbindung schon eingerichtet hat und beschreibe nur die Firewall und dass Masquerading/NAT.Da Wir die Firewall beim Systemstart laden wollen braucht das Script eine spezielle Form, es muss die Commandozeilen Parameter start und stop unterstüzen. Zusätzlich habe ich noch restart und help implementiert, damit ist das script noch universeller.
Hier erst mal das Script (alles nach einem $IPTABLES sollte in einer Zeile stehen, hier gibt es teilweise ungewollte zeilenumbrüche...):
#!/bin/bash
# chkconfig: 345 90 10
# description: Starts and Stops Firewall for a NAT Router
#
#Variablen
LAN_INTERFACE="eth0"
WAN_INTERFACE="ppp0"
LAN_IP="192.168.1.253"
LAN_RANGE="192.168.1.0/24"
LAN_BCAST="192.168.1.255"
IPTABLES="/sbin/iptables"
start() {
echo -n $"Firewall hochfahren..."
#Regeln loeschen
$IPTABLES -F
$IPTABLES -X
#Default Policy
$IPTABLES -P INPUT DROP
$IPTABLES -P FORWARD DROP
$IPTABLES -P OUTPUT DROP
#Loopback freigeben
$IPTABLES -A INPUT -i lo -j ACCEPT
$IPTABLES -A OUTPUT -o lo -j ACCEPT
#SSH fuer Verwaltung aus dem Lan freigeben
$IPTABLES -A INPUT -p tcp --dport 22 -i $LAN_INTERFACE -s $LAN_RANGE -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A OUTPUT -p tcp --sport 22 -o $LAN_INTERFACE -d $LAN_RANGE -m state --state ESTABLISHED,RELATED -j ACCEPT
#Masquerading fuer alles ausgehenden Verbindungen
$IPTABLES -t nat -A POSTROUTING -o $WAN_INTERFACE -j MASQUERADE
#IP-Spoofing loggen und verhindern
$IPTABLES -A FORWARD -s $LAN_RANGE -i $WAN_INTERFACE -j LOG --log-level 6 --log-prefix "FIREWALL:spoofing"
$IPTABLES -A FORWARD -s $LAN_RANGE -i $WAN_INTERFACE -j DROP
#begrenztes Forwarding erlauben
$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A FORWARD -i ! $WAN_INTERFACE -m state --state NEW -j ACCEPT
#Samba/Windows Broadcasts verwerfen (ueberfluten sonst die Logfiles)
$IPTABLES -A INPUT -p udp --ddort 137:138 -i $LAN_INTERFACE -j DROP
#e-donkey pakete droppen bevor geloggt wird (ueberfluten sonst die Logfiles)
$IPTABLES -A INPUT -p tcp --dport 4662 -i $WAN_INTERFACE -j DROP
#Alles loggen was bis hier hin durchgekommen ist, bevor es verworfen wird
$IPTABLES -A INPUT -j LOG --log-level 6 --log-prefix "FIREWALL:input"
$IPTABLES -A FORWARD -j LOG --log-level 6 --log-prefix "FIREWALL:forward"
$IPTABLES -A OUTPUT -j LOG --log-level 6 --log-prefix "FIREWALL:output"
echo
#IP Forwarding aktivieren
echo -n $"IP-Forwarding aktivieren..."
echo 1 > /proc/sys/net/ipv4/ip_forward
echo
exit 0
}
stop() {
echo -n $"Firewall runterfahren..."
#Regeln loeschen
$IPTABLES -F
$IPTABLES -X
#Default Policy auf Accept (alles durchlassen)
$IPTABLES -P INPUT ACCEPT
$IPTABLES -P FORWARD ACCEPT
$IPTABLES -P OUTPUT ACCEPT
exit 0
}
restart() {
$0 stop
$0 start
}
help() {
#prints a short help
cat << HELP
This Script starts/stops an Iptables-Based Firewall
Usage: firewall {start|stop|restart|help}
Example: ./firewall restart
check the Firewall-Rules with
iptables --list
HELP
exit 0
}
case "$1" in
start) start ;;
stop) stop ;;
restart) restart ;;
help) help ;;
*)
echo $"Usage : $0 {start|stop|restart|help}"
exit 1
esac
exit 0
#end of file
Dieses Script kann man in das Verzeichnis /etc/rc.d/init.d (RedHat basierende Systeme, bei z.B. Debian kann das Verzeichnis abweichen) kopieren und dann mit
chkconfig --add firewall
in den Systemstart Prozess einbinden. Damit das Funktioniert gibt es die Zeile
# chkconfig: 345 90 10
Diese teilt chkconfig mit, das die Firewall in den Runleveln 3,4 und 5 gestartet werden soll. Die Zahlen 90 und 10 legen die Reihenfolge fest. 90 fuer den Start 10 fuer das beenden. Das Tool chkconfig legt selbständig die Symlinks in den entsprechenden Verzeichnissen rcX.d an.
Das obige Script ist relativ offen fuer geroutete Verbindungen, es lässt vom internen Netz alle Verbindungen raus, aber nur bereits aufgebaute Verbindungen wieder rein. Relativ Sicher ist der Router selbst. Es sind nur Verbindungen per SSH aus dem internen Netz möglich. Diverse Sicherheitsscans bestätigen das, Der Router selbst ist von außen nicht erreichbar, kein Port ist offen, es wird auch nicht auf Pings geantwortet. Gegenüber Script-Kiddies dürfte diese Firewall erstmal eine Basis sein, ob das interne Netz noch etwas besser geschützt werden sollte , sei dahingestellt.
Bei der hier dargestellten Lösung, braucht man keine Regeln in die ip-up.local zu schreiben, da alles vom Firewall Script beim Systemstart erledigt wird.
Das Script gibt es zum download unter : http://sites.rcs4u.de/arne/files/scripte/firewall
(leichte Abweichungen sind möglich)
Die beiden Iptables Firewall-Scripte sind auf keinen Fall komplett, aber eine Basis sollte man damit haben. Fuer mich funktionieren die Scripte gut.
Disclaimer: Ich übernehme hier keine Verantwortung fuer die Scipte. Wenn man alles in der Konsole eingibt, werden die änderungen sofort übernommen, und man sieht ob es geht, geht es nicht startet man neu und die regeln sind wieder gelöscht, es sein denn man hat "save" ausgeführt, dann hilft allerdings
service iptables restart
dadurch werden alle policys auf ACCEPT gesetzt, den ausgangs zustand und alle regeln gelöscht.
25.01.2005: Tippfelher behoben, Dank an Rolf G.
-------------------------
09.05.2004: Tippfehler behoben (Dank an Martin F.),
außerdem einen Download-Link hinzugefügt für ein
komplettes Script.
-------------------------
18.02.2004: Tippfehler behoben
-------------------------
25.01.2003: Masquerading-Router mit IPTables Firewall
-------------------------
15.01.2003: Firewall als Script, su-Hinweis, kleine Ergänzungen und überarbeitung des Layouts
-------------------------
10.10.2002: Samba Broadcast hinzugefügt
-------------------------
05.10.2002: Erste Fassung