Linux-Systeme vor Angriffen schützen, Teil 2
Schotten dicht!
Wir gehen davon aus, dass Sie wie in der letzten Ausgabe beschrieben die wichtigsten – oder unnützesten – Dienste abgeschaltet haben, und können uns der Absicherung der verbleibenden Daemons zuwenden. Dazu verwenden wir eine Firewall, die Zugriffe von draußen reglementiert.
Das Thema Firewall ist als überaus komplex verschrien – leider zu Recht, doch für den Heimgebrauch ist man mit nur ein paar Zeilen dabei. Administratoren, die große Server bei Firmen und Providern konfigurieren, müssen viele Randbedingungen und Spezialdienste berücksichtigen, die beim Heimanwender keine oder nur eine untergeordnete Rolle spielen.
Für unser Beispiel verwenden wir einen Rechner, der sich via ISDN-Karte ins Internet einwählt. Als Interface verwenden wir hier ippp0
, und benutzen 192.168.1.1 als unsere vom Internet-Provider zugewiesene Adresse (IP). Modem-Benutzer brauchen lediglich das "i" im Gerätenamen weg lassen, das Modem-Interface heißt meist ppp0
. Auch Netzwerkkarten können benutzt werden, hier wird entsprechend eth0
verwendet, die Vorgehensweise ist stets gleich.
Die Firewall arbeitet als Filter zwischen allen Netzwerk-Geräten wie Modems, ISDN- und Netzwerkkarten und dem internen Bereich. Welche Daten letztendlich wo landen, wird dabei durch Filter-Regeln festgelegt. Für diese Regeln gibt es vier grundlegende Bereiche: Alle in der Sektion input
eingetragenen Regeln werden wie eine Kette (chain) nacheinander auf alle ankommenden Datenpakete angewandt, während die unter output
stehenden Regeln nacheinander auf alle ausgehenden Datenpakete Anwendung finden. forward
-Regeln dienen insbesondere dem Masquerading, und als viertes können eigene Sektionen angelegt und mit Regeln bestückt werden. Dies ist im Heimbereich meist nicht nötig, und auf Masquerading werden wir in einem gesonderten Artikel eingehen.
Die Standard-Kernel der meisten Distributionen sind bereits mit Firewall-Support versehen, so dass ein Neu-Übersetzen entfällt. Auch das benötigte Paket ipchains
wird bei fast allen Standard-Installationen eingerichtet, im Zweifelsfall finden Sie es bei den Netzwerk-Utilities und müssen es nachinstallieren.
Wie oben angesprochen wollen wir die "Schotten dicht" machen und nur einzelne, handverlesene Dienste freigeben. Dieses Vorgehen hat prinzipiell Nachteile, doch darauf gehe ich bei den entsprechenden Regeln noch genauer ein. Mit ipchains -n -L
können Sie sich jederzeit die jeweils eingerichteten Regeln ansehen. Eingangs ist alles erlaubt:
linux:~ # ipchains -L Chain input (policy ACCEPT) Chain forward (policy ACCEPT) Chain output (policy ACCEPT)
Unter policy
ist die grundsätzliche Haltung gegenüber den Datenpaketen zu verstehen: Sind alle Regeln einer Kette (chain) auf das Paket angewandt worden, ohne dass das Paket an eine andere Stelle weiter geleitet wurde, wird es bei ACCEPT
akzeptiert oder bei DENY
verworfen. Wir wollen in unserem Fall erreichen, dass alles verboten wird, was nicht ausdrücklich erlaubt ist. Deshalb setzen wir die Input-Policy auf DENY
:
ipchains -P input DENY
Die Regeln werden stets in Reihenfolge ihres Eintrags abgearbeitet – wir müssen also erst sagen, was wir von ippp0
akzeptieren, bevor wir den Rest verwerfen. Wenn ein Regelsatz, der offensichtlich keinen Fehler enthält, nicht funktioniert, liegt es meist an der falschen Reihenfolge. Ist ein Paket einmal verworfen, kann man es nicht in der nächsten Regel zurück bekommen.
Nun geht erst einmal überhaupt nichts mehr: Alle Daten, egal ob wir sie über Netzwerk, ISDN, Modem oder auch lokal erhalten, werden verworfen. Damit wir lokal alle Dienste benutzen können und auch unsere grafische Oberfläche weiterhin funktioniert, müssen wir uns selbst von der Verwerfung ausnehmen:
ipchains -A input -i lo -j ACCEPT
Der Parameter -A
gibt an, dass wir eine Regel hinzufügen wollen, input
steht für die gewünschte Sektion – alle ankommende Daten. Danach folgt die eigentliche Filter-Regel. -i lo
betrifft alle über das Loopback-Device hereinkommenden Daten – das Loopback-Device können nur Programme benutzen, die auf unserem Rechner lokal laufen und Verbindung zu anderen Programmen oder Diensten auf unserer Maschine suchen. Mit -j
sagen wir schließlich, was mit den Paketen geschehen soll: Sie werden akzeptiert.
Die totale Abschottung hat nicht nur positive Effekte. So erhalten wir Nachrichten, dass wir beispielsweise einen Server nicht erreichen können, nicht mehr. Diese Nachrichten sind für einen reibungslosen Internet-Verkehr aber sehr wichtig. Deshalb lassen wir sie als erstes zu, und war aus allen Richtungen:
ipchains -A input -p icmp -j ACCEPT
Der Parameter -p icmp
benennt das Protokoll ICMP, das für die Übertragung der Nachrichten zuständig ist; -j ACCEPT
steht wiederum für die Verfahrensweise: akzeptieren.
Nameserver freischalten
Ein ebenfalls sehr wichtiger Dienst ist der Domain Name Service, kurz DNS. Die DNS-Server, kurz Nameserver, sorgen für die Auflösung von beispielsweise http://www.linux-user.de in die IP-Adresse des Servers, hier 195.143.20.36
. Ohne diese IP-Adresse geht im Internet gar nichts. Deshalb müssen wir auch unsere Nameserver freischalten.
Dazu benötigen Sie das Script aus Listing 1, das Sie unter dem Namen resolv-list
im Verzeichnis /usr/local/bin
speichern. Bitte vergessen Sie nicht, es anschließend mit chmod a+x /usr/local/bin/resolv-list
ausführbar zu machen.
Listing 1
if [ -r /etc/resolv.conf ]; then set – `grep -i nameserver /etc/resolv.conf` while [ $# -ge 2 ]; do echo $2 shift 2 done fi
resolv-list
liefert uns eine Liste der verwendeten Nameserver, die wir mit folgenden Befehlen in unserer Firewall freischalten:
for ns in `/usr/local/bin/resolv-list`; do ipchains -A input -s $ns 53 -d 192.168.1.1 1024: -i ippp0 -p udp -j ACCEPT ipchains -A input -s $ns 53 -d 192.168.1.1 1024: -i ippp0 -p tcp -j ACCEPT done
Der Unterschied der beiden ipchains
-Zeilen liegt in der Protokoll-Angabe mittels -p
, hier einmal UDPund einmal TCP. Als Beispiel-Nameserver benutzen wir 192.168.2.1, je nach Internet-Provider unterscheidet sich die IP bei Ihnen. Es könnten aber auch mehrere Nameserver eingetragen sein, Linux verkraftet bis zu drei.
Die Adresse der Datenquelle wird mit -s
angegeben, in unserem Beispiel wurde hier die Variable $ns
eingetragen. Dahinter haben wir mit "53" die Port-Nummer, oder auch Dienste-Kennung, stehen. Schließlich wird noch das Ziel mit -d
benannt, wobei auch hier die erlaubten Port-Nummern eingegrenzt werden können. Durch die Angabe 1024:
haben wir alle Port-Nummern ab 1024 aufwärts bis 65535 erlaubt. Ports unterhalb von 1024 haben einen Sonderstatus, doch dazu später mehr.
Wenn Sie nun ipchains -n -L
eingeben, sollten Sie folgende Liste erhalten:
Chain input (policy ACCEPT) target prot opt source destination ports ACCEPT all —— 0.0.0.0/0 0.0.0.0/0 n/a ACCEPT icmp —— 0.0.0.0/0 0.0.0.0/0 * -> * ACCEPT udp —— 192.168.2.1 192.168.1.1 53 -> 1024:65535 ACCEPT tcp —— 192.168.2.1 192.168.1.1 53 -> 1024:65535 Chain forward (policy ACCEPT) Chain output (policy ACCEPT)
Erschrecken Sie nicht bei der zweiten Zeile – auch wenn es hier so aussieht, als ob alles überall erlaubt wäre, ist dem nicht so. In dieser Ausgabeform wird der Gerätename, auf den sich die Regel bezieht, nicht angezeigt, und wir hatten bei der Einrichtung mit -i lo
das lokale Loopback-Device angegeben.
Zugang erwünscht
Wir wollen zudem erlauben, dass sich bekannte Anwender auf unserem System einloggen können. Damit Benutzername und Passwort nicht ausgespäht werden können, erlauben wir nur die Verwendung der verschlüsselten Secure Shell, kurz SSH. Den dafür zuständigen Daemon sshd
haben wir wohlweislich beim Daemon-Killen der letzten Ausgabe ausgespart. Die Freigabe erfolgt mit der Regel:
ipchains -A input -d 192.168.1.1 ssh -p tcp -i ippp0 -j ACCEPT
Mit dem Parameter -i ippp0
betrifft die Regel alle über die ISDN-Karte hereinkommenden Daten. Hätten wir noch eine Netzwerkkarte, an der weitere Linux-Rechner angeschlossen sind, so könnte sich von dort aus niemand mehr bei uns anmelden – wir haben die Regel auf die ISDN-Karte beschränkt und lehnen alles andere standardmäßig ab.
Diese Regel lässt also alle Datenpakete durch, die für den SSH-Dienst des Rechners 192.168.1.1 bestimmt sind und über die ISDN-Karte ippp0
hereinkommen. Da das Paket bereits akzeptiert ist, würden alle anderen Regeln nicht mehr zum Zug kommen. ipchains -n -L
liefert uns nun:
Chain input (policy ACCEPT) target prot opt source destination ports ACCEPT all —— 0.0.0.0/0 0.0.0.0/0 n/a ACCEPT icmp —— 0.0.0.0/0 0.0.0.0/0 * -> * ACCEPT udp —— 192.168.2.1 192.168.1.1 53 -> 1024:65535 ACCEPT tcp —— 192.168.2.1 192.168.1.1 53 -> 1024:65535 ACCEPT tcp —— 0.0.0.0/0 192.168.1.1 * -> 22 Chain forward (policy ACCEPT) Chain output (policy ACCEPT)