Linux Server - Firewall
Aufbau eines eigenen Firewall-Scripts
Um ein komplettes Firewallscript zu schreiben fehlt uns hier der benötigte Rahmen, wir können aber die Regeln für die wichtigsten Dienste hier formulieren und alles weitere kann dann - sofern erwünscht - hinzugefügt werden.Wir erstellen die Regeln am Besten in einem Shellscript, das wir dann jedesmal einfach aufrufen können, dann stellt sich gar nicht erst die Frage, wie einzelne Regeln gespeichert werden.
Das Script beginnt üblicherweise mit einem ganzen Satz von Variablendefinitionen, damit wir uns später leichter mit der Formulierung der Regeln tun:
#!/bin/bash EXTERN_INTERFACE=eth0 # Unsere Netzschnittstelle LOOP_INTERFACE=lo # Das Loopback Interface IPADDR=10.230.1.100 # Unsere IP-Adresse ANYWHERE=any/0 # Jede Adresse im Netz MYNET=10.230.1.0/24 # Unsere Netzadresse UNPRIVPORTS=1024:65535 # Die unprivilegierten PortsAls nächstes löschen wir alle bestehenden Regeln. Falls wir das Script einmal mehrfach hintereinander starten kommt es so nicht zu Doppelregeln. Dadurch, dass wir keine Regelkette angeben, werden alle bestehenden Regelketten gelöscht.ipchains -FAlle Ketten sind jetzt leer. Allerdings haben wir noch nicht die Grund-Policies gelöscht bzw. verändert. Sie bleiben auch nach dem Löschen vorhanden. Also stellen wir jetzt diese Policies ein, für jede Kette extra. Dazu stellt ipchains den Parameter -P (nicht verwechseln mit -p) zur Verfügung. Wir setzen alle drei Regelketten auf die Grundeinstellung DENY, also ist alles verboten, was nicht explizit erlaubt ist.ipchains -P input DENY ipchains -P output DENY ipchains -P forward DENYAb hier ist jetzt also alles verboten. Es existieren keinerlei Regeln mehr, die Grundeinstellung ist DENY. Wir können uns ab diesem Moment nicht einmal mehr selbst anpingen.Damit das Loopback-Interface wieder funktioniert erlauben wir in den nächsten beiden Regeln grundsätzlich alles auf diesem Interface.
ipchains -A input -i $LOOP_INTERFACE -j ACCEPT ipchains -A output -i $LOOP_INTERFACE -j ACCEPTJetzt erlauben wir alle ICMP-Pakete auf der Netzschnittstelle. Wir könnten zwar hier verschiedene Einschränkungen machen, aber das ist langwierig und kompliziert. Viele Programme benötigen ICMP-Nachrichten um z.B. eine Nichtverfügbarkeit oder ähnliche Fehlermeldungen zu übertragen.ipchains -A input -i $EXTERN_INTERFACE -p icmp -j ACCEPT ipchains -A output -i $EXTERN_INTERFACE -p icmp -j ACCEPTJetzt funktioniert wenigstens ein Ping schonmal wieder. Allerdings nur mit numerischen IP-Adressen. Denn wir haben noch keinerlei Zugriff auf Nameserver. DNS funktioniert in den meisten Fällen über UDP auf Port 53. Wir können jetzt die erste vollständige Regel anwenden, indem wir den Zugriff auf Nameserver freischalten. Da uns über Port 53 wenig Gefahr droht geben wir ihn für alle frei, nicht nur für einen bestimmten Nameserver. Falls das nicht gewünscht wöre, müsste der Eintrag $ANYWHERE durch die IP-Adresse des Nameservers ersetzt werden.ipchains -A output -i $EXTERN_INTERFACE -p udp\ -s $IPADDR $UNPRIVPORTS \ -d $ANYWHERE 53 -j ACCEPT ipchains -A input -i $EXTERN_INTERFACE -p udp\ -s $ANYWHERE 53 \ -d $IPADDR $UNPRIVPORTS -j ACCEPTJetzt können wir anfangen, die wichtigen Dienste einzeln zu erlauben. Zunächst einmal HTTP (TCP Port 80) und HTTP mit SSL (TCP Port 443) Wir erlauben nur Antworten eines Servers an uns.ipchains -A output -i $EXTERN_INTERFACE -p tcp\ -s $IPADDR $UNPRIVPORTS \ -d $ANYWHERE 80 -j ACCEPT ipchains -A input -i $EXTERN_INTERFACE -p tcp ! -y\ -s $ANYWHERE 80 \ -d $IPADDR $UNPRIVPORTS -j ACCEPT ipchains -A output -i $EXTERN_INTERFACE -p tcp\ -s $IPADDR $UNPRIVPORTS \ -d $ANYWHERE 443 -j ACCEPT ipchains -A input -i $EXTERN_INTERFACE -p tcp ! -y\ -s $ANYWHERE 443 \ -d $IPADDR $UNPRIVPORTS -j ACCEPTSind wir selbst auch Webserver, dann müssen wir auch Zugriffe fremder Clients auf unseren Server zulassen und unsere Antwortpakete an diese Clients. Das könnte mit der Einschränkung passieren, dass wir nur Clients aus dem lokalen Netz ($MYNET) akzeptieren.ipchains -A input -i $EXTERN_INTERFACE -p tcp\ -s $MYNET $UNPRIVPORTS \ -d $IPADDR 80 -j ACCEPT ipchains -A output -i $EXTERN_INTERFACE -p tcp ! -y\ -s $IPADDR 80 \ -d $MYNET $UNPRIVPORTS -j ACCEPTSchwieriger wird es mit FTP. Hier existieren zwei Portnummern (20 und 21), eine für den FTP-Befehlskanal und eine für den Datenkanal. Zudem existieren zwei Modi, der sogenannte aktive Modus und der passive Modus, der von den meisten Browsern verwendet wird. Der Unterschied liegt darin, dass der passive Modus beim Datenkanalaufbau auf beiden Ports (Sender und Empfänger) unprivilegierte Portnummern verwendet. Wir brauchen also 6 Regeln um als Client an einen FTP Server zu kommen:In der oben genannten Reihenfolge sieht das also folgendermaßen aus:
- Anfrage des lokalen Clients beim fremden Server
- Antwort des fremden Servers
- Datenkanalaufbau durch den fremden Server (aktiv)
- Antwort auf Datenkanalaufbau durch den lokalen Client (aktiv)
- Datenkanalaufbau des Clients zum fremden Server (passiv)
- Antwort des fremden Servers auf Datenkanalaufbau (passiv)
ipchains -A output -i $EXTERN_INTERFACE -p tcp \ -s $IPADDR $UNPRIVPORTS\ -d $ANYWHERE 21 -j ACCEPT ipchains -A input -i $EXTERN_INTERFACE -p tcp ! -y \ -s $ANYWHERE 21\ -d $IPADDR $UNPRIVPORTS -j ACCEPT ipchains -A input -i $EXTERN_INTERFACE -p tcp\ -s $ANYWHERE 20\ -d $IPADDR $UNPRIVPORTS -j ACCEPT ipchains -A output -i $EXTERN_INTERFACE -p tcp ! -y\ -s $IPADDR $UNPRIVPORTS\ -d $ANYWHERE 20 -j ACCEPT ipchains -A output -i $EXTERN_INTERFACE -p tcp\ -s $IPADDR $UNPRIVPORTS\ -d $ANYWHERE $UNPRIVPORTS -j ACCEPT ipchains -A input -i $EXTERN_INTERFACE -p tcp ! -y\ -s $ANYWHERE $UNPRIVPORTS\ -d $IPADDR $UNPRIVPORTS -j ACCEPTDas Gleiche in umgekehrter Reihenfolge wäre dann für einen eigenen FTP-Server nötig.Dabei belassen wir es einmal, die Grundzüge des Aufbaus der Firewallscripts sind damit eigentlich geklärt. Das ganze Script ist hier nochmal am Stück einsehbar.
Unsere Firewall schützt bisher natürlich nur uns selbst, Aber die Mechanismen sind natürlich auch bei einer Firewall mit zwei Netzwerkkarten im Grunde die selben.
[Zurück zur Firewall-Seite]