Beschreibung: Prüfungskandidaten sollten in der Lage sein, die Systemkonfiguration zu überprüfen, um die Sicherheit des Hosts in Übereinstimmung mit lokalen Sicherheitsrichtlinien sicherzustellen. Dieses Lernziel beinhaltet die Konfiguration von tcpwrappers, das Finden von Dateien mit gesetztem SUID/SGID-Bit, das Überprüfen von Softwarepaketen, das Setzen oder Ändern von Benutzerkennwörtern und des Ablaufs von Kennwörtern, das Aktualisieren von Programmdateien nach Empfehlung von CERT, Bugtraq und/oder Sicherheitswarnungen des Distributors. Ebenfalls enthalten ist ein grundsätzliches Wissen über ipchains und iptables.
Die wichtigsten Dateien, Bezeichnungen und Anwendungen:
Diese Techniken werden hier nicht näher beschrieben, sondern als Wissen vorausgesetzt.
Um das ganze System nach Dateien zu durchsuchen, die dieses Bit (oder eines dieser Bits) gesetzt haben, benutzen wir den Befehl find. Mit der Suchoption -perm ist es möglich, Dateien zu suchen, die bestimmte Rechte gesetzt haben. Ein Zugriffsrecht von 4XXX bedeutet, daß das SUID-Bit gesetzt ist, ein 2XXX gibt an, daß das SGID-Bit gesetzt ist. Die Summe davon (6XXX) wären beide Bits gesetzt. Wenn dem angegebenen Zugriffsrecht ein Minuszeichen vorangeht, so ist gemeint, daß mindestens diese Rechte gesetzt sein müssen, es reicht also, nach 4111 oder gar 4000 zu suchen, wenn wir alle Programme mit SUID-Bit suchen.
find / -perm -4000 -user rootsucht alle Dateien des gesamten Systems, die das SUID-Bit gesetzt haben und dem User root gehören. Das sind zunächst einmal überraschend viele Programme, es wäre also ratsam, die Ausgabe dieses Befehls direkt nach der Installation in eine Datei umzuleiten und regelmäßig den Befehl erneut aufzurufen und mit dieser Datei zu vergleichen.
Das entsprechende zum SGID-Bit wäre der Befehl
find / -perm -2000 -group rootDie Angabe des Users wurde hier weggelassen, stattdessen suchen wir nach Dateien, die der Gruppe root zugehören. Ohne diese Angabe, würden alle Dateien mit gesetztem SGID-Bit angezeigt.
Die Firewalltechnik unter Linux basiert auf sogenannten Paketfilterregeln. Ein- und ausgehende Pakete können nach folgenden Kriterien durchgelassen oder abgewiesen werden:
Die Regeln werden mit einem kommandozeilenorientierten Programm formuliert und stehen dann im Kernelspeicher. Die eigentliche Firewall, also das Programm, das Pakete durchlässt oder abweist, ist kein separates Programm sondern der Kernel selbst.
Dieses Programm, zur Formulierung der Regeln hat zwischen der Kernel-Version 2.2 und 2.4 gewechselt. Das Standard-Programm bei Kerneln der 2.2 Reihe war ipchains. Es funktioniert unter gewissen Umständen auch noch bei neueren Kerneln. Seit der Version 2.4 existiert stattdessen das Programm iptables, das die selbe Aufgabe hat, sie aber etwas anders löst. Eine Grundkenntnis beider Programme wird für die LPI102 Prüfung vorausgesetzt.
Bevor jedoch die einzelnen Programme besprochen werden, noch etwas Theorie, die für das Verständnis beider Programme unabdingbar ist.
Im Prinzip laufen alle Übertragungen nach dem gleichen Muster ab. Ein Client fängt mit einer Anfrage an einen Server an und der antwortet ihm. Dabei spielen die Portnummern eine große Rolle. Um einen Dienst auf einem anderen Rechner anzusprechen, muß der Client also die IP-Adresse des Servers und die Portnummer des gewünschten Dienstes kennen. Damit der Server ihm auch antworten kann, muß der Client auch seine eigene IP-Adresse angeben und eine Portnummer, auf der er selbst lauscht. Da der Client keine fest zugewiesene Portnummer besitzt, wählt er sich einfach eine beliebige Nummer aus dem Pool der unprivilegierten Portnummern (1024 bis 65535) aus.
Wir können also davon ausgehen, daß ein Paket mit einer Anfrage des Clients an den Server folgendes an Header-Information beinhaltet:
Eine Ausnahme dieses Prinzips haben wir bei ICMP, dort hat der Sender selbst keinen Port bzw. keinen Pakettyp.
Der Client schickt ein Paket mit folgender Header-Information an den Server:
Empfänger IP: | Empfänger Port: | Sender IP: | Sender Port: | Flags: |
---|---|---|---|---|
IP-Adresse des Servers z.B. 123.45.67.89 | Portnummer des gewünschten Dienstes z.B. 80 | Eigene IP-Adresse des Clients z.B. 111.22.33.44 | Zufällige Portnummer z.B. 12345 | SYN |
Der Client setzt also das SYN-Flag, gleichbedeutend mit der Nachfrage nach einem Verbindungsaufbau (Synchronisation). Der Server schickt jetzt ein Paket zurück, das folgende Information beinhaltet:
Empfänger IP: | Empfänger Port: | Sender IP: | Sender Port: | Flags: |
---|---|---|---|---|
IP-Adresse des Clients-111.22.33.44 | Portnummer des Clients-12345 | IP-Adresse des Servers-123.45.67.89 | Portnummer des Server-Dienstes-80 | SYN und ACK |
Der Server setzt also einerseits das ACK (Acknowledge) Flag um zu zeigen, daß er den Verbindungsaufbau gewährt und setzt zusätzlich nochmal das SYN-Flag um seinerseits die Verbindung anzufordern. Das nächste Paket des Clients enthält jetzt nur noch das ACK-Flag:
Empfänger IP: | Empfänger Port: | Sender IP: | Sender Port: | Flags: |
---|---|---|---|---|
IP-Adresse des Servers-123.45.67.89 | Portnummer des Server-Dienstes-80 | IP-Adresse des Clients-111.22.33.44 | Portnummer des Clients-12345 | ACK |
Von diesem Moment an gilt die Verbindung als etabliert und alle weiteren Pakete haben jetzt grundsätzlich das ACK-Flag und niemals mehr das SYN-Flag gesetzt. Aus dieser Handshake-Methode heraus ist anhand der Flags grundsätzlich festzustellen, ob ein Paket eine Nachfrage eines Clients an einen Server darstellt oder nicht. Zusammengefasst kann man sagen, daß ein Paket immer dann eine Client-Nachfrage beinhaltet, wenn das SYN-Flag gesetzt und das ACK-Flag nicht gesetzt ist.
Diese fünf (TCP) bzw. vier (UDP) Kriterien stehen uns also für die Firewall zur Verfügung. Anhand dieser Eigenschaften müssen wir entscheiden, ob wir ein Paket durchlassen oder nicht.
Es stehen drei Grundeinstellungen zur Verfügung:
Der zweite Fall ist mit Sicherheit die bessere Wahl, wenn es darum geht, ein System richtig abzusichern, auch wenn es zunächstmal mehr Arbeit bedeutet. Schematisch dargestellt könnte man die Grundeinstellung ACCEPT folgendermaßen darstellen:
Die DENY-Grundeinstellung hingegen sähe so aus:
ipchains formuliert Regeln, die dann direkt in den Speicher geschrieben werden. Das hat zur Folge, daß diese Regeln nach einem Neustart allesamt wieder verschwunden sind. Es empfielt sich also, die Regeln in Form eines Shellscripts zu formulieren.
Um Regeln zu definieren werden wir also mit ipchains -A arbeiten. Der Angabe der Kette folgen dann die entsprechenden Regelformulierungen.
IP-Adressen können mit einer Maske versehen werden, die die signifikannten Bits der Adresse angibt. Diese Maske wird als Bitmaske realisiert und einfach mit einem Slash (/) hinten an die Adresse angehängt. Die Bedeutung ist einfach, die Adressangabe
192.168.100.123/24bedeutet, daß die ersten 24 Bit der Adressangabe mit der gefundenen Adresse übereinstimmen müssen, damit die Regel greift. In diesem Beispiel sind das also alle Adressen, die vorne 192.168.100 stehen haben. Eine Maske /32 bedeutet also, daß die Adresse exakt übereinstimmen muß, eine Maske /0 bedeutet, daß kein Bit übereinstimmen muß, also alle Adressen gemeint sind. Dafür ist auch die Abkürzung any/0 zulässig.
Ports werden als Nummern angegeben. Soll ein ganzer Bereich von gültigen Portnummern angegeben werden, so wird das in der Form
ipchains -A Regelkette -i Interface -p Protokoll \ -s Absenderadresse Absenderport \ -d Empfängeradresse Empfängerport -j PolicyIn manchen Fällen wird dem Protokoll noch die Angabe ! -y folgen oder einzelne Ports werden weggelassen. Aber der grundsätzliche Aufbau hält sich immer an diese Struktur.
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, daß 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, daß 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, daß 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:
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. Jedes verwendete Protokoll benötigt also einen Regelsatz, der sowohl die eingehenden, als auch die ausgehenden Pakete berücksichtigt.
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.
Drei Standard-Tabellen stehen zur Verfügung:
Der Befehl iptables erhält die Information, welche Tabelle er bearbeiten soll durch den Parameter -t Tabelle. Wird diese Angabe weggelassen, so wird standardmäßig die Tabelle filter angenommen.
Die eigentliche Formulierung der Regeln selbst entspricht ziemlich genau der von ipchains.
Es gibt zwei große Einrichtungen, die zentral solche Sicherheitslücken aufdecken und veröffentlichen: BUGTRAQ und CERT.
BUGTRAQ ist eine moderierte Mailingliste, die für die detailierte Diskussion und Veröffentlichung von Sicherheitsproblemen zuständig ist. Hier wird beschrieben, was Sicherheitslücken genau sind, wie herausgefunden wird, ob sie ein bestimmtes System betreffen und wie sie beseitigt werden können.
Um sich an dieser Mailingliste zu beteiligen - lesend oder schreibend - muß eine Mail an LISTSERV@SECURITYFOCUS.COM geschickt werden, die im Mailkörper - nicht in der Überschrift - die folgende Anweisung besitzt:
SUBSCRIBE BUGTRAQ Nachname, VornameMan erhält anschließend eine Bestätigungsmail, die man beantworten muß. Sobald diese Antwort auf die Bestätigungsmail eingegangen ist, ist man Mitglied der Liste und erhält regelmäßig die Nachrichten über neu entdeckte Sicherheitslücken.
Auf der Webseite von www.securityfocus.com können die Archive der Mailingliste eingesehen werden.
Die zweite große Institution für die Veröffentlichung von Sicherheitslücken ist CERT. Auf der Webseite von www.cert.org werden regelmäßig neue Sicherheitslücken und Lösungen dazu veröffentlicht.
Weitere wichtige Adressen im Internet sind
Zusätzlich veröffentlichen die Linux-Distributoren selbst Nachrichten über Sicherheitslücken und liefern etsprechende Bug-Fixes. Ein paar Beispiele wären:
Diese Informationsquellen sollten regelmäßig konsultiert werden, um über neue Sicherheitsprobleme informiert zu sein und auftretende Schlupflöcher zu schließen.
Selbst wenn alle möglichen Dienste, die von außen zugreifbar sind, geschlossen wurden, so existiert mit socket eine Möglichkeit, Angriffe von innen heraus zuzulassen. Das Programm sollte also mit Vorsicht benutzt werden und sicherheitshalber nicht für alle User zugänglich sein.