IP Filter Based Firewalls HOWTO Brendan Conoboy Erik Fichtner Sat Jan 13 11:22:26 EST 2001 Uebersetzung von Thorsten Lindloff URL: www.lindloff.com Abstraktes: Dieses Dokument soll einen neuen User in den Gebrauch des PFILTER- Firewalling- Pakets einfuehren und gleichzeitig dem Benutzer das fundamentale Grundwissen im guten Firewall- Design vermitteln. 1. Einfuehrung IPFilter ist ein grossartiges, kleines Firewallpaket. Es macht alles, was andere freie Firewalls auch tun (ipchains, ipfwadm); aber es ist auch genauso portierbar und leistet ein paar interessante Dinge, die die Anderen nicht tun. Dieses Dokument wurde verfasst, um die zur Zeit spaerliche Dokumentation von IPFilter zu verbessern. Ein paar Vorkenntnisse in der Konfiguration von Paketfiltern sind nuetzlich; wobei allerdings bei zu genauer Kenntnis dieser Programme das Lesen dieses Dokumentes eine gewisse Zeitverschwendung darstellt. Um einen tieferen Einblick in die Materie zu gewinnen, empfehlen die Autoren das Buch "Building Interent Firewalls" von Chapman & Zwicky aus dem O'Reilly- Verlag und "TCP/IP Illustrated, Volume 1" von Stevens aus dem Verlag Addison-Wesley 1.1 Haftungsausschluss Die Autoren dieses Dokumentes sind nicht fuer Probleme verantwortlich, die bei Aktionen, die nach dieser Anleitung durchgefuehrt werden, entstehen koennen. Das Dokument ist als eine Einfuehrung in den Bau einer IPFilter- basierten Firewall gedacht. Wenn Du nicht komfortabel damit bist, die Verantwortung fuer Deine eigenen Aktionen zu uebernehmen, dann suche Dir lieber einen qualifizierten Profi fuer diese Aufgabe, der die Firewall fuer Dich aufsetzt. -2- 1.2. Copyright Sofern es nicht anders angegeben wird, liegen die Urheberrechte fuer Howtos bei den Autoren. HOWTOs duerfen ganz oder in Teilen, in jedem Medium (Physisch oder elektronisch) weiterverbreitet werden, wenn dieser Hinweis mit weitergegeben wird. Ein kommerzieller Vertrieb ist durchaus erlaubt und erwuenscht; die Autoren wollen allerdings ueber diese Art der Weiterverbreitung informiert werden. Alle Uebersetzungen, Ableitungen oder Überarbeitungen, die in andere HOWTOS uebernommen werden, muessen unter dieser Coyright- Notiz weitergegeben werden. Das heisst: Es duerfen keinerlei zusaetzliche Beschraenkungen in das Dokument aufgenommen werden, wenn das Dokument ueberarbeitet und/oder weitergegeben wird. Ausnahmen von dieser Regel koennen unter bestimmten Bedingungen gemacht werden. In so einem Fall bitte den HOWTO- Koordinator kontaktieren. Kurz gesagt: Wir wollen, dass diese Informationen weiterverbreitet werden; und das ueber so viele Kanaele wie moeglich. Wie auch immer: Wir moechten die Copyrights fuer diese HOWTO- Dokumente behalten und wollen informiert werden, wenn es irgendwelche Plaene gibt, diese HOWTOs weiter zu verbreiten. 1.3. Wo es die wichtigsten Teile gibt Die ofizielle IPF- Homepage ist unter: Die neueste Version findet sich unter: 2. Firewalling - Die Basics Diese Sektion dient dazu, Dich mit der ipfilter- Syntax und der Firewall- Theorie im Allgemeinen vertraut zu machen. Die hier diskutierten Features finden sich in jedem guten Firewallpaket. Dieser Teil des Dokumentes soll ein solides Fundament im einfachen Lesen und Verstehen des "Advanced- Teils" sein. Es muss einem aber bewusst sein, dass dieser Teil fuer sich genommen nicht ausreichend ist, um eine gute Firewall zu aufzusetzen. Der "Advanced- Teil" ist wirklich Voraussetzung, fuer jeden, der ein effektives Sicherheitssystem braucht. -3- 2.1. Konfigurationsdatei: Reihenfolge, Dynamik und Vorrang IPF (IPFilter) besitzt eine Konfigurationsdatei (um nicht zu sagen, dass jedes Kommando nochmal und nochmal fuer jede Regel ausgefuehrt wird). Die Datei entspricht den Unix- Standards: Die "#" markiert einen Kommentar; und man kann Regeln und Kommentare gemeinsam in der selben Zeile haben. Zusaetzlicher "Whitespace" ist erlaubt und fuer eine bessere Lesbarkeit der Regeln empfehlenswert. 2.2. Ausfuehren der Regeln Die Regeln werden immer von Anfang bis Ende der Datei ausgefuehrt; immer eine nach der anderen. Das meint schlicht und ergreifend, dass eine Regel wie diese: block in all pass in all ...vom Computer so gesehen wird: block in all pass in all Was bedeutet, dass, falls ein Paket hereinkommt, ist das erste, was IPF tut das hier: block in all Sollte IPF es fuer noetig halten, zur naechsten Regel zu gehen, dann wendet es die zweite Regel an: pass in all An diesem Punkt koenntest Du Dich selbst fragen "Geht IPF weiter zu zweiten Regel?". Wenn Du Dich mit ipfwadm oder ipfw auskennst, wirst Du das moeglicherweise nicht tun. Eine kurze Zeit spaeter wirst Du Dich wundern, dass die Pakete immer dann abgelehnt oder angenommen werden, wenn das nicht geschehen sollte. Viele Paketfilter stoppen mit dem Vergleich der Pakete, wenn eine Regel auf diese Pakete zutrifft. IPF gehoert nicht dazu. Anders als andere Paketfilter setzt IPF ein Flag, das beschreibt, ob oder ob das Paket nicht zu einer Regel passt. Solange du den Fluss nicht unterbrichst, geht IPF durch den gesamten Regelsatz, um eine Entscheidung zu faellen, ob das Paket hereindarf oder in der letzten Regel verworfen werden soll. Die Szenerie: IPFilter ist aktiv. Es nimmt einen Teil der CPU- Zeit fuer sich in Anspruch. Es hat ein Checkpoint- Clipboard, das dieses hier liest: block in all pass in all -4- Ein Paket kommt in das Interface und es ist Zeit, an die Arbeit zu gehen. Es legt einen Blick auf das Paket und auf die erste Regel: block in all "Soweit denke ich, ich sollte das Paket blockieren" sagt IPF. Dann wendet es seinen Blick der zweiten Regel zu: pass in all "Soweit denke ich, ich sollte das Paket passieren lassen" sagt IPF. Es legt einen Blick auf Regel Nummer drei. Es gibt aber keine dritte Regel. Also tut es das, was seine letzte Entscheidung war: Das Paket darf die Firewall passieren. Jetzt ist die Zeit guenstig, herauszufinden, was passiert, wenn der Regelsatz so aussehen wuerde: block in all block in all block in all block in all pass in all Das Paket duerfte immer noch passieren. Es gibt keinen Gesamteffekt. Die letzte Regel hat immer Vorrang. 2.3. Die Ausfuehrung der Regeln kontrollieren: Wenn Du Erfahrung mit anderen Paketfiltern hast, kann es sein, dass Du dieses Layout als etwas konfus empfindest. Du koenntest darueber spekulieren, dass Probleme mit der Austauschbarkeit mit anderen Filtern und der Geschwindigkeit der Ueberpruefung, ob eine Regel passt, auftreten koennten. Stelle Dir vor, Du hast 100 Regeln und die wichtigsten sind die ersten zehn. Das gibt einen fuerchterlichen Overhead, weil jedes Paket jedes Mal alle 100 Regeln passieren muss. Gluecklicherweise gibt es aber ein einfaches Schluesselwort, das in jede Regel eingesetzt werden kann, um bei einem Paket eine Aktion hervorzurufen. Dieses Schluesselwort heisst quick. Das hier ist eine modifizierte Kopie vom Original- Regelsatz, die das "quick"- Schluesselwort nutzt: block in quick all pass in all In diesem Fall betrachtet sich IPF die erste Regel: block in quick all Das Paket passt und die Suche ist vorbei. Das Paket ist geraeuschlos verworfen worden. Es gibt keine Notizen, keine Logeintraege, keine feierliche Beerdigung. Kuchen wird uebrigens auch nicht serviert. -5- Und was ist nun mit der naechsten Regel? pass in all Diese Regel wird nie abgearbeitet werden. Man kann in der Konfigurationsdatei schlicht und ergreifend auf sie verzichten. Das alles hinwegfegende Match aller Pakete und das terminierende Schluesselwort "quick" aus der vorhergehenden Regel macht klar, dass nach ihr keine weiteren Regeln folgen werden. Die Haelfte einer Konfigurationsdatei zu verschwenden, ist nur selten eine gute Idee. Auf der anderen Seite ist da IPF, um Pakete zu blockieren; und es leistet gute Dienste, wenn es richtig konfiguriert ist. Nicht zuletzt ist es auch dazu da, einige Pakete durchzulassen. Mit einer Änderung des Regelsatzes ist das moeglich, wenn das gewuenscht wird. 2.4. Einfaches Filtern nach IP- Adressen IPF kann nach vielen Regeln filtern. Eine davon ist es, festzulegen, dass in bestimmten Bloecken des Adressraumes kein Verkehr stattfinden soll. Ein solcher Block ist der aus den nicht routebaren Netzwerken 192.168.0.0/16 (/16 ist die CIDR- Notation fuer eine Netzmaske). Es kann sein, dass Du mit dem Dezimalformat besser vertraut bist: 255.255.0.0 . IPF akzeptiert beide Formate). Wenn Du diesen Bereich blockieren willst, ist dies hier ein Weg: block in quick from 192.168.0.0/16 to any pass in all Jetzt haben wir einen weniger strengen Regelsatz, der derzeit etwas fuer uns tut. Die erste Regel wird geprueft: block in quick from 192.168.0.0/16 to any Das Paket kommt von 1.2.3.4, nicht von 192.168.*.*; es gibt hier kein Match. Die zweite Regel wird geprueft: pass in all Das Paket von 1.2.3.4 ist eindeutig ein Paket von all; das Paket wird gesendet, was auch immer sein Ziel ist und dort mit ihm passiert. Auf der anderen Seite haben wir vermutlich ein Paket, das von 192.168.1.2 kommt. Die erste Regel wird geprueft: block in quick from 192.168.0.0/16 to any Hier ist ein Match. Das Paket wird verworfen und das ist das bittere Ende. Nochmal: Es geht nicht durch die zweite Regel, weil die erste Regel ein Match war und sie das "quick"- Schluesselwort enthielt. -6- An diesem Punkt kannst Du einen ziemlich auschweifenden Satz von Regeln aufsetzen, der festlegt, was die Firewall passieren darf oder nicht. Seit wir begonnen haben, private Adressen zu blockieren, sollten wir auch den anderen Bereichen die noetige Beachtung schenken: block in quick from 192.168.0.0/16 to any block in quick from 172.16.0.0/12 to any block in quick from 10.0.0.0/8 to any pass in all Die ersten drei Regeln blockieren einiges aus den privaten Adressraeumen. 2.5. Interfaces kontrollieren Es kommt oefter vor, dass Firmen schon ein internes Netzwerk besitzen, bevor sie eine Verbindung mit der Welt "draussen" einrichten wollen. Genauer gesagt: Es ist moeglicherweise der Hauptgrund fuer die Einrichtung einer Firewall auf dem "ersten Rechner am Netz". Die Maschine, die die Bruecke von der Welt "draussen" zur Welt "drinnen" darstellt, ist der Router. Was den Router von anderen Maschinen unterscheidet, ist einfach: Er hat mehr als ein Netzwerkinterface. Jedes Paket, das Du empfaengst und jedes Paket, das Deinen Rechner verlaesst, geht durch so ein Interface. Sagen wir mal, Deine Maschine hat drei Interfaces: lo0 (loopback), x10 (3com- ethernet) und tun0 (FreeBSD- spezifischer generischer Tunnel; das Interface, das ppp benutzt); aber Du willst nicht, dass irgendwelche Pakete ueber das tun0 Interface hereinkommen? Das sieht so aus: block in quick on tun0 all pass in all In diesem Fall bedeutet das "on"- Schluesselwort, dass ein Datenpaket ueber das genannte Interface hereinkommt. Wenn es ueber tun0 kommt, blockiert die erste Regel das Paket. Wenn es ueber lo0 oder x10 kommt, passt die erste Regel nicht. Die zweite Regel passt allerdings und das Paket darf die Firewall passieren. 2.6. Die Benutzung von IP- Adressen mit den Interfaces Es ist schon ein etwas sonderbarer Zustand, wenn sich jemand entscheidet, das tun0- Interface zu aktivieren, ohne das irgendwelche Daten dieses Interface passieren duerfen. Eine weitere Eigenschaft einer Firewall ist die, dass sie mit einer zunehmenden Anzahl an Regeln entweder fester oder lockerer werden kann. Das ist der Startpunkt fuer eine effektive Firewall. block in quick on tun0 from 192.168.0.0/16 to any ----------- Anmerkung: Siehe auch rfc1918 auf http://www.faqs.org/rfcs/rfc1918.html und http://www.ietf.org/internet-drafts/draft-man- ning-dsua-03.txt -7- pass in all Vergleiche dies mit der vorherigen Regel: block in quick from 192.168.0.0/16 to any pass in all Der alte Weg, allen Verkehr von 192.168.0.0/16 ohne Beachtung eines Interfaces zu blockieren, war der einer vollstaendigen Blockade. Auf dem neuen Weg, ueber tun0, wird das Paket nur blockiert, wenn es ueber tun0 hereinkommt. Wenn ein Paket ueber das x10- Interface ankommt, darf es herein. Auch an diesem Punkt kannst Du einen ziemlich ausschweifenden Regelsatz definieren, die entweder durchlaesst oder blockiert Schon seit wir damit begonnen haben, private Adressraeume ueber tun0 zu blockieren, sollten wir dem Rest der Regeln etwas Beachtung zukommen lassen. block in quick on tun0 from 192.168.0.0/16 to any block in quick on tun0 from 172.16.0.0/12 to any block in quick on tun0 from 10.0.0.0/8 to any block in quick on tun0 from 127.0.0.0/8 to any block in quick on tun0 from 0.0.0.0/8 to any block in quick on tun0 from 169.254.0.0/16 to any block in quick on tun0 from 192.0.2.0/24 to any block in quick on tun0 from 204.152.64.0/23 to any block in quick on tun0 from 224.0.0.0/3 to any pass in all Du hast schon die ersten drei Bloecke gesehen, aber nicht den Rest. Die vierte Regel ist ein ausgedehntes Class-A- Netzwerk, das fuer den Loopback gebraucht wird. Es gibt viel Software, die mit sich selbst auf 127.0.0.1 kommuniziert. Demnach ist es eine gute Idee, Eingaenge von externen Quellen zu blockieren. Die Fuenfte, "0.0.0.0 /8" sollte niemals im Internet auftauchen. Viele IP- Stacks sehen "0.0.0.0/32" als den Default- Gateway an. Und der Rest des "0.0.0.0"- Netzwerks wird von verschiedenen Systemen als ein Nebenprodukt aus den Routing- Entscheidungen betrachtet. Du solltest 0.0.0.0/8 genau so betrachten wie 127.0.0.0/8. 169.254.0.0/16 wurde von der IANA fuer die Auto- Konfiguration von Rechnern reserviert, die noch nicht in der Lage sind, eine IP- Adresse via DHCP oder Ähnlichem zu beziehen. Microsoft Windows wird Adressen in diesem Bereich nutzen, wenn es auf DHCP eingestellt ist und keinen Server findet. 192.0.2.0/24 ist zum Gebrauch als beispielhafter Netzwerkblock fuer Autoren von Dokumentationen ebenfalls reserviert. Wir benutzen diese spezifizierten Bereiche nicht, weil das Konfusionen verursachen wuerde. Darum kommen alle unsere Beispiele von 20.20.20.0/25. 204.152.64.0/23 ist ein merkwuerdiger Netzblock, der von Sun Microsystems fuer private Cluster- Interconnects reserviert wurde. Ob Du diese Adressen blockierst, musst Du selbst entscheiden. Als Letztes gibt es da noch 224.0.0.0/3, die den Bereich der Klassen D und E abdecken und meistens fuer Multicast- Verkehr genutzt werden, obwohl ein "Class E"- Adressraum in RFC1166 beschrieben ist. -8- Es gibt da einen wichtigen Grundsatz im Paketfiltern, der besagt, dass Pakete, die eigentlich nur aus einem privaten Netz kommen koennen, zu blockieren sind: Wenn Du weisst, dass bestimmte Arten von Daten nur von einer bestimmten Stelle kommen koennen, dann wird das System so konfiguriert, dass diese Art von Daten nur von diesem Platz kommen kann. Im Fall der unroutebaren Adressen weisst Du, dass von 10.0.0.0/8 nichts auf dem Interface tun0 ankommen darf, weil es keinen Weg gibt, solche Anfragen zu beantworten. Es ist also ein illegitimes Paket. Das Gleiche gilt auch fuer die anderen unroutebaren Adressen wie 127.0.0.0/8. Viele Teile von Software erledigen ihre gesamte Authentifizierung auf der Basis der Herkunftsadresse des Paktets. Wenn Du ein internes Netzwerk betreibst, sagen wir 20.20.20.0/24, weisst Du, dass der Verkehr nur aus dem lokalen Ethernet kommen kann. Sollte ein Paket ueber einen ppp- Dialup hereinkommen, hast Du einen wichtigen Grund, das Paket fallen zu lassen oder es in einem dunklen Raum zu verhoeren. Es sollte aus keinem anderen Grund die Firewall zu seinem Ziel passieren duerfen. Du kannst das sehr einfach erreichen, wenn du etwas ueber IPF weisst. Der neue Regelsatz sieht jetzt so aus: block in quick on tun0 from 192.168.0.0/16 to any block in quick on tun0 from 172.16.0.0/12 to any block in quick on tun0 from 10.0.0.0/8 to any block in quick on tun0 from 127.0.0.0/8 to any block in quick on tun0 from 0.0.0.0/8 to any block in quick on tun0 from 169.254.0.0/16 to any block in quick on tun0 from 192.0.2.0/24 to any block in quick on tun0 from 204.152.64.0/23 to any block in quick on tun0 from 224.0.0.0/3 to any block in quick on tun0 from 20.20.20.0/24 to any pass in all 2.7. Bidirektionales Filtern; das "out" Schluesselwort Bis hierher haben wir nur den eingehenden oder ausgehenden Verkehr durchgelassen oder blockiert. Um Klarheit zu schaffen: Eingehender Verkehr ist alles, was ueber irgendein Interface in die Firewall hereinkommt. Ausgehender Verkehr ist genau das Gegenteil davon: Er verlaesst die Firewall ueber irgendein Interface. Das heisst auch, dass nicht nur der Verkehr gefiltert wird, der ueber die Firewall hereinkommt, sondern auch der Verkehr, der hinausgeht. Bis hierher haben wir eingehenden Verkehr entweder durchgelassen oder blockiert. Um zu klaeren, was damit gemeint ist, wiederhole ich das hier noch mal: Eingehender Verkehr sind alle Daten, die die Firewall ueber irgendein Interface in den Rechner hinein passieren; egal, welcher Art diese Pakete sind. Im Gegensatz dazu steht der ausgehende Verkehr: Dieser verlaesst der Rechner; egal ueber welches Interface (Hierbei ist es egal, ob dieser Verkehr nur weitergeleitet wird oder vom Host selbst ausgeht.). Das bedeutet, dass alle Pakete nicht nur gefiltert weden, wenn sie hereinkommen, sondern auch, wenn sie den Rechner verlassen. Bisher war das nur ein implementierter Ausgang von allen Paketen, wobei es nicht entscheidend war, ob diese Pakete die Firewall verlassen durften oder auch nicht. Genauso wie eingehender Verkehr blockiert werden kann, kann man das auch mit dem ausgehenden Verkehr machen. Jetz wissen wir, dass es einen Weg gibt, den ausgehenden Verkehr genauso zu filtern wie den eingehenden. Wir sind jetzt so weit, dass wir uns an die Arbeit machen koennen, einen Weg zu finden, um genau dieses zu tun. Eine Moeglichkeit, diese Funktion zu nutzen ist, zu verhindern, dass gespoofte (und fuer Angreifer interessante) Pakete das eigene Netzwerk verlassen koennen. Anstatt den gesamten Verkehr nach aussen durch den Router zu lassen, kann der ausgehende Verkehr auf Pakete von 20.20.20.0/24 limitiert werden. Das kannst Du so machen: -9- pass out quick on tun0 from 20.20.20.0/24 to any block out quick on tun0 from any to any Wenn ein Paket von 20.20.20.1/32 kommt, wird es nach der ersten Regel gesendet. Wenn das Paket von 1.2.3.4/32 kommt, wird es von der zweiten Regel blockiert. Du kannst aehnliche Regeln fuer die unroutebaren Adressen festlegen. Wenn einige Maschinen versuchen sollten, ein Paket durch IPF mit dem Ziel 192.168.0.0/16 zu routen, warum blockierst Du das nicht? Das Schlimmste, das passieren kann, ist, dass Du etwas Bandbreite einbuesst: block out quick on tun0 from any to 192.168.0.0/16 block out quick on tun0 from any to 172.16.0.0/12 block out quick on tun0 from any to 10.0.0.0/8 block out quick on tun0 from any to 0.0.0.0/8 block out quick on tun0 from any to 127.0.0.0/8 block out quick on tun0 from any to 169.254.0.0/16 block out quick on tun0 from any to 192.0.2.0/24 block out quick on tun0 from any to 204.152.64.0/23 block out quick on tun0 from any to 224.0.0.0/3 block out quick on tun0 from !20.20.20.0/24 to any Auf den ersten Blick verbessert das Deine Sicherheit nicht. Aber es verbessert die Sicherheit von vielen anderen. Es ist daher eine gute Idee, das zu machen. Als anderen Gesichtspunkt kann man das unterstuetzen, um so zu verhindern, dass niemand gespoofte Pakete aus Deinem Netzwerk versenden kann, dass Deine Site nicht als Relay fuer solche Angriffe verwendet werden kann und als solcher auch kein Ziel darstellen kann. Du wirst noch eine gewisse Anzahl von Anwendungen fuer das Blockieren von ausgehenden Paketen finden. Eines sollte man dabei noch im Gedaechtnis behalten: Dass alle ein- und ausgehenden Richtungen immer in Relation zur Firewall stehen, niemals aber zu anderen Maschinen. 2.8. Das Geschehen protokollieren; das "log"- Schluesselwort Bis zu diesem Punkt wurden alle blockierten oder freigegebenen Pakete entweder stillschweigend blockiert oder ebenso stillschweigend durchgelassen. Im Normalfall willst Du aber wissen, ob Du angegriffen wurdest, anstatt ziemlich verwundert darueber zu sein, wenn die Firewall auf einmal irgendwelche Sachen einkauft. Waehrend ich nicht alle Pakete aufzeichnen will, die die Firewall passieren, wuerde ich gerne mehr ueber die blockierten Pakete von 20.20.20.0/24 wissen. Um das zu tun, ergaenzen wir die Regel um das "log"- Schluesselwort. block in quick on tun0 from 192.168.0.0/16 to any ----------- Das kann natuerlich mit der Benutzung von -DIPFILTER_DEFAULT_BLOCK bei der Compilation von ipfilter auf Deinem System geaendert werden -10- block in quick on tun0 from 172.16.0.0/12 to any block in quick on tun0 from 10.0.0.0/8 to any block in quick on tun0 from 127.0.0.0/8 to any block in quick on tun0 from 0.0.0.0/8 to any block in quick on tun0 from 169.254.0.0/16 to any block in quick on tun0 from 192.0.2.0/24 to any block in quick on tun0 from 204.152.64.0/23 to any block in quick on tun0 from 224.0.0.0/3 to any block in log quick on tun0 from 20.20.20.0/24 to any pass in all So weit ist unsere Firewall schon mal ganz gut geruestet, um Pakete von suspekten Orten zu blockieren. Auf der einen Seite akzeptieren wir ausgehende Pakete, die nach ueberall hingehen sollen. Eine Arbeit, die wir uns noch machen sollten, ist, sicher zu gehen, dass Pakete nach 20.20.20.0/32 und 20.20.20.255/32 verworfen werden. Das anders zu machen, oeffnet das interne Netz fuer eine Smurf- Attacke. Diese beiden Zeilen schuetzen das hypothetische Netzwerk vor dem Missbrauch als Smurf- Relay. block in log quick on tun0 from any to 20.20.20.0/32 block in log quick on tun0 from any to 20.20.20.255/32 Das laesst unseren Regelsatz in etwa so aussehen: block in quick on tun0 from 192.168.0.0/16 to any block in quick on tun0 from 172.16.0.0/12 to any block in quick on tun0 from 10.0.0.0/8 to any block in quick on tun0 from 127.0.0.0/8 to any block in quick on tun0 from 0.0.0.0/8 to any block in quick on tun0 from 169.254.0.0/16 to any block in quick on tun0 from 192.0.2.0/24 to any block in quick on tun0 from 204.152.64.0/23 to any block in quick on tun0 from 224.0.0.0/3 to any block in log quick on tun0 from 20.20.20.0/24 to any block in log quick on tun0 from any to 20.20.20.0/32 block in log quick on tun0 from any to 20.20.20.255/32 pass in all 2.9. Komplettes bidirektionales Filtern an den Interfaces Bisher haben wir nur Fragmente eines kompletten Regelsatzes gesehen. Wenn Du Deinen eigenen Regelsatz kreierst, musst Du Regeln fuer jede Richtung und jedes Interface festlegen. Der Defaultstatus von ipfilter ist es, alles durchzulassen. Es ist, als ob es eine unsichtbare Regel gibt, die alle Pakete, also alle ein- und ausgehenden durchlaesst. Anstatt sich auf irgendein Standardverhalten zu verlassen, sollte alles so spezifisch wie moeglich gemacht werden; Interface fuer Interface, bis alles verpackt ist. Wir starten zuerst mit dem lo0- Interface, das wild und frei laufen will. Seit es Programme gibt, die mit anderen auf dem System kommunizieren, gehe einfach weiter und lasse es offen: -11- pass out quick on lo0 pass in quick on lo0 Das Naechste ist das x10- Interface. Wir beginnen spaeter damit, Regeln fuer dieses Interface festzulegen. Fuer den Moment gehen wir davon aus, dass alles aus Deinem lokalen Netz vertrauenswuerdig ist und lassen es genau so laufen wie lo0. pass out quick on xl0 pass in quick on xl0 Zum Schluss ist da noch das tun0- Interface, das wir bis jetzt nur zur Haelfte filtern: block out quick on tun0 from any to 192.168.0.0/16 block out quick on tun0 from any to 172.16.0.0/12 block out quick on tun0 from any to 127.0.0.0/8 block out quick on tun0 from any to 10.0.0.0/8 block out quick on tun0 from any to 0.0.0.0/8 block out quick on tun0 from any to 169.254.0.0/16 block out quick on tun0 from any to 192.0.2.0/24 block out quick on tun0 from any to 204.152.64.0/23 block out quick on tun0 from any to 224.0.0.0/3 pass out quick on tun0 from 20.20.20.0/24 to any block out quick on tun0 from any to any block in quick on tun0 from 192.168.0.0/16 to any block in quick on tun0 from 172.16.0.0/12 to any block in quick on tun0 from 10.0.0.0/8 to any block in quick on tun0 from 127.0.0.0/8 to any block in quick on tun0 from 0.0.0.0/8 to any block in quick on tun0 from 169.254.0.0/16 to any block in quick on tun0 from 192.0.2.0/24 to any block in quick on tun0 from 204.152.64.0/23 to any block in quick on tun0 from 224.0.0.0/3 to any block in log quick on tun0 from 20.20.20.0/24 to any block in log quick on tun0 from any to 20.20.20.0/32 block in log quick on tun0 from any to 20.20.20.255/32 pass in all Das ist schon eine signifikante Menge an Regeln, um 20.20.20.0/24 von Spoofing- Angriffen oder der Nutzung als Relay fuer solche Angriffe zu schuetzen. Kuenftige Beispiele werden weiterhin diese Einseitigkeit zeigen, aber behalte im Gedaechtnis, dass wir das um der Kuerze willen so machen. Wenn Du Deinen eigenen Regelsatz aufsetzen willst, ergaenze das bitte um Regeln fuer jedes Interface und jede Richtung, sofern das noetig ist. 2.10. Die Kontrolle von bestimmten Protokollen; Das "proto"- Schluesselwort Denial-of-Service- Angriffe grassieren genauso im Internet wie Buffer- Overflow- Angriffe. Viele Denial-of-Service- Angriffe verlassen sich auf Fehler im TCP/IP- Stack verschiedener Betriebssysteme. Manchmal kommen sie auch als ICMP- Pakete. Warum sollte man sowas nicht gleich ganz blockieren? -12- block in log quick on tun0 proto icmp from any to any Jetzt wird jeder eingehende ICMP- Verkehr aufgezeichnet und anschliessend verworfen. 2.11. ICMP Filtern mit dem "icmp-type"- Schluesselwort; Regelsaetze Natuerlich ist das Fallenlassen von allen ICMP- Paketen nicht die Idealloesung. Warum eigentlich nicht? Nun, es ist sinnvoll, das partiell zu erlauben. Es koennte sein, dass Du manchen ICMP- Verkehr behalten willst und andere Arten verworfen werden sollen. Wenn Du pingen und tracerouten willst, brauchst Du die ICMP- Typen 10 und 11. Im Klartext: Das MUSS keine gute Idee sein, aber Du musst zwischen Sicherheit und Komfort abwaegen. IPF hilft Dir dabei: pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0 pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11 Denke dran, dass die Reihenfolge des Regelsatzes wichtig ist. Seit wir alles "quick" machen, muessen wir unsere "passes" vor die "blocks" setzen. Ergo setzen wir die letzten drei Regeln in dieser Reihenfolge: pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0 pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11 block in log quick on tun0 proto icmp from any to any Das Anhaengen dieser drei Regeln an die Anti- Spoofing- Regeln ist etwas haarig. Ein Fehler koennte es sein, die neuen ICMP- Regeln an den Anfang zu setzen. pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0 pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11 block in log quick on tun0 proto icmp from any to any block in quick on tun0 from 192.168.0.0/16 to any block in quick on tun0 from 172.16.0.0/12 to any block in quick on tun0 from 10.0.0.0/8 to any block in quick on tun0 from 127.0.0.0/8 to any block in quick on tun0 from 0.0.0.0/8 to any block in quick on tun0 from 169.254.0.0/16 to any block in quick on tun0 from 192.0.2.0/24 to any block in quick on tun0 from 204.152.64.0/23 to any block in quick on tun0 from 224.0.0.0/3 to any block in log quick on tun0 from 20.20.20.0/24 to any block in log quick on tun0 from any to 20.20.20.0/32 block in log quick on tun0 from any to 20.20.20.255/32 pass in all Das Problem dabei ist, dass ein ICMP- Paket des Typs 0 von 192.168.0.0/16 die erste Regel passieren wird und von der vierten Regel niemals blockiert wird. Also: Seit wir ICMP ECHO_REPLYS passieren lassen oeffnen wir uns eine Hintertuer fuer diese ekligen Smurf- Angriffe. -13- Also erklaeren wir die letzten zwei Blockaderegeln fuer nichtig. Um dem aus dem Wege zu gehen, setzen wir die ICMP- Regeln hinter die Anti- Spoofing- Regeln. block in quick on tun0 from 192.168.0.0/16 to any block in quick on tun0 from 172.16.0.0/12 to any block in quick on tun0 from 10.0.0.0/8 to any block in quick on tun0 from 127.0.0.0/8 to any block in quick on tun0 from 0.0.0.0/8 to any block in quick on tun0 from 169.254.0.0/16 to any block in quick on tun0 from 192.0.2.0/24 to any block in quick on tun0 from 204.152.64.0/23 to any block in quick on tun0 from 224.0.0.0/3 to any block in log quick on tun0 from 20.20.20.0/24 to any block in log quick on tun0 from any to 20.20.20.0/32 block in log quick on tun0 from any to 20.20.20.255/32 pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0 pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11 block in log quick on tun0 proto icmp from any to any pass in all Weil wir gespooften Verkehr blockieren, bevor die ICMP- Regeln ausgefuehrt werden, schafft es ein gespooftes Paket niemals bis zum ICMP- Regelsatz. Es ist sehr wichtig, solche Situationen im Hinterkopf zu behalten, wenn man Regeln miteinander verschmilzt. 2.12. TCP und UDP Ports; Das "port"- Schluesselwort Jetzt haben wir damit begonnen, die Pakete auf ihren Protokollen basierend abzublocken. Wir koennen die Pakete nach spezifischen Aspekten fuer jedes Protokoll abblocken. Der am meisten genutzte Aspekt ist die Portnummer. Services wie rsh, rlogin und telnet sind sehr bequem, wenn man sie installiert hat, aber sie verbergen auch gewisse Unsicherheiten gegen Network- Sniffing- und Spoofing- Angriffe. Ein moeglicher Kompromiss ist es, diese Dienste nur intern laufen zu lassen und sie nach aussen hin zu blockieren. Das ist einfach zu machen, weil diese Dienste immer auf definierten TCP- Ports laufen. Als solches ist das Schaffen von Regeln, mit denen sie blockiert werden koennen, einfach. block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 513 block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 514 block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 23 Stelle sicher, dass alle drei vor dem Pass in All stehen. Dann sind sie fuer die Aussenseite dicht. pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 0 pass in quick on tun0 proto icmp from any to 20.20.20.0/24 icmp-type 11 block in log quick on tun0 proto icmp from any to any block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 513 block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 514 -14- block in log quick on tun0 proto tcp from any to 20.20.20.0/24 port = 23 pass in all Du kannst ausserdem 514/udp (syslog), 111/tcp und 111/udp (portmap), 515/tcp (lpd), 2049/tcp und 2049/udp (NFS), 6000/tcp (X11) undsoweiter und so fort blockieren. Eine komplette Liste mit den Ports bekommst Du mit netstat -a (oder lsof -i, wenn das installiert ist). Wenn anstelle des TCP- Protokolls UDP- Pakete blockiert werden sollen, braucht man das "proto tcp"- Kommando nur durch "proto udp" zu ersetzen. Die Regel fuer Syslog sieht dann so aus: block in log quick on tun0 proto udp from any to 20.20.20.0/24 port = 514 IPF bietet ausserdem einen schnellen Weg, um Regeln zu schreiben, die TCP und UDP gleichzeitig blockieren. Portmap und NFS benutzen beide Protokolle. Die Regel fuer Portmap sieht so aus: block in log quick on tun0 proto tcp/udp from any to 20.20.20.0/24 port = 111 3. Advanced Firewalling Introduction (Anmerkung des Uebersetzers: Das sollte besser in Englisch bleiben) Dieses Kapitel wurde als eine Art "Follow- up" zur Basissektion geschrieben. Der Text unten beinhaltet sowohl Konzepte fuer ein erweitertes Firewall- Design als auch erweiterte Funktionen, die nur IPFilter in dieser Form bietet. Wenn Du einmal komfortabel mit dieser Sektion bist, solltest Du in der Lage sein, eine wirklich gute Firewall zu bauen. 3.1. Die wuchernde Paranoia; oder die "Default- Deny- Einstellung" Es kann zu einem grosse Problem auswachsen, Dienste nach Ports zu blockieren, weil sie sich manchmal veraendern. RPC- basierte Programme (lockd, statd, nfs) sind schrecklich gut darin; besonders NFS horcht gerne auch an anderen Ports als 2049. Es ist wirklich schwierig, etwas vorauszusagen und es ist noch viel schwieriger, diese Einstellungen immer automatisch zu korrigieren. Was ist, wenn Du einen Dienst vermisst? Statt mit dieser ganzen Hirselei zu dealen, lass uns noch mal mit einer sauberen Konfiguration neu starten. Der derzeitige Regelsatz sieht so aus: Jaja, wir starten wirklich noch einmal neu. Die erste Regel, die wir nutzen, ist diese: block in all Kein Netzwerkverkehr geht durch. Keiner. Nicht ein Piep. Du bist wirklich sicher mit dieser Einstellung. Das ist nicht wirklich zu gebrauchen, aber eben auch absolut sicher. Die eigentlich grosse Sache in dieser Angelegentheit ist, dass es allerdings nicht viel mehr braucht, um Deine Kiste sowohl sicher als auch benutzbar zu machen. -15- Sagen wir der Maschine, dass auf ihr ein Webserver laeuft; nicht mehr, aber auch nicht weniger. Sie macht keine DNS- Lookups. Sie will nur Verbindungen ueber Port 80/tcp aufnehmen und das war's dann. Wir koennen das so machen. Und zwar mit einer zweiten Regel; Du weisst schon wie: block in on tun0 all pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 80 Diese Maschine laesst allen Traffic fuer 20.20.20.1 auf Port 80 durch. Fuer eine einfache Firewall reicht das. 3.2. Bedingungsloses "Allow"; die "keep state"(Status halten)- Regel Der Job Deiner Firewall ist es, unerwuenschten Traffic von Punkt A nach Punkt B zu unterbinden. Wir haben allgemeingueltige Regeln, die dem Computer sagen "So lange dieses Paket fuer Port 23 ist, ist das in Ordnung." Wir haben allgemeine Regeln, die sagen "Solange dieses Paket den FIN- Flag gesetzt hat, ist das in Ordnung." Unsere Firewall kennen den Anfang, den Mittelteil oder das Ende einer TCP/UDP/ICMP- Sitzung nicht. Sie besitzt nur vage Regeln, die fuer alle Pakete angewendet werden. Wir gehen in der Hoffnung, dass das Paket mit einem gesetzten FIN- Flag auch wirklich ein FIN- Scan ist, der zu unseren Diensten passt. Wir hoffen, dass das Paket an Port 23 kein unerwuenschter "Tramper" in unserer Telnet- Sitzung ist. Was ist aber, wenn da ein Weg ist, individuelle TCP/UDP/ICMP- Sitzungen zu identifizieren und zu autorisieren oder sie von Portscannern oder Denial-of-Service- Attacken erkannt werden koennen? Es gibt da einen Weg. Er wird "keeping state" genannt. Wir wollen Komfort und Sicherheit auf einmal. Viele Leute wollen das. Das ist auch der Grund, warum Cisco eine "established"- Klausel hat, die "etablierte" oder besser, erwuenschte TCP- Sitzungen zulaesst. IPFW hat diese Funktion. IPFWADM hat Setup/established. Sie alle haben dieses Feature, aber der Name ist oft irrefuehrend. Als wir das zu ersten Mal sahen, dachten wir, dass unserem Paketfilter bewusst war, was da passiert, dass er wusste, ob eine Verbindung wirklich "established" war oder eben nicht. Fakt ist, dass sie alle das "Wort" dafuer aus einem Teil des Paketes entnehmen, in dem jeder luegen kann. Sie lesen die Flag-Sektion des TCP- Paketes. Das ist der Grund, warum UDP/ICMP damit nicht funktioniert. Diese Pakete haben das schlicht nicht. Jeder der ein Paket mit "Bogus"- Flag erzeugen kann, kann mit diesem Setup von einer Firewall akzeptiert werden. Wo kommt IPF denn nun ins Spiel, fragst Du Dich? Nun, im Gegensatz zu anderen Firewalls kann IPF herausfinden, ob ein Paket "established" ist oder eben nicht. Und es macht das mit TCP, UDP und ICMP, nicht nur mit TCP. Bei IPF heisst das "keeping state", also Status oder Zustand halten. Das Schluesselwort dafuer ist "keep state". Bis jetzt redeten wir nur ueber Pakete, die hereinkommen; dann wir der Regelsatz geprueft; Pakete gehen raus; der Regelsatz wird geprueft. Derzeit passiert mit den Paketen dieses hier: Pakete kommen herein und werden vielleicht geprueft. Pakete verlassen den Rechner und werden vielleicht geprueft. Was also derzeit passiert, ist, dass die Pakete entweder nach dem Regelsatz fuer eingehende oder nach dem Regelsatz fuer ausgehende Pakete geprueft werden. -16- Die Statustabelle ist eine Liste von TCP/UDP/ICMP- Sitzungen, die ungefragt die Firewall passieren duerfen, eingeschraenkt durch den gesamten Regelsatz. Das klingt fuer Dich nach einem ernsthaften Sicherheitsloch? Bleib dran; es ist das Beste, was Deiner Firewall passieren kann. Alle TCP/IP- Sitzungen sehen aus wie ein Schulaufatz: Es gibt einen Anfang, einen Hauptteil und ein Ende (besonders, wenn sich alles im selben Paket befindet). Du kannst keinen Hauptteil ohne einen Anfang haben und kein Ende ohne Hauptteil. Das bedeutet, dass alles, was Du wirklich filtern musst, sich eigentlich auf den Anfang der TCP/UDP/ICMP- Sitzung beschraenkt. Wenn der Anfang einer Sitzung von Deiner Firewall zugelassen wird, willst Du wirklich auch den Hauptteil und das Ende davon (Dein IP- Stack sollte aber nicht ueberflutet werden, damit der Rechner nicht unbrachbar wird). Den Status zu halten, erlaubt es Dir, die Pakete in der Mitte einer Sitzung und an ihrem Ende zu ignorieren und einfach nur neue Sitzungen zu blockieren oder durchzulassen. Wenn die neue Sitzung die Firewall passieren durfte, werden alle dazugehoerigen Pakete ebenfalls durchgelassen. Wenn diese Sitzung blockiert wurde, werden auch alle nachfolgenden Pakete dieser Sitzung nicht durchgelassen. Hier ist ein Beispiel fuer einen SSL- Server (und nichts anderes als ein SSL- Server): block out quick on tun0 all pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 22 keep state Das Erste, was Du Dir merken solltest, dass es keine "pass- out"- Vorkehrung gibt. Abgesehen davon, ist der Regelsatz komplett. Weil wir den Status halten, wird der gesamte Regelsatz nicht noch einmal abgefragt. Wenn das erste Syn- Paket den SSH- Server erreicht hat, wird der Status erstellt. Die Sitzung behaelt diesen, ohne dass sich die Firewall einmischt. Hier ist ein anderes Beispiel: block in quick on tun0 all pass out quick on tun0 proto tcp from 20.20.20.1/32 to any keep state In diesem Fall laufen auf dem Server keine Dienste. In Wirklichkeit ist das kein Server, sondern ein Client. Und dieser Client will nicht, dass unautorisierte Pakete in den IP- Stack der Maschine eindringen. Aber der Client will trotzdem vollen Zugriff auf das Internet und die Antwortpakete, die solche Privilegien enthalten. Dieser einfache Regelsatz erstellt Statuseintragungen fuer jede neue ausgehende TCP- Sitzung. Zu Wiederholung: Wenn ein Statuseintrag stattgefunden hat, ist es den neuen TCP- Sessions freigestellt, vor- und zurueck zu "reden" wie sie es wuenschen, und zwar ohne Behinderung oder Kontrolle durch den Regelsatz der Firewall. Wir weisen nochmals darauf hin, dass das gleichermassen fuer UDP und ICMP gilt: block in quick on tun0 all pass out quick on tun0 proto tcp from 20.20.20.1/32 to any keep state pass out quick on tun0 proto udp from 20.20.20.1/32 to any keep state pass out quick on tun0 proto icmp from 20.20.20.1/32 to any keep state -17- Jou, Ostfriesland; wir koennen pingen. Nun koennen wir "keep state" fuer TCP, UDP und ICMP durchfuehren. Jetzt koennen wir ausgehende Verbindungen genauso herstellen, als ob es keine Firewall gaebe. Und Moechtegern- Hacker koennen sich nicht in das System einklinken. Das ist sehr praktisch, weil es keinen Bedarf gibt, aufzuzeichnen, auf welchen Ports gehorcht wird. Nur auf die Ports, die wir freigeben, kann von anderen Leuten zugegriffen werden. State ist schoen praktisch, aber auch etwas kitzlig. Du kannst Dir damit selbst auf mysterioesen und befremdlichen Wegen auch selbst in den Fuss schiessen. Vergleiche mal den folgendenen Regelsatz: pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 pass out quick on tun0 proto tcp from any to any keep state block in quick all block out quick all Auf der ersten Blick scheint das eine gute Konfiguration zu sein. Wir erlauben eingehende Sitzungen an Port 23 und ausgehende Sitzungen nach ueberall. Natuerlich werden Pakete, die nach Port 23 gehen, ein Antwortpaket bekommen. Aber ein Regelsatz, der so aufgesetzt wird, erzeugt einen Zustandseintrag und alles wird richtig funktionieren. Das ist das Wenigste, denkst Du. Die unsaegliche Wahrheit ist, dass nach 60 Sekunden Idletime der Eintrag geschlossen wird (Im Gegensatz zu den ueblichen fuenf Tagen). Das liegt daran, dass der "State-Tracker" niemals das Original-SYN- Paket sieht; es sieht nur das SYN-ACK. IPF kann TCP- Sitzungen von Anfang bis Ende sehr gut verfolgen, aber ist nicht so gut darin, in die Mitte der Sitzung zu kommen. Also musst Du Deine Regel so aendern wie unten beschrieben: pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 keep state pass out quick on tun0 proto tcp from any to any keep state block in quick all block out quick all Der Zusatz zu dieser Regel traegt das allererste Paket in die Zustandstabelle ein; und alles wird funktionieren wie gedacht. Wenn der 3-Wege-Handshake einmal von der "Zustandsmaschine" (state-engine) bezeugt wurde, ist er im 4/4- Modus markiert; was bedeutet, dass seine Einstellungen fuer einen langfristigen Datenaustausch gelten, bis die Verbindung beendet wird (Wobei der Modus sich nochmals aendert. Man kann das mit ipfstat -s abfragen, was natuerlich fuer die gesamte Zustandstabelle gilt). 3.3. Zustaende mit UDP Fuer UDP gibt es solche Zustaende nicht; es ist natuerlich etwas schwerer, zuverlaessig einen Zustand zu definieren und diesen zu halten. Abgesehen davon leistet ipf auch hier gute Dienste. Wenn Maschine A mit Quellport X ein UDP- Paket an Maschine B mit Zielport Y schickt, wird ipf eine Antwort von Maschine B, Port Y an Maschine A, zulassen. Das ist ein Kurzzeitzustand, der nur 60 Sekunden besteht. -18- Hier ist ein Beispiel fuer das, was passiert, wenn wir einen nslookup ausfuehren, um herauszufinden, welche IP- Adresse die Firma 3com hat: $ nslookup www.3com.com Ein DNS- Paket wird erzeugt: 17:54:25.499852 20.20.20.1.2111 > 198.41.0.5.53: 51979 Das Paket kommt von 20.20.20.1, Port 2111; als Ziel ist 198.41.0.5, Port 53 angegeben. Ein einminuetiger Statuseintrag wird erzeugt. Wenn das Paket von 198.41.0.5, Port 53, mit dem Ziel 20.20.20.1, Port 2111 zurueckkommt, wird das Antwortpaket die Firewall passieren. Wie Du hier sehen kannst, geschieht das bereits Millisekunden spaeter: 17:54:25.501209 198.41.0.5.53 > 20.20.20.1.2111: 51979 q: www.3com.com Das Antwortpaket passt auf die Statuskriterien und wird durchgelassen. Im gleichen Moment, in dem das Paket durchgelassen wurde, wird dieser Weg wieder verschlossen. Neue eingehende Pakete duerfen die Firewall nicht mehr passieren; auch und besonders, wenn sie vorgeben, vom selben Platz zu stammen. 3.4. ICMP mit Status IPFilter behandelt ICMP- Zustaende in der Weise, in der jemand versteht, wie ICMP mit TCP und UDP benutzt wird und wie das "Keep State"- Feature funktioniert. Es gibt zwei grundsaetzliche Arten von ICMP- Nachrichten: Anfragen und Antworten. Wenn Du eine Regel schreibst wie diese hier: pass out on tun0 proto icmp from any to any icmp-type 8 keep state um Echo Requests (ein typischer Ping) zu erlauben, wird das resultierende ICMP-Typ 0- Paket zugelassen werden. Dieser Statuseintrag besitzt einen Default- Timeout eines unvollstaendigen 0/0- Status von 60 Sekunden. Das bedeutet: Wenn Du den Status irgendwelcher icmp- Pakete herausfinden willst, brauchst Du ein ICMP- Protokoll [...] und eine "keep state"- Regel. Trotzdem, die haeufigste Anwendung von ICMP- Nachrichten sind Statusinformationen, die von einigen Fehlern im UDP- Protokoll (Manchmal auch in TCP) und in 3.4x und neueren IPFiltern erzeugt werden (Beispiel: icmp-Typ 3 Code 3 "port unreachable" oder auch ein "time exceeded"), die fuer einen aktiven Statuseintrag passen. Es kann aber auch sein, dass ein aktiver Statuseintrag diese Meldung generiert hat. Beispiel: Wenn Du einen aelteren IPFilter benutzt, musst Du fuer Traceroute folgendes eintragen: pass out on tun0 proto udp from any to any port 33434><33690 keep state pass in on tun0 proto icmp from any to any icmp-type timex Du kannst jetzt die richtigen Dinge tun und den Status fuer UDP so halten: -19- pass out on tun0 proto udp from any to any port 33434><33690 keep state Um einen gewissen Schutz gegen das Einschleichen von fremden ICMP- Paketen in einer aktiven Verbindung zu erreichen, wird das Paket nicht nur auf Herkunft und Ziel geprueft (nebst der Ports, sofern gefragt), wofuer ein kleiner Teil des Paketes beansprucht wird. 3.5. FIN Scan Detection; "flags" Schluesselwort, "keep frags" Schluesselwort Lasst uns mal zurueckgehen zum Vierer- Regelsatz aus dem vorherigen Kapitel: pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 keep state pass out quick on tun0 proto tcp from any to any keep state block in quick all block out quick all Das ist meistens, aber nicht insgesamt, zufriedenstellend. Das Problem dabei ist, dass nicht nur SYN- Pakete, die das duerfen, an Port 23 gehen, sondern dass jedes aeltere Paket durchkommen kann. Wir koennen das mit der "flags"- Option abstellen: pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 flags S keep state pass out quick on tun0 proto tcp from any to any flags S keep state block in quick all block out quick all Jetzt werden nur TCP- Pakete, die an 20.20.20.1, Port 23, mit einem einzelnen SYN- Flag hereingelassen und in die Statustabelle eingetragen. Ein einzelner SYN- Flag ist nur im allerersten Paket vorhanden (der sog. TCP- Handshake); und das ist es, was wir eigentlich wollen. Diese Sache hat zwei Vorteile: Kein unerwuenschtes Paket kann hereinkommen und die Statustabelle durcheinanderbringen. Gleichzeitig werden FIN- und XMAS- Scans scheitern, wenn sie andere Flags setzen als das SYN- Flag. Nun muessen alle Pakete einen Handshake durchfuehren oder bereits einen Status in der Tabelle besitzen. Wenn moeglicherweise etwas anderes hereinkommt, ist es vielleicht ein Portscan oder ein "geschmiedetes" (gefaehrliches) Paket. Eine Ausnahme gibt es allerdings: Ein eingehendes Paket, das auf seiner Reise fragmentiert wurde. ----------- Einige Beispiele benutzen dis S/SA- Flags anstelle von S. S- Flags sind zur Zeit mit den S/AUPFRS- Flags gleichzusetzen und weisen nur das SYN- Paket von allen sechs gueltigen Flags ab; wobei S/SA- Flags Pakete erlaubt, die das URG-, PSH-, FIN- oder RST- Flag gesetzt haben oder auch nicht. Einige Protokolle verlangen das URG- oder PSH- Flag, so dass S/SAFR die bessere Wahl fuer diese sein sollte. Allerdings wissen wir, dass es weniger sicher ist, S/SA- Flags zu benutzen, wenn das nicht verlangt wird. Aber es ist Deine Firewall... -20- IPF bietet auch hier etwas an, das "keep frags"- Schluesselwort. Damit wird IPF fragmentierte Pakete bemerken und die Spur dieser Pakete halten, indem es die erwarteten Fragmente durchlaesst. Wir schreiben die drei Regeln, mit denen wir die "geschmiedeten" Pakete aufzeichnen und fragmentierte Pakete zulassen: pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 23 flags S keep state keep frags pass out quick on tun0 proto tcp from any to any keep state flags S keep frags block in log quick all block out log quick all Das funktioniert, weil jedes Paket, das durchgelassen werden soll, seine Weg durch die Statustabelle macht, bevor die Blockierregeln erreicht werden. Wenn Du wirklich darueber besorgt bist, kannst Du besonders die initiativen SYN- Pakete aufzeichnen. 3.6. Ein blockiertes Paket beantworten Bis jetzt haben wir alle abgelehnten Pakete auf den Boden fallen lassen; Protokolliert oder auch nicht. Wir haben nie etwas an den Absender zurueckgeschickt. Manchmal ist das aber nicht das beste Verfahren. Wir erzaehlen einem Angreifer naemlich, dass da ein Paketfilter seinen Dienst versieht. Es scheint weitaus besser zu sein, dass man den Angreifer so irrefuehrt, dass dieser glaubt, dass ein Paketfilter seinen Dienst tut, obwohl gar keiner da ist. Das ist genauso, als wenn keine Dienste vorhanden sind, durch die man einbrechen kann. Das ist der Bereich, in dem das Vorspiegeln einer Firewall ins Spiel kommt. Wenn ein Service auf einem Unixsystem nicht laeuft, laesst das System den anderen Host das normalerweise mit einigen Arten von Return- Paketen wissen. In TCP wird das mit einem RST (Reset)- Paket gemacht. Wenn ein TCP- Paket blockiert wird, kann IPF zur Zeit ein RST an den Absender schicken, indem es das "return-rst"- Schluesselwort verwendet. Wo wir zuerst das getan haben: block in log on tun0 proto tcp from any to 20.20.20.0/24 port = 23 pass in all ...sollten wir jetzt dies hier machen: block return-rst in log from any to 20.20.20.0/24 proto tcp port = 23 block in log quick on tun0 pass in all Wir brauchen zwei "Block"- Statements, seit Return-RST nur mit TCP funktioniert und wir wollen Protokolle wie TCP, ICMP und andere abblocken. Das ist jetzt getan. Die andere Seite bekommt jetzt ein "Connection refused" anstelle eines "connection timed out" Es ist genauso moeglich, eine Fehlermeldung zu senden, wenn jemand ein UDP- Paket an Dein System schickt. Wobei Du dieses hier benutzten solltest: block in log quick on tun0 proto udp from any to 20.20.20.0/24 port = 111 -21- Du kannst stattdessen das "return-icmp"- Schluesselwort verwenden, um eine Antwort zu schicken: block return-icmp(port-unr) in log quick on tun0 proto udp from any to 20.20.20.0/24 port = 111 Dem illustren TCP/IP entsprechend ist "port-unreachable" die korrekte ICMP- Antwort, wenn kein Dienst auf dem abgefragten Port auf Anfragen wartet. Du kannst jeden ICMP- Typen benutzen, den Du magst, aber "port-unreachable" ist vermutlich die beste Wahl. Es ist auch der Standard- ICMP- Typ fuer "Return-icmp". Aber: Wenn Du "return-icmp" verwendest, sollte Dir bewusst sein, dass das nicht gerade unsichtbar ist. Es schickt das ICMP- Paket mit der Adresse der Firewall zurueck, nicht etwa mit der IP- Adresse des eigentlichen Ziels. Das wurde in ipfilter 3.3 abgestellt. Ausserdem wurde ein neues Schluesselwort, "return-icmp-as-dest", hinzugefuegt. Das neue Format ist das hier: block return-icmp-as-dest(port-unr) in log on tun0 proto udp from any to 20.20.20.0/24 port = 111 3.7. Beliebte Logging- Techniken Es ist wichtig zu wissen, dass das Vorhandensein des "log"- Schluesselwortes nur sicherstellt, dass das Paket fuer das Logging- device (/dev/ipl) verfuegbar ist. Um diese Log- Information sehen zu koennen, muss das Ipmon- Utility laufen (oder ein anderes, dass von /dev/ipl lesen kann). Typischerweise wird Log in Verbindung mit "ipmon -s" verwendet, um die Informationen an Syslog weiterzureichen. Seit Ipfilter-3.3 kann eine Regel das Aufzeichnungsverhalten von Syslog durch die Nutzung des "log level"- Schluesselwortes geregelt werden. Beispielsweise in Regeln wie dieser: block in log level auth.info quick on tun0 from 20.20.20.0/24 to any block in log level auth.alert quick on tun0 proto tcp from any to 20.20.20.0/24 port = 21 Zusaetzlich kannst Du Dir zurechtstricken, welche Informationen aufgezeichnet werden sollen. Beispiel: Es koennte sein, dass Du nicht daran interessiert bist, dass jemand Deinen Telnet- Port 500mal testet; aber Du wirst durchaus daran interessiert sein, wenn es jemand geschafft hat, Dich oder Dein System zu untersuchen. Du kannst das "log first"- Schluesselwort benutzen, um nur das erste Exemplar eines Paketsatzes aufzuzeichnen. Natuerlich trifft diese Idee nur auf Pakete einer bestimmten Sitzung zu. Und fuer das typische abgelehnte Paket wirst Du unter den Druck geraten, eine Situation nachzuvollziehen, wo dieses Paket tut, was Du erwartest. Dennoch, wenn das in Zusammenarbeit mit "pass" und "keep state" benutzt wird, kann das ein wertvolles Schluesselwort sein, um bestimmte Tabellen im Verkehr zu behalten. Eine andere nuetzliche Sache, die Du damit machen kannst, ist es, interessante Teile eines Paketes zusaetzlich zu den Header- Informationen aufzuzeichnen, die normalerweise aufgezeichnet werden. IPFilter gibt Dir die ersten 128 Bytes des Paketes, wenn Du das "body"- Schluesselwort benutzst. -22- Du solltest den Gebrauch des "body- Logging" aber beschraenken, weil es die Logdaten sehr ausfuehrlich und umfangreich macht. Aber fuer bestimmte Applikationen ist es oft von Nutzen, wenn man in der Lage ist, zurueckzugehen und einen Blick auf das Paket zu werfen oder diese Daten an eine andere Anwendung zu schicken, die die Sachen weiterprueft. 3.8. Der Zusammenbau So, jetzt haben wir eine schoene feste Firewall. Aber sie kann noch fester werden. Einiges aus dem originalen Regelsatz das wir weggewischt haben, ist zu Zeit immer noch sehr brauchbar. Ich denke, man sollte das Anti- Spoofing- Zeugs wieder einbauen. Das sieht dann so aus: block in on tun0 block in quick on tun0 from 192.168.0.0/16 to any block in quick on tun0 from 172.16.0.0/12 to any block in quick on tun0 from 10.0.0.0/8 to any block in quick on tun0 from 127.0.0.0/8 to any block in quick on tun0 from 0.0.0.0/8 to any block in quick on tun0 from 169.254.0.0/16 to any block in quick on tun0 from 192.0.2.0/24 to any block in quick on tun0 from 204.152.64.0/23 to any block in quick on tun0 from 224.0.0.0/3 to any block in log quick on tun0 from 20.20.20.0/24 to any block in log quick on tun0 from any to 20.20.20.0/32 block in log quick on tun0 from any to 20.20.20.255/32 pass out quick on tun0 proto tcp/udp from 20.20.20.1/32 to any keep state pass out quick on tun0 proto icmp from 20.20.20.1/32 to any keep state pass in quick on tun0 proto tcp from any to 20.20.20.1/32 port = 80 flags S keep state 3.9. Leistungssteigerung durch Regelgruppen Lass uns die Moeglichkeiten unserer Firewall erweitern, indem wir sie viel komplizierter machen; und hoffen, dass sie eher dem wirklichen Leben entgegenkommt. In diesem Beispiel aendern wir die Interface- Namen und die Netzwerknummern. Lass uns annehmen, wir haben drei Interfaces in unserer Firewall, x10, x11 und x12. xl0 ist mit unserem externen Netzwerk verbunden: 20.20.20.0/26 x11 ist mit unserer DMZ verbunden, Netzwerk 20.20.20.64/26 x12 ist mit unserem geschuetzten Netz verbunden: 20.20.20.128/25 Wir werden den gesamten Regelsatz in einem Rutsch definieren, seit wir wissen, dass Du diese Regeln jetzt lesen kannst: block in quick on xl0 from 192.168.0.0/16 to any block in quick on xl0 from 172.16.0.0/12 to any block in quick on xl0 from 10.0.0.0/8 to any block in quick on xl0 from 127.0.0.0/8 to any block in quick on xl0 from 0.0.0.0/8 to any block in quick on xl0 from 169.254.0.0/16 to any block in quick on xl0 from 192.0.2.0/24 to any block in quick on xl0 from 204.152.64.0/23 to any block in quick on xl0 from 224.0.0.0/3 to any -23- block in log quick on xl0 from 20.20.20.0/24 to any block in log quick on xl0 from any to 20.20.20.0/32 block in log quick on xl0 from any to 20.20.20.63/32 block in log quick on xl0 from any to 20.20.20.64/32 block in log quick on xl0 from any to 20.20.20.127/32 block in log quick on xl0 from any to 20.20.20.128/32 block in log quick on xl0 from any to 20.20.20.255/32 pass out on xl0 all pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 80 flags S keep state pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 21 flags S keep state pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 20 flags S keep state pass out quick on xl1 proto tcp from any to 20.20.20.65/32 port = 53 flags S keep state pass out quick on xl1 proto udp from any to 20.20.20.65/32 port = 53 keep state pass out quick on xl1 proto tcp from any to 20.20.20.66/32 port = 53 flags S keep state pass out quick on xl1 proto udp from any to 20.20.20.66/32 port = 53 keep state block out on xl1 all pass in quick on xl1 proto tcp/udp from 20.20.20.64/26 to any keep state block out on xl2 all pass in quick on xl2 proto tcp/udp from 20.20.20.128/25 to any keep state Von diesem eigensinnigen Beispiel ausgehend, sehen wir, dass unser Regelsatz weniger einflussreich geworden ist. Um die Situation nicht noch weiter zu verschlechtern, indem wir besondere Regeln fuer unsere DMZ hinzufuegen, ergaenzen wir unsere Firewall durch weiter Tests fuer jedes Paket, das die Performance der x10 <--> x12- Verbindungen beeinflusst. Wenn du eine Firewall mit einem Regelsatz wie diesem aufsetztst und Du eine Menge Bandbreite mit hinreichender CPU- Leistung hast, wird jeder, der eine Workstation im x12- Netzwerk hat, nach Deinem Kopf suchen, um ihn auf einem Tablett zu praesentieren. Also: Halte Dein Torso <--> Gehirn- Netz in Ordnung. Du kannst Die Sachen beschleunigen, wenn Du Regelgruppen einrichtest. Regelgruppen erlauben es, statt einer linearen Liste, den Regelsatz in einer Baumstruktur zu schreiben. Das bedeutet, dass Dein Paket, wenn es mit den Tests nichts zu tun hat (alle x11- Regeln beispielsweise), diese Regeln nicht konsultieren wird. Es ist sowas wie mehrere Firewalls, die alle auf derselben Maschine laufen. Hier ist ein einfaches Beispiel: block out quick on xl1 all head 10 pass out quick proto tcp from any to 20.20.20.64/26 port = 80 flags S keep state group 10 block out on xl2 all In diesem simplifizierten Beispiel koennen wir einen kleinen Hinweis auf die Leistung der Regelgruppe erkennen. Wenn das Paket nicht an x11 gerichtet ist, wird der Kopf der Regelgruppe 10 nicht zutreffen und das System wird mit den Tests fortfahren. Wenn das Paket nicht fuer x11 passt, wird das "quick"- Schluesselwort alles weitere im Root- Level (regelgruppe 0) ausfuehren und seine Tests auf die Regeln, die der Gruppe 10 angehoeren; genaugenommen den SYS- Check fuer Port 80/tcp. Auf diesem Weg koennen wir die Regeln oben neu schreiben, damit wir die Performance unserer Firewall maximieren koennen. -24- block in quick on xl0 all head 1 block in quick on xl0 from 192.168.0.0/16 to any group 1 block in quick on xl0 from 172.16.0.0/12 to any group 1 block in quick on xl0 from 10.0.0.0/8 to any group 1 block in quick on xl0 from 127.0.0.0/8 to any group 1 block in quick on xl0 from 0.0.0.0/8 to any group 1 block in quick on xl0 from 169.254.0.0/16 to any group 1 block in quick on xl0 from 192.0.2.0/24 to any group 1 block in quick on xl0 from 204.152.64.0/23 to any group 1 block in quick on xl0 from 224.0.0.0/3 to any group 1 block in log quick on xl0 from 20.20.20.0/24 to any group 1 block in log quick on xl0 from any to 20.20.20.0/32 group 1 block in log quick on xl0 from any to 20.20.20.63/32 group 1 block in log quick on xl0 from any to 20.20.20.64/32 group 1 block in log quick on xl0 from any to 20.20.20.127/32 group 1 block in log quick on xl0 from any to 20.20.20.128/32 group 1 block in log quick on xl0 from any to 20.20.20.255/32 group 1 pass in on xl0 all group 1 pass out on xl0 all block out quick on xl1 all head 10 pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 80 flags S keep state group 10 pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 21 flags S keep state group 10 pass out quick on xl1 proto tcp from any to 20.20.20.64/26 port = 20 flags S keep state group 10 pass out quick on xl1 proto tcp from any to 20.20.20.65/32 port = 53 flags S keep state group 10 pass out quick on xl1 proto udp from any to 20.20.20.65/32 port = 53 keep state group 10 pass out quick on xl1 proto tcp from any to 20.20.20.66/32 port = 53 flags S keep state pass out quick on xl1 proto udp from any to 20.20.20.66/32 port = 53 keep state group 10 pass in quick on xl1 proto tcp/udp from 20.20.20.64/26 to any keep state block out on xl2 all pass in quick on xl2 proto tcp/udp from 20.20.20.128/25 to any keep state Jetzt koennen wir die Regelgruppen in Aktion bewundern. Fuer einen Host auf dem x12- Netzwerk koennen wir auf alle Checks fuer Gruppe 10 verzichten, wenn wir nicht mit den Hosts aus diesem Netzwerk kommunizieren. Situationsabhaengig kann es auch sinnvoll sein, die Regel nach Protokollen, verschiedenen Maschinen, Netzwerkbloecken oder was auch immer den Datenfluss verbessert, zu ordnen. 3.10. "Fastroute"; Das Stichwort fuer Heimlichkeit Gerade wenn wir einige Pakete weiterleiten und andere blockieren, benehmen wir uns, wie es ein wohlerzogener Router tut, der die TTL eines Paketes reduziert und der ganzen Welt mitteilt, dass hier ein Hop ist. Aber wir koennen unsere Praesenz vor inquisitorischen Programmen wie Traceroute, das UDP- Pakete mit verschiedenen TTL- Werten nutzt, um die Hops zwischen zwei Sites zu protokollieren, schuetzen. -25- Wenn wir wollen, dass eingehende traceroutes funktionieren, aber wir die Gegenwart unserer Firewall nicht als Hop bekanntmachen wollen, koennen wir das mit einer Regel wie dieser hier tun: block in quick on xl0 fastroute proto udp from any to any port 33434 >< 33465 Das Vorhandensein des Fastroute- Schluesselworts wird das Paket nicht fuer ein Routing durch den IP- Stack lassen, wenn daraus eine Reduzierung der TTL resultiert. Das Paket wird von IPFilter auf das Output- Interface geschickt, so dass eine solche Reduzierung nicht stattfinden wird. IPFilter wird natuerlich die Routing- Tabelle des Systems verwenden, um herauszufinden, welches das richtige Output- Interface ist; aber es wird vorsichtig damit sein, selbst zu routen. Das ist auch ein Grund, aus dem wir "block quick" in unserem Beispiel benutzen. Haetten wir "pass" benutzt und IP- Forwarding in unserem Kernel zugelassen, wuerden wir damit abenden, dass wir zwei Pfade fuer ein Paket haetten, ueber die dieses Paket kommen kann; und wuerden unseren Kernel moeglicherweise in Panik versetzen. Es sollte im Gedaechtnis bleiben, dass die meisten Unix- Kernels ueber einen weitaus effizienteren Routing- Code verfuegen als IPFilter. Dieses Schluesselwort sollte nicht als ein Weg zur Steigerung der Firewallperformance verwendet werden. Und es sollte nur an Stellen verwendet werden, wo diese Heimlichkeit eine Bedingung ist. 4. NAT und Proxies Ausserhalb der Firmenumgebung ist eine der groessten Verlockungen der Firewalltechnologie die Moeglichkeit fuer den Enduser, mehrere Rechner durch ein gemeinsames externes Interface an das Internet anzustoepseln. Oftmals passiert das ohne Erlaubnis, Wissen oder Zustimmung des Service- Providers. Fuer alle, die Linux kennen: Diese Konzept wird IP- Masquerading genannt, aber der Rest der Welt kennt das als Network Adress Translation, oder kurz NAT. 4.1. Viele Adressen in eine umsetzen Anmerkung fuer pedantische Leute: Was IPFilter anbietet, wird wirklich NPAT genannt, kurz fuer "Network and Port Translation"; was heisst, dass wir die Quell- und Zieladressen nebest deren Quell- und Zielports aendern koennen. Wirkliches NAT erlaubt nur das Aendern der Adressen. -26- Die Standardanwendung von NAT ist ziemlich das Gleiche wie Linuxens IP- Masquerading. Und es wird nur eine Regel dafuer gebraucht: map tun0 192.168.1.0/24 -> 20.20.20.1/32 Sehr einfach: Wann immer ein Paket mit der CIDR- Netzmaske 192.168.1.0/24 durch das tun0- Interface geht, wird das Paket in den IP- Stack zurueckgeschrieben, so das seine Quelladresse 20.20.20.1 ist und es wird an sein Originalziel geschickt. Das System pflegt ausserdem eine Liste, in der steht, welche uebersetzten Adressen in Arbeit sind, damit wir die Antwort zurueck an den internen Host leiten koennen, der das Paket generiert hat (und an 20.20.20.1 gerichtet ist). Da ist aber ein Nachteil in der gerade geschriebenen Regel. In vielen Faellen wissen wir die IP- Adresse unserer Verbindung nach draussen nicht (Wenn wir tun0 und einen typischen ISP benutzen). Das macht das Aufsetzen unserer NAT- Tabellen zu einer schwierigen Aufgabe. Gluecklicherweise ist NAT so klug, dass es eine Adresse Namens 0/32 als ein Singnal akzeptiert, nachzuschauen, welche Adresse das Interface wirklich hat. Wir meussen unsere Regel nur so umschreiben: map tun0 192.168.1.0/24 -> 0/32 Jetzt koennen wir unsere IPNAT- Regeln ungestraft laden und uns mit der Aussenwelt verbinden, ohne irgendetwas editieren zu muessen. Du musst "ipf -y" aufrufen, um die Adresse neu zu laden, wenn Deine Vebindung abgebrochen wurde und Dich neu einwaehlen, wenn Deine DHCP- Adresse sich geaendert hat. Einige Leute werden sich wundern, was mit dem Quellport passiert, wenn das Paket gemappt wird. Mit unserer gegenwaertigen Regel ist der Quellport des Pakets der Gleiche wie der Original- Quellport. Es gibt aber besondere Faelle, in denen wir dieses Verhalten nicht wollen. Das kann sich um eine andere Firewall handeln, durch die unser Upstream gehen muss oder vielleicht um viele Hosts, die den selben Port benutzen, was eine Kollision verursachen kann, wenn das Paket nicht passt und das Paket unuebersetzt das System verlaesst. Ipnat unterstuetzt uns hier mit dem "portmap"- Schluesselwort: map tun0 192.168.1.0/24 -> 0/32 portmap tcp/udp 20000:30000 Unsere Regel schuhloeffelt alle uebersetzten Verbindungen (das kann tcp, udp oder tcp/udp sein) in die Ports von 20,000 bis 30,000. ----------- Das ist ein typischer privater Adressraum. Seit dieser nicht ins Internet geroutet werden kann, wird er oft fuer interne Netze benutzt. Du solltest diese Pakete immer sperren, besonders wenn sie von aussen kommen, wie frueher schon beschrieben. -27- 4.2. Viele Adressen in einen Adressenpool mappen Eine andere allgemeine Nutzung von NAT ist es, einen kleinen statischen Adressblock zu nehmen und viele Computer in diesen kleinen Adressraum zu mappen. Das ist einfach zu realisieren, wenn Du das nutzt, was Du ueber die "map"- und "portmap"- Schluesselworte weisst und eine Regel schreibst, die aussieht wie diese hier: map tun0 192.168.0.0/16 -> 20.20.20.0/24 portmap tcp/udp 20000:60000 Es gibt auch Faelle, in denen eine Remote- Applikation vorraussetzt, dass multiple Verbindumgen immer von derselben IP- Adresse kommen. Wir koennen das unterstuetzen, indem wir in solchen Faellen NAT erzaehlen, dass es bestimmte Sitzungen von einem Host im Adressenpool statisch mappen und bei der Portauswahl zaubern soll. Das geht mit dem "map-block"- Schluesselwort wie folgt: map-block tun0 192.168.1.0/24 -> 20.20.20.0/24 4.3. Eins-zu-eins Mappings Manchmal ist es entscheidend, ein System mit einer IP- Adresse hinter der Firewall zu betreiben, das der Oeffentlichkeit eine voellig andere Adresse zeigt. Ein Beispiel ist ein Labor aus Computern, die zu verschiedenen Netzwerken gehoeren und alle mit einem bestimmten Versuch laufen sollen. In diesem Beispiel musst Du das gesamte Labornetz nicht umkonfigurieren, wenn Du ein NAT- System an der "Front" austetzen kannst und die Adressen einfach nur an einer Stelle wechselst. Wir koennen das bidirektionale Mapping mit dem "bimap"- Schluesselwort machen. Bimap bietet ein paar zusaetzliche Schutzfunktionen, um einen bekannten Zustand fuer eine Verbindung abzusichern, wenn das "map"- Schluesselwort benutzt wird, um eine Quelladresse nebst Port zu lokalisieren, um das Paket umzuschreiben und die Verbindung am Leben zu halten. bimap tun0 192.168.1.1/32 -> 20.20.20.1/32 ... erledigt das Mapping fuer einen Host. 4.4. Spoofing- Dienste Spoofing- Dienste? Was hat das mit alledem zu tun? Viel. Stellen wir uns vor, wir haben auf Maschine 20.20.20.5 einen Webserver laufen und unsere Zweifel hinsichtlich der Sicherheit unseres Netzwerkes wachsen. Wir wollen den Server nicht mehr auf Port 80 laufen lassen, weil dieser Prozess auf Port 80 eine gewisse Lebensspanne als Root voraussetzt. Aber wie sollen wir das auf einem weniger privilegierten Port wie 8000 in der Welt der Dot-Coms laufen lassen? Wir wird man unseren Server finden? Wir koennen wir die Umleitungsfunktion von NAT nutzen, um dieses Problem zu loesen. Indem wir die Verbindungen, die fuer 20.20.20.5:80 besimmt sind, auf 20.20.20.5:8000 umleiten. Fuer diese Funktion benutzen wir das "rdr"- Schluesselwort: rdr tun0 20.20.20.5/32 port 80 -> 192.168.0.5 port 8000 -28- Wir koennen hier auch das Protokoll spezifizieren, wenn wir einen anstelle eines TCP- einen UDP- Dienst umleiten wollen (Default ist TCP). Beispiel: Wir haben einen Honigtopf auf unserer Firewall, um das populaere Back Orifice fuer Windows nachzuahmen. Wir koennen den gesamten Netzwerkverkehr auf diesen einen Platz mit einer einzigen einfachen Regel umschaufeln: rdr tun0 20.20.20.0/24 port 31337 -> 127.0.0.1 port 31337 udp Ein extrem wichtiger Punkt muss bei "rdr" beachtet werden: Man kann das nicht einfach als Reflektor benutzen. Beispiel: rdr tun0 20.20.20.5/32 port 80 -> 20.20.20.6 port 80 tcp ...wird in einer Situation, in der sich .5 und .6 im selben LAN-Segment befinden, nicht funktionieren. Dir "rdr"- Funktion wird nur an Pakete angehaengt, die die Firewall ueber ein bestimmtes Interface betreten. Wenn ein Paket kommt, fuer das eine "rdr"-Regel passt, wird es zum Filtern nach IPF umgeleitet; sollte es den Satz an Filterregeln erfolgreich durchlaufen, wird es an den Unix- Routingcode geschickt. So lange dieses Paket immer noch an dasselbe Interface gebunden ist und das System nicht verlassen kann, um einen Host zu erreichen, wird das System durcheinandergeraten. Reflektoren funktionieren einfach nicht. Nichts beschreibt die Adresse des Interfaces, auf dem das Paket eben hereingekommen ist. Behalte immer im Gedaechtnis, dass "rdr"- Ziele das System auf einem anderen Interface verassen muessen. 4.5. Transparente Proxies; Umleitungen benutzen In der Zeitspanne, in der Du eine Firewall installiert hast, koenntest Du entschieden haben, dass es sinnvoll ist, einen Proxy- Server fuer viele Deiner ausgehenden Verbindungen zu benutzen, um die Regeln fuer das interne Netzwerk fuer einen besseren Schutz noch enger zu setzen. Es koennte aber auch sein, dass Du in eine Situation kommst, in der der NAT- Mappingprozess nicht vernuenftig gehandhabt werden kann. Das kann ebenfalls mir einem Redirection- Statement gemacht werden: rdr xl0 0.0.0.0/0 port 21 -> 127.0.0.1 port 21 Dieses Statement besagt, dass alle Pakete, die ueber das x10- Interface hereinkommen und fuer jede Ardresse (0.0.0.0/0) auf dem FTP- Port auf einen Proxy umgeleitet werden sollen, der auf dem NAT- System laeuft. ----------- Jaha. Da ist ein Weg, das zu tun. Es ist dermassen abstrus, dass ich es strikt ablehne, sowas zu verwenden. Einige faehige Leute, die diese Funktionalitaet brauchen, werden sowas wie den TIS- Plug- GW auf 127.0.0.1 umleiten. Dumme Leute werden ein Dummy- Loop Paerchen aufsetzen und zweimal ueberschreiben. Das schliesst ganz nebenbei 127.0.0.1 natuerlich mit ein. Sauber, wa (Fuer "huh" habe ich nur die niederdeutsche Uebersetzung...). -29- Dieses spezielle Beispiel von FTP- Proxying bringt ein paar Komplikaionen mit sich, wenn man das mit Web- Browsern anwendet, die nicht in der Lage sind, mit einem Proxy- Server zu kommunizieren. Es gibt da allerdings einige Patches um das TIS- FWTK fuer den NAT- Prozess einsatzfaehig zu machen, damit es fuer die automatische Weiterleitung einer Verbindung herausfinden kann, wo Du hinwillst. Es gibt mittlerweile viele Proxy- Pakete, die in einer transparenten Umgebung funktionieren. Squid, zu finden unter http://squid.nlanr.net, ist sehr gut in dieser Disziplin. Diese Anwendung der "rdr"- Schluesselwortes ist oft besser, wenn Du das automatische Authentifizieren der User mit dem Proxy vorantreiben willst (Beispiel: Deine Ingenieure sollten im Web surfen duerfen, aber Du willst nicht, dass Deine Call- Center- Agents das auch tun). 4.6. Magisch versteckt hinter NAT; Application Proxies Weil Ipnat eine Methode anbietet, nach der Pakete ueberschrieben werden, wenn sie die Firewall passieren, ist das ein bequemer Platz, um ein paar Anwendungsschichts- Proxies zu bauen, um bekannte Unterschiede zwischen typischen Firewalls und Application- Firewalls zu ueberschminken. Beispiel FTP: Wir koennen unsere Firewall so einrichten, dass sie den Paketen Beachtung schenkt, wenn sie diese passieren; und wenn sie merkt, dass sie mit einer aktiven FTP- Sitzung verhandelt, kann sie temporaere Regeln selbst schreiben, sehr aehnlich den "keep state"- Regeln. Um das zu benutzen nehmen wir eine Regel wie diese hier: map tun0 192.168.1.0/24 -> 20.20.20.1/32 proxy port ftp ftp/tcp Du musst immer beachten, dass Du diese Proxy- Regel vor die Portmap- Regeln setzt; sonst wird Portmap, wenn es an der Reihe ist und sich fuer das Paket zustaendig fuehlt, das Paket ueberschreiben. Ein Proxy wird dann keine Chance haben, mit diesem Paket zu arbeiten. Denke daran, dass "ipnat"- Regeln immer die ersten sind, die Gueltigkeit besitzen. Es gibt auch Proxies fuer "rcmd" (was wir zweifelhaft finden; Berkeley- r*- Kommandos sollten immer verboten werden, vor allem solche, von denen wir nicht wissen, was der Proxy tut, wenn sie aufgerufen werden) und "raudio" fuer die Ral- Audio- PMN- Streams. Beide Regeln dieser Art sollten vor die Portmap- Regeln gesetzt werden, wenn Du NAT verwendest. 5. Laden und Manipulieren von Filterregeln; das IPF- Utility IP- Filter- Regeln werden bei Nutzung des Programms geladen. Die Filterregeln koennen in jeder Datei im System abgelegt werden. Typischerweise werden diese Regeln aber in /usr/local/etc/ipf.rules oder /etc/opt/ipf/ipf.rules gespeichert. IP- Filter hat zei Arten von Regeln: einen aktiven und einen inaktiven Satz. Im Normalfall werden alle Operationen nach dem aktiven Regelsatz durchgefuehrt. -30- Du kannst den inaktiven Satz mit "-I" hinter der IPF- Kommandozeile manipulieren. Zwischen beiden Saetzen kann mit der "-s" Kommandozeilenoption hin- und her geschaltet werden. Das ist sehr sinnvoll, wenn man die neuen Regeln testen will, ohne den alten Regelsatz gleich zewatechnisch zu beseitigen. Die Regeln koennen auch mit der Option "-r" aus der Liste entfernt werden. Aber es ist generell besser, den benutzten Regelsatz mit der Option "-F" zu flushen und nach Aenderungen komplett neu zu laden, wenn Du was veraendert hast. Summasummarum: Der einfachste Weg, einen Regelsatz zu laden ist mit "ipf -FA -f /etc/ipf.rules. Fuer kompliziertere Aenderungen sei hier auf die ipf(1) Manpage hingewiesen. 6. Laden un Manipulieren von NAT- Regeln; Das ipnat- Utility NAT- Regeln werden bei Benutzung des ipnat- Werkzeuges geladen. Die NAT- Regeln koennen ebenfalls in jeder Datei im System untergebracht werden, aber es ist ueblich, diese in den Dateien /etc/ipnat.rules oder in /etc/opt/ipf/ipnat.rules unterzubringen. Auch diese Regeln koennen aus der Liste mit der "-r"- option in der Kommandozeile geloescht werden; aber es ist auch hier besser, den gesamten Regelsatz zu loeschen und ihn dann mit der Option "-C" komplett neu zu laden, wenn etwas geaendert wurde. Irgendwelche aktiven Mappings werden von "-C" nicht angeruehrt und koennen mit "-F" entfernt werden. NAT- Regeln und aktive Mappings koennen mit der "-I" Option geprueft werden. Der einfachste Weg ist es, die NAT- Regeln mit "ipnat -CF -f /etc/ipnat.rules" neu zu laden. 7. Monitoring und Debugging Es wird die Zeit kommen, zu der Du wissen willst, was Deine Firewall gerade tut. IPFilter waere nicht komplett, wenn es keinen vollen Satz an Status- Monitoring- Werkzeugen haette. 7.1. Das ipfstat- Utility In seiner einfachsten Form zeigt Ipfstat eine Tabelle mit interessanten Daten darueber, wie Deine Firewall arbeitet: eine Tabelle darueber, wie viele Pakete die Firewall passieren durften oder blockiert wurden, ob sie aufgezeichnet wurden oder nicht, wieviele Zustandseintraege gemacht wurden und so weiter. Hie ist ein Beispiel fuer etwas von dem, wa sdu sehen kannst, wenn Du das Tool laufen laesst: # ipfstat input packets: blocked 99286 passed 1255609 nomatch 14686 counted 0 output packets: blocked 4200 passed 1284345 nomatch 14687 counted 0 -31- input packets logged: blocked 99286 passed 0 output packets logged: blocked 0 passed 0 packets logged: input 0 output 0 log failures: input 3898 output 0 fragment state(in): kept 0 lost 0 fragment state(out): kept 0 lost 0 packet state(in): kept 169364 lost 0 packet state(out): kept 431395 lost 0 ICMP replies: 0 TCP RSTs sent: 0 Result cache hits(in): 1215208 (out): 1098963 IN Pullups succeeded: 2 failed: 0 OUT Pullups succeeded: 0 failed: 0 Fastroute successes: 0 failures: 0 TCP cksum fails(in): 0 (out): 0 Packet log flags set: (0) none ipfstat kann Dir auch Deine aktuelle Regelliste anzeigen. Mit dem "i-" oder dem "-o"- flag werden die aktuell geladenen Regeln fuer der Ein- oder Ausgang angezeigt. Ein angehaengtes "-h" bietet gleichzeitig brauchbarere Informationen, indem es einen "Hitcout" fuer jede Regel anzeigt. Beispiel: # ipfstat -ho 2451423 pass out on xl0 from any to any 354727 block out on ppp0 from any to any 430918 pass out quick on ppp0 proto tcp/udp from 20.20.20.0/24 to any keep state keep frags Daraus koennen wir ersehen, ob vielleicht etwas anormal gelaufen ist, seit wir eine Menge blockierter Pakete ausgeschlossen haben. Besonders bei einer sehr liberalen Regelung fuer den Ausgang. Einiges davon rechtfertigt ein vorangehendes Verhoer; oder es muesste ein perfektes Design besitzen. ipfstat kann Dir nicht sagen, ob Deine Regeln richtig oder falsch sind. Es kann Dir nur sagen, was aufgrund Deiner Regeln passiert ist oder passieren wird. Um Deine Regeln vorher zu debuggen, kannst Du das "-n"- Flag benutzen, das die Nummer jeder einzelnen Regel anzeigt: # ipfstat -on @1 pass out on xl0 from any to any @2 block out on ppp0 from any to any @3 pass out quick on ppp0 proto tcp/udp from 20.20.20.0/24 to any keep state keep frags Das finale Stueck einer wirklich interessanten Information, das ipfstat uns bieten kann, ist ein Dump der Zustandstabelle. Das wird mit dem "-s"-Flag gemacht: # ipfstat -s 281458 TCP 319349 UDP 0 ICMP 19780145 hits 5723648 misses -32- 0 maximum 0 no memory 1 active 319349 expired 281419 closed 100.100.100.1 -> 20.20.20.1 ttl 864000 pass 20490 pr 6 state 4/4 pkts 196 bytes 17394 987 -> 22 585538471:2213225493 16592:16500 pass in log quick keep state pkt_flags & b = 2, pkt_options & ffffffff = 0 pkt_security & ffff = 0, pkt_auth & ffff = 0 Hier sehen wir, dass wir einen Statuseintrag fuer eine TCP- Verbindung haben. Der Output variiert etwas von Version zu Version, aber die eigentliche Information ist immer dieselbe. Wir koennen in dieser Verbindung sehen, dass sie voll etabliert ist (wird durch den 4/4- Zustand angezeigt. Andere Zustaende sind unvollstaendig und werden spaeter dokumentiert.). Wir koennen sehen, dass der Statuseintrag eine Lifetime von 240 Stunden hat, was zwar eine reichlich absurde Zeitspanne ist, aber dem Standardwert einer etablierten TCP- Verbindung entspricht. Dieser TTL- Counter wird jede Sekunde heruntergezaehlt, in der dieser Statuseintrag nicht benutzt wird, was am Ende bedeutet, dass die Verbindung geloescht wird, wenn sie einige Zeit unbenutzt bleibt. Die TTL wird auch nach 864000 zurueckgesetzt, wann immer dieser Status benutzt wird; Bedingung dabei ist, dass der Eintrag waehrend seiner aktiven Benutzung nicht ungueltig wird. Wir koennen auch sehen, dass 196 Pakete mit einer Gesamtgroesse von 17KB die Firewall passieren durften. Wir koennen die Ports beider Endpunkte der Verbindung sehen (diesmal 987 und 22); was bedeutet, dass dieser Statuseintrag eine Verbindung von 100.100.100.1, Port 987 nach 20.20.20.1, Port 22 repraesentiert. Die wirklich grossen Nummern in der zweiten Zeile sind die TCP- Sequenznummern dieser Verbindung, die uns dabei helfen, dass es nicht so einfach ist, boese Pakete in diese Verbindung einzuschleusen. Das TCP- Fenster wird ebenfalls gezeigt. Die dritte Zeile ist eine genaue Darstellung der Regel, die vom "kepp state"- Code generiert wurde und anzeigt, das diese Verbindung eine Eingehende ist. 7.2. Das ipmon- Utility ipfstat ist auch gut darin, Schnappschuesse von dem einzusammeln, was gerade auf dem System passiert. Aber es ist oft praktisch, eine Art von Protokollierung zu haben, mit der man die Events beobachten kann, wenn sie gerade stattfinden. ipmon heisst das Werkzeug dafuer. ipmon kann packet log (wenn das mit dem "log"- Schluesselwort in den Regeln gefordert ist), state log oder NET- Log beobachten oder eben auch alle zusammen. Dieses Tool kann sowohl im Vordergrund laufen als auch im Hintergrund als Daemon; um die Daten an Syslog zu uebergeben oder in eine Datei zu schreiben. Wenn wir die Statustabelle in Aktion beoachten wollen, wuerde "ipmon -O -s" dieses hier ausgeben: # ipmon -o S 01/08/1999 15:58:57.836053 STATE:NEW 100.100.100.1,53 -> 20.20.20.15,53 PR udp 01/08/1999 15:58:58.030815 STATE:NEW 20.20.20.15,123 -> 128.167.1.69,123 PR udp 01/08/1999 15:59:18.032174 STATE:NEW 20.20.20.15,123 -> 128.173.14.71,123 PR udp -33- 01/08/1999 15:59:24.570107 STATE:EXPIRE 100.100.100.1,53 -> 20.20.20.15,53 PR udp Pkts 4 Bytes 356 01/08/1999 16:03:51.754867 STATE:NEW 20.20.20.13,1019 -> 100.100.100.10,22 PR tcp 01/08/1999 16:04:03.070127 STATE:EXPIRE 20.20.20.13,1019 -> 100.100.100.10,22 PR tcp Pkts 63 Bytes 4604 Hier sehen wir einen Statuseintrag fuer eine externe DNS- Abfrage aus unserem Nameserver, zwei xntp- Pings an bekannte Timeserver und eine sehr kurze ausgehende SSH- Verbindung. Ipmon kann uns ausserdem anzeigen, welche Pakete aufgezeichnet wurden. Wenn beispielsweise "state" benutzt wird, wirst Du oft auf Pakete stossen wie diese hier: # ipmon -o I 15:57:33.803147 ppp0 @0:2 b 100.100.100.103,443 -> 20.20.20.10,4923 PR tcp len 20 1488 -A Was bedeutet das? Das erste Feld ist einfach zu erkennen: Es zeigt den Zeitstempel. Fuer das zweite Feld gilt das Gleiche. Es zeigt uns das Interface, auf dem das Event stattgefunden hat. Das dritte Feld (@0:2) ist etwas, das viele Leute vermissen: Es ist die Regel, die einem Event sagt, dass er stattzufinden hat. Erinnerst Du Dich an "ipfstat -in"? Wenn Du wissen willst, wo das herkam, kannst Du Dir hier Regel 2 in Gruppe 0 heraussuchen. Das vierte Feld, das kleine "b" besagt, dass dieses Paket blockiert wurde. Generell wirst Du das ignorieren, bis Du Pakete, die passieren durften, ebenfalls protokollierst. Dann erscheint an dieser Stelle ein kleines "p". Die Felder fuenf und sechs erklaeren sich eigentlich selbst. Sie sagen aus, wo das Paket herkam und wohin es gegangen ist. Das siebte ("PR") und das achte Feld erzaehlen Dir, ueber welches Protokoll das Paket gegangen ist und Feld neun stellt die Groesse des Pakets dar. Der letzte Teil, das "-A" zeigt uns die die Flags des Pakets. Dieses was ein ACK- Paket. Warum erwaehnte ich ich die Zustaende nicht eher? Durch die oftmals etwas krude Natur des Internets werden die Pakete manchmal regeneriert. Manchmal bekommst zwei Kopien eines Pakets und Deine Zustandsregel, die die Sequenznummern in der Spur haelt, wird das Paket auch zweimal gesehen haben und davon ausgehen, dass das Paket ein Bestandteil einer anderen Verbindung ist Eventuell laeuft das Paket durch eine reale Route, die damit gedealt hat. Das letzte Paket einer geschlossenen Sitzung wird oft protokolliert weil der "keep state"- Code die Verbindung schon beendet hat, bevor das letzte Paket die Chance hatte, Deine Firewall zu passieren. Das ist normal. Du brauchst Die also keine Sorgen zu machen. Ein anderes Beispiel fuer ein Paket, das aufgezeichnet sein koennte: 12:46:12.470951 xl0 @0:1 S 20.20.20.254 -> 255.255.255.255 PR icmp len 20 9216 icmp 9/0 ----------- Fuer eine technische Praesentation von IPFilter's Inspection Engine lese bitte auch das Whitepaper "Real Stateful TCP Packet Filtering in IP Filter" von Guido van Rooij. Das Blatt kann unter gefunden werden. -34- Das hier ist ein ICMP- Router- Discovery- Broadcast. Wir koennen das mittels des ICMP- Typs 9/0 bekanntmachen. Zu guter Letzt laesst uns ipmon auch die NAT- Tabelle in Aktion begutachten: # ipmon -o N 01/08/1999 05:30:02.466114 @2 NAT:RDR 20.20.20.253,113 <- -> 20.20.20.253,113 [100.100.100.13,45816] 01/08/1999 05:30:31.990037 @2 NAT:EXPIRE 20.20.20.253,113 <- -> 20.20.20.253,113 [100.100.100.13,45816] Pkts 10 Bytes 455 Das waere eine Umleitung zu einem identd, der einem Aussenstehenden vorflunkert, einen Ident- Dienst fuer die Hosts hinter unserer NAT anzubieten, seit sie typischerweise nicht mehr in der Lage sind, sich selbst diesen Service mit der normalen NAT anzubieten. 8. Bestimmte Anwendungen der IPFilter- Sachen sollten aber auch erwaehnt werden. 8.1. Keep State mit Servern und Flags. Einen Zustand zu halten ist eine gute Sache, aber es ist ziemlich leicht, einen Fehler in der Richtung zu machen, in der Du "keep state" ausfuehren willst. Normalerweise wird ein "keep state"- Schluesselwort in der ersten Regel eines Paketes gesetzt, das mit einer Regel fuer eine Verbindung interagiert. Ein verbreiteter Fehler wird gemacht, wenn man das Halten eines Zustandes mit Filter- Flags wie diesen mischt: block in all pass in quick proto tcp from any to 20.20.20.20/32 port = 23 flags S pass out all keep state Das erscheint so, als ob Du eine Verbindung zum Telnet- Server auf 20.20.20.20 nebst der ausgehenden Antworten erlaubst. Wenn Du versuchst, diese Regel zu benutzen, wirst Du sehen, dass sie nur momentan funktioniert. Seit wir nach den SYN- Flags filtern, wird der Zustandseintrag niemals vollstaendig erstellt; und die Standard- TTL eines unvollstaendigen Zustandes ist immer 60 Sekunden. Wir koennen das problem loesen, indem wir diese Regel auf einem dieser beiden Wege neu schreiben: 1) block in all pass in quick proto tcp from any to 20.20.20.20/32 port = 23 keep state block out all oder: 2) block in all pass in quick proto tcp from any to 20.20.20.20/32 port = 23 flags S keep state pass out all keep state -35- Jeder dieser Regelsaetze wird zu einem volletabliertem Zustandseintrag fuer eine Verbindung zu Deinem Server fuehren. 8.2. Kopieren mit FTP FTP ist eines dieser Protokolle, bei denen Du Dich zuruecklehnen und die Frage stellen musst "Was zur Hoelle haben die sich dabei gedacht?". FTP hat viele Probleme, mit denen ein Systemadministrator umgehen muss. Was schlimmer ist: Die Probleme, die der Administrator finden muss unterscheiden sich zwischen dem Aufsetzen von FTP- Servern und dem von -Clients. Im FTP- Protokoll gibt es zwei Formen von Datentransfer: aktiv und passiv genannt. Aktive Transfers sind die, in denen der Server sich mit einem offenen Port am Client verbindet, um Daten zu schicken. Bei passiven Verbindungen verbindet sich der Client mit dem Server, um Daten zu empfangen. 8.2.1. Betrieb eines FTP Server Bei einem laufenden FTP- Server ist es einfach, aktive FTP- Sitzungen aufzusetzen und sie zu haendeln. Gleichzeitig ist ist das Handling von passivem FTP ein grosses Problem. Als Erstes regeln wir, wie aktives FTP zu handhaben ist. Dann machen wir das Gleiche mit der passiven Variante. Grundsaetzlich koennen wir aktive FTP- Sitzungen als eingehende HTTP- oder SMTP- Sitzung handhaben, ganz wie es gefaellt. Du musst nur den FTP- Port oeffnen und "keep state" den Rest machen lassen: pass in quick proto tcp from any to 20.20.20.20/32 port = 21 flags S keep state pass out proto tcp all keep state Diese Regeln erlauben alle aktiven FTP- Sitzungen (den gaengigsten Typ) mit dem FTP- Server auf 20.20.20.20. Die naechste Herausforderung ist das Handling von passiven FTP- Verbindungen. Webbrowser benutzen normalerweise diesen Modus. Er ist deshalb ziemlich populaer und deshalb sollte das unterstuetzt werden. Das Problem dabei ist, dass bei jeder passiven Sitzung der Server beginnt, an einem neuen Port auf Verbindungen zu warten (normalerweise oberhalb 1023). Das ist fast wie das Erschaffen eines neuen unbekannten Dienstes auf dem Server. Ausgehen davon, dass wir eine gute Firewall mit einer Default- Deny- Regel haben, wird der neue Dienst blockiert und diese aktiven FTP- Sitzungen werden abgebrochen. Aber verzweifle nicht! Es gibt noch Hoffnung. Die erste Idee eines Menschen wird es sein, einfach alle Ports oberhalb 1023 zu oeffnen. Die Wahrheit ist, dass das funktioniert: pass in quick proto tcp from any to 20.20.20.20/32 port > 1023 flags S keep state pass out proto tcp all keep state -36- Das ist natuerlich schon etwas unbefriedigend. Wenn man alles oberhalb Port 1023 hereinlaesst, oeffnen wir uns selbst fuer eine Anzahl potentieller Probleme. Waehrend der Bereich 1-1023 eigentlich fuer die Serverdienste gedacht ist, laufen bestimmte Programme (z.B. NFS oder X) auf Nummern >1023. Die gute Nachricht ist, dass Dein FTP- Server entscheiden wird, welche Ports fuer passive Sitzungen benutzt werden. Das heisst: Statt alle Ports oberhalb von 1023 zu oeffnen, kannst Du festlegen, dass nur die Ports 15001 bis 19999 fuer diesen Zweck verwendet werden sollen und nur diesen Bereich durch Deine Firewall oeffnest. In wu-ftp wird das mit der "passive ports"- Option in ftpaccess gemacht. Auf der IPFilter- Seite muessen wir nur die Regeln fuer die Korrespondenz setzen: pass in quick proto tcp from any to 20.20.20.20/32 port 15000 >< 20000 flags S keep state pass out proto tcp all keep state Wenn gerade diese Loesung Dich nicht zufriedenstellt, kannst Du den IPF- Support auch in Deinen FTP- Server hacken oder eben FTP- Server- Support in IPF mit einbauen. 8.2.2. Betrieb eines FTP Clients Waehrend der FTP- Server- Support in IPF immer noch nicht perfekt ist, funktioniert der FTP- Client- Support ab Version 3.3.3 schon ganz gut. Genau wie bei den Servern gibt es zwei Arten von FTP- Client- Transfers: Aktiv und passiv. Die einfachste Art eines Client- Transfers ist aus dem Standpunkt der Firewall der passive Transfer. Ausgehen davon, dass Deine "keep state"- Regeln alle ausgehenden TCP- Verbindungen enthalten, werden passive Transfers schon funktionieren. Wenn Du das noch nicht tust, denke bitte mal ueber folgendes nach: pass out proto tcp all keep state Der zweite Typ des Client- Transfers (aktiv) ist etwas schwieriger, aber nichts destoweniger ein geloestes Problem. Aktive Transfers fordern den Server auf, eine zweite Verbindung fuer den Datendurchfluss zurueck zum Client aufzubauen. Das ist normalerweise ein Problem, wenn sich in der Mitte eine Firewall befindet, die eingehende Verbindungen stoppt. Um das zu loesen, enthaelt IPFilter einen IPNAT- Proxy, der temporaer einen Weg nur fuer den FTP- Server die Firewall zurueck zum Client oeffnet. Sogar, wenn Du IPNAT nicht fuer NAT benutzt, ist dieser Proxy aktiv. Die folgenden Regeln sind das nackte Minimum, das in die IPNAT- Konfiguration eingebaut werden sollte (ep0 soll das Interface fuer die ausgehende Verbindung sein): map ep0 0/0 -> 0/32 proxy port 21 ftp/tcp Weitere Details fuer interne IPFilter- Proxies stehen in Kapitel 3.6. -37- 8.3. Kernel- Variablen Es gibt da einige nuetzlich Kernel- Tuneups, die entweder gesetzt werden muessen, damit IPF funktioniert oder die man einfch kennen sollte, wenn man eine Firewall bauen will. Das Wichtigste, was Du aktivieren musst, ist das IP- Forwarding. Sonst wird IPF nur sehr wenig tun. Beispielsweise werden im darunterliegenden IP- Stack keine Pakete geroutet. IP Forwarding: openbsd: net.inet.ip.forwarding=1 freebsd: net.inet.ip.forwarding=1 netbsd: net.inet.ip.forwarding=1 solaris: ndd -set /dev/ip ip_forwarding 1 Ephemeral Port Adjustment: openbsd: net.inet.ip.portfirst = 25000 freebsd: net.inet.ip.portrange.first = 25000 net.inet.ip.por- trange.last = 49151 netbsd: net.inet.ip.anonportmin = 25000 net.inet.ip.anonportmax = 49151 solaris: ndd -set /dev/tcp tcp_smallest_anon_port 25000 ndd -set /dev/tcp tcp_largest_anon_port 65535 Andere nuetzliche Werte: openbsd: net.inet.ip.sourceroute = 0 net.inet.ip.directed-broadcast = 0 -38- freebsd: net.inet.ip.sourceroute=0 net.ip.accept_sourceroute=0 netbsd: net.inet.ip.allowsrcrt=0 net.inet.ip.forwsrcrt=0 net.inet.ip.directed-broadcast=0 net.inet.ip.redirect=0 solaris: ndd -set /dev/ip ip_forward_directed_broadcasts 0 ndd -set /dev/ip ip_forward_src_routed 0 ndd -set /dev/ip ip_respond_to_echo_broadcast 0 FreeBSD hat einige zuaetzliche IPF- spezifische sysctl- Variablen: net.inet.ipf.fr_flags: 0 net.inet.ipf.fr_pass: 514 net.inet.ipf.fr_active: 0 net.inet.ipf.fr_tcpidletimeout: 864000 net.inet.ipf.fr_tcpclosewait: 60 net.inet.ipf.fr_tcplastack: 20 net.inet.ipf.fr_tcptimeout: 120 net.inet.ipf.fr_tcpclosed: 1 net.inet.ipf.fr_udptimeout: 120 net.inet.ipf.fr_icmptimeout: 120 net.inet.ipf.fr_defnatage: 1200 net.inet.ipf.fr_ipfrttl: 120 net.inet.ipf.ipl_unreach: 13 net.inet.ipf.ipl_inited: 1 net.inet.ipf.fr_authsize: 32 net.inet.ipf.fr_authused: 0 net.inet.ipf.fr_defaultauthage: 600 9. Spass mit ipf! Dieses Kapitel zeigt Dir nichts notwendigerweise irgendwas Neues ueber IPF; aber es bringt unter Umstaenden ein paar Dinge zur Sprache, ueber die Du vielleicht bisher noch nicht nachgedacht hast. Es koennte auch passieren, dass es Deine Hirnwindungen in eine Dankrichtung fuehrt, aus der heraus Du etwas neues entdeckst, ueber das wir bisher noch nicht nachgedacht haben. 9.1. Localhost filtern Vor langer Zeit in einer weit entfernten Universitaet, schuf Weitse Venema das TCP- Wrapper- Paket. Und immer wurde es benutzt, um ueberall in der Welt fuer die Netzwerkdienste einen gewissen Schutz zu bieten. Das ist gut. Aber die TCP- Wrapper haben ein paar nicht zu kleine Fehler. -39- Fuer Anfaenger: Die TCP- Wrappers schuetzen nur TCP- Dienste, wie der Name schon sagt. Das bedeutet: Wenn Du die Dienste vom inetd startest, oder Du die Sachen seziell mit libwrap oder kompatibeln Varainten compiliert hast, sind Deine Dienste nicht geschuetzt. Das hinterlaesst als Folge gigantische Sicherheitsloecher in Deinen Hosts. Wir koennen diese mittels IPF schliessen, indem wir das auch auf dem Localhost anwenden. Beispiel: Mein Laptop wird oftmals in Netzwerke gestoepselt, denen ich nicht unbedingt traue. Und weil das eben so ist, benutze ich den folgenden Regelsatz: pass in quick on lo0 all pass out quick on lo0 all block in log all block out all pass in quick proto tcp from any to any port = 113 flags S keep state pass in quick proto tcp from any to any port = 22 flags S keep state pass in quick proto tcp from any port = 20 to any port 39999 >< 45000 flags S keep state pass out quick proto icmp from any to any keep state pass out quick proto tcp/udp from any to any keep state keep frags Er ist eine ganze Weile so geblieben und hat mir in dieser Zeit keine Schmerzen oder Aengste bereitet, weil IPF die ganze Zeit geladen war. Als ich diesen Regelsatz enger setzen wollte, konnte ich auf den NAT- FTP- Proxy umschalten und ein paar weitere Regeln einbauen, um Spoofing- Angriffe zu verhindern. Aber gerade wie sie jetzt dasteht, ist diese Kiste weitaus restriktiver als es fuer das lokale Netzwerk aussieht und sie tut weit mehr, als es ein typischer Host tut. Das ist eine gute Idee, wenn Du eine Maschine laufen lassen musst, die viele User benutzen duerfen. Und Du kannst sicher gehen, dass keiner von ihnen einen Dienst starten kann, wenn das nicht erlaubt ist. Es wird einen richtigen Hacker nicht davon abhalten, mittels eines Root- Accesses die IPF- Regeln zu aendern oder auf irgendeinem Weg einen Dienst zu starten. Aber es wird das "ehrliche Volk" ehrlich bleiben lassen und deine Dienste sicher, gemuetlich und warm halten; besonders, wenn das LAN unsicher ist. Aus meiner Sicht ist das ein grosser Gewinn. Das Localhost- Filtering in Verbindung mit etwas wie einer "wenig restriktiven" Firewall- Maschine kann genauso viele Performance- Probleme loesen wie auch solche politischen Alptraeume wir "Warum geht IRC nicht?" und "warum kann ich keinen Webserver auf meiner Workstation installieren?! Das ist doch MEINE WORKSTATION!!". Ein anderer sehr grosser Gewinn. Wer sagt denn, dass man Sicherheit und Bequemlichkeit nicht gleichzeitig haben kann? 9.2. Welche Firewall? Transparentes Filtern. Ein der Hauptsorgen beim Aufsetzen einer Firewall ist die Integritaet der Firewall selbst. Kann jemand in Deine Firewall eindringen und dabei den Regelsatz umdrehen? Das ist ein allgegenwaertiges Problem, das Administratoren nicht aus den Augen verlieren sollten. Besonders, wenn sie Firewall- Loesungen auf ihren Unix- oder NT- Maschinen benutzen. Einige Leute missbrauchen diesen Aspekt als ein Argument fuer eine Blackbox- Hardwareloesung. Und das mit dem falschen Argument, dass die innere Obskuritaet von deren geschlossenen Systemen ihre Sicherheit verbessere. Wir haben da einen besseren Weg. -40- Viele Network- Admins wissen, wie die gaengige Ethernet- Bridge funktioniert. Das ist ein Geraet, das zwei Ethernet- Segmente zu einem verbindet. Eine Ethernet- Bridge wird meistens dazu verwendet, separate Gebaeude miteinander zu verbinden, Geschwindigkeiten umzuschalten oder die maximalen Kabellaengen zu vergroessern. Hubs und Switches sind auch Bridges; manchmal sind sie nur Geraete mit zwei Anschluessen, die man Repeater nennt. Verschiedene Versionen von NetBSD, OpenBSD, FreeBSD und Linux beinhalten auch Software, mit der man einen 1000$- PC in eine 10$- Bridge verwandeln kann. Was alle Bridges gemainsam haben ist die Eigenschaft, dass sie, wenn sie in der Mitte einer Verbindung sitzen, von beiden Maschinen nicht bemerkt werden. Man nehme IPFilter und OpenBSD, sagt da der Chefkoch. Das Ethernet- Bridging hat seinen Platz in Layer 2 des ISO- Stacks. IP hat seinen Platz in Layer 3. IPFilter befasst sich hauptsaechlich Layer 3, aber es beschaeftigt sich auch mit Layer 2, wenn es mit den Interfaces arbeitet. Wenn wir IPFilter mit OpenBSD's Bridge- Device mischen, koennen wir eine Firewall bauen, die sowohl unerreichbar als auch unsichtbar ist. Das System braucht keine IP- Adresse; und es muss auch seine Ethernet- Adresse nicht preisgeben. Das einzig sichtbare Zeichen fuer das Vorhandensein eines Filters ist, dass die Latenzzeiten von cat5 etwas hoeher sind als bei einem nomalen cat5 und dass es so aussieht, dass die Pakete es nicht bis zu ihrem endgueltigen Ziel schaffen. Das Aufsetzen eines solchen Regelsatzes ist ueberraschenderweise auch ziemlich einfach. In OpenBSD wird das erste Bridging- Interface "bridge0" genannt. Nehmen wir an, wir haben zwei Ethernet- Karten in unserer Maschine, genannt x10 und x11. Um diese Maschine in eine Bridge umzuwandeln ist alles, was getan werden muss, die folgenden Kommandos einzugeben: brconfig bridge0 add xl0 add xl1 up ifconfig xl0 up ifconfig xl1 up An diesem Punkt wird der gesamte ankommende Verkehr auf x10 an x11 geschickt und der gesamte Verkehr von x11 geht zur Weiterleitung an x10. Du wirst sicher gemerkt haben, dass weder x10 noch x11 eine IP- Adresse besitzen. Wir muessen diese Interfaces auch nicht mit einer Adresse versehen. Wenn man ueber alle diese Dinge nachdenkt, ist es das Beste, wenn wir auch keine hinzufuegen. Regelsaetze verhalten sich grunsaetzlich so, wie sie es immer tun. Breit und braesig ist da ein Bridge0- Interface; wir filtern nicht auf seiner Basis. Dir Regeln folgen basierend auf das spezielle Interface, das wir benutzen; was es wichtig macht, welches Kabel denn nun in welchem Interface auf der Rueckseite der Maschine eingestoepselt ist. Lass uns mal mit ein paar einfachen Regeln starten, um zu illustrieren, was den nun genau passiert ist. Gehe mal davon aus, dass ein Netzwerk benutzt wird wie dieses hier: -41- 20.20.20.1 <---------------------------------> 20.20.20.0/24 network hub Das sieht so aus: Wir haben einen Router auf 20.20.20.1, der an das 20.20.20.0/24- Netzwerk angeschlossen ist. Alle Pakete aus dem 20.20.20.0/24- Netz gehen durch diesen Router, um in die Aussenwelt zu gelangen und zurueck. Jetzt fuegen wir die IPF- Bridge hinzu: 20.20.20.1 <-------/xl0 IpfBridge xl1/-------> 20.20.20.0/24 network hub Wir haben zusaetzlich den folgenden Regelsatz auf dem IPFBridge- Host geladen: pass in quick all pass out quick all Mit diesem geladenen Regelsatz ist die Netzwerkfunktionalitaet identisch. Soweit das den 20.20.20.1- Router und die 20.20.20.0/24- Hosts betrifft, sind die beiden Netzwerkdiagramme identisch. Lass uns den Regelsatz mal ein wenig aendern: block in quick on xl0 proto icmp pass in quick all pass out quick all 20.20.20.1 und 20.20.20.0/24 denken immer noch, dass das Netzwerk identisch ist. Aber wenn 20.20.20.1 20.20.20.2 anpingen soll, wird der Host niemals eine Antwort erhalten. Was auch sonst. 20.20.20.2 wir gerade das erste Paket nicht bekommen. IPFilter wird das Paket abfangen, bevor es an der anderen Seite des virtuellen Kabels ankommt. Wir koennen einen Bridged- Filter ueberall einbauen. Mit dieser Methode koennen wir den Vertrauenskreis im Netzwerk auf einen individuellen hostbasierten Level einschraenken (sofern genug Ethernet- Karten vorhanden sind...). Das Blockieren des ICMP- Verkehrs scheint etwas ungluecklich zu sein, besonders, wenn Du Systemadministrator bist und Du zuweilen pingen, tracerouten oder Deine MTU zuruecksetzen musst. Lass uns mal einen besseren Regelsatz bauen und und mit Hilfe des Originalen IPF- Schluesselfeatures einen Vorteil verschaffen: Die stateful inspection (keep state). pass in quick on xl1 proto tcp keep state pass in quick on xl1 proto udp keep state pass in quick on xl1 proto icmp keep state block in quick on xl0 In dieser Situation kann das 20.20.20.0/24- Netzwerk (vielleicht etwas einfacher als x11- Netz bezeichnet) die Welt draussen erreichen; aber von draussen kann weder jemand in das Netz hinein; noch kann er herausfinden, warum das so ist. Der Router ist erreichbar; die Hosts sind aktiv, aber von aussen kann niemand hinein. Besonders, wenn der Router blossgestellt wurde, bleibt die Firewall aktiv und erfolgreich. -42- Bis hierher haben wir nur nach Interfaces und Protokollen gefiltert. Besonders das Bridging beruehrt auch Layer 2; so koennen wir auch bestimmte IP- Adressen diskriminieren. Normalerweise laufen auch ein paar Dienste. Unser Regelsatz koennte also so aussehen: pass in quick on xl1 proto tcp keep state pass in quick on xl1 proto udp keep state pass in quick on xl1 proto icmp keep state block in quick on xl1 # nuh-uh, we're only passing tcp/udp/icmp sir. pass in quick on xl0 proto udp from any to 20.20.20.2/32 port=53 keep state pass in quick on xl0 proto tcp from any to 20.20.20.2/32 port=53 flags S keep state pass in quick on xl0 proto tcp from any to 20.20.20.3/32 port=25 flags S keep state pass in quick on xl0 proto tcp from any to 20.20.20.7/32 port=80 flags S keep state block in quick on xl0 Jetzt haben wir ein Netzwerk, in dem 20.20.20.2 als Nameserver dient; 20.20.20.3 ist der Server fuer eingehende Mail und 20.20.20.7 ist ein Webserver. Wir muessen allerdings einraeumen, dass das Bridging mit IPFilter noch nicht perfekt ist. Zuerst solltest Du wissen, dass alle aufgesetzen Regeln anstelle einer bidirektionalen Ausrichting nur die "in"- Richtung benutzen. Das liegt daran, dass die "out"- Richtung unter OpenBSD in der Zusammenarbeit mit dem Bridgeing noch nicht implementiert ist. Das wurde urspruenglich so gemacht, um grosse Performanceverluste mit vielen Netzwerkkarten zu verhindern. Es wurde bereits daran gearbeitet, die Geschwindigkeit zu steigern, aber es gilt noch als unimplementiert. Wenn Du dieses Feature wirklich willst, kannst Du selbst Hand an den Code legen oder die OpenBSD- Leute fragen, wie Du ihnen helfen kannst. Zum Zweiten macht der Gebrauch von IPFilter mit den Bridges IPF's NAT- Features unbenutzbar, wenn das nicht gefaehrlich werden soll. Das erste Problem ist, dass es eben eine Filtering- Bridge ist. Das zweite Problem ist, dass die Bridge keine eigene IP- Adresse zum Maskieren besitzt, was mit Sicherheit zu Konfusion und vielleicht auch einer Kernel- Panic beim Booten fuehren wird. Du kannst natuerlich das ausgehende Interface mit einer IP- Adresse versehen, damit NAT funktioniert, aber dann wird ein Teil der Schadenfreude beim Bridging vermindert. 9.2.1. Transparent Filtering zum Korrigieren von Designfehlern im Netz Viele Organisationen begannen, IP zu benutzen, bevor sie auf die Idee kamen, dass es gut sein koennte, eine Firewall oder ein Subnetz einzurichten. Jetzt haben sie ein Class-C- Netz oder groesser, das alle ihre Server, Workstations, Router, Kaffeemaschinen, Staubsauger, eben einfach alles, beinhaltet. Das ist der Grusel schlechthin. Das Umadressieren in brauchbare Subnetze, Trustlevels, Filter etc. ist zeitaufwendig und teuer. Die Ausgaben fuer Hardware und Mannstunden alleine koennen so teuer werden, dass die meisten Organisationen nicht daran interessiert sind, das Problem zu loesen. Dabei wird allerdings nicht die daraus resultierende Downtime erwaehnt. Ein typisches Problem- Netzwerk sieht so aus: -43- 20.20.20.1 router 20.20.20.6 unix server 20.20.20.2 unix server 20.20.20.7 nt workstation 20.20.20.3 unix server 20.20.20.8 nt server 20.20.20.4 win98 workstation 20.20.20.9 unix workstation 20.20.20.5 intelligent switch 20.20.20.10 win95 workstation Nur ist es 20mal groesser und entsprechend chaotischer und ausserdem zu einem guten Teil undokumentiert. Im Idealfall hast Du alle vertraulichen Server in einem Subnetz, die Workstations in einem anderen und die Netzwerk- Switches in einem dritten. Dann wuerde der Router die Pakete zwischen den Subnetzen filtern und den Workstation limitierten Zugriff auf die Server erlauben; kein Zugriff auf die Switches erlauben und nur der Workstation des Systemadministrators den Zugriff auf den Kaffeepott erlauben. Ich habe noch nie ein Class-C- Netzwerk in so einem Zusammenhang gesehen. IPFilter kann da helfen. Um damit zu starten, trennen wir zuerst den Router, die Workstaions und die Server voneinander. Um das zu koennen, brauchen wir zwei Hubs, die wir vielleicht sogar schon haben und eine IPF- Maschine mit drei Ethernet- Karten. Wir beginnen damit, dass wir die Server auf einen Hub legen und die Workstations mit dem anderen verbinden. Normalerweise verbinden wir dann die Hubs untereinander und dann mit dem Router. Statt dessen werden wir den Router mit IPFs x10- Interface verbinden; die Server kommen an x11 und die Workstations werden mit x12 verbunden. Unser Netzwerkplan sieht dann etwa so aus wie dieser hier: | 20.20.20.2 unix server router (20.20.20.1) ____________| 20.20.20.3 unix server | / | 20.20.20.6 unix server | /xl1 | 20.20.20.7 nt server ------------/xl0 IPF Bridge < xl2 | 20.20.20.4 win98 workstation ____________| 20.20.20.8 nt workstation | 20.20.20.9 unix workstation | 20.20.20.10 win95 workstation Wo vorher nichts ausser Kabeln war, ist jetzt eine Filtering- Bridge, fuer die kein einziger Host modifiziert werden muss, um davon zu profitieren. Wir haben das Bridging aktiviert, damit sich das Netzwerk im Normalfall perfekt verhaelt. Vorher starten wir mit einem Regelsatz, der weitgehend unserem letzten Satz entspricht: pass in quick on xl0 proto udp from any to 20.20.20.2/32 port=53 keep state pass in quick on xl0 proto tcp from any to 20.20.20.2/32 port=53 flags S keep state pass in quick on xl0 proto tcp from any to 20.20.20.3/32 port=25 flags S keep state pass in quick on xl0 proto tcp from any to 20.20.20.7/32 port=80 flags Skeep state block in quick on xl0 pass in quick on xl1 proto tcp keep state pass in quick on xl1 proto udp keep state pass in quick on xl1 proto icmp keep state block in quick on xl1 # juh-uh, wir lassen nur tcp/udp/icmp durch, Sir pass in quick on xl2 proto tcp keep state -44- pass in quick on xl2 proto udp keep state pass in quick on xl2 proto icmp keep state block in quick on xl2 # nuh-uh, we're only passing tcp/udp/icmp sir. Zu Wiederholung: Verkehr, der vom Router kommt, ist auf DNS, SMTP und HTTP beschraenkt. In diesem Moment koennen die Server frei miteinander kommunizieren. Abhaengig davon, welcher Organisation Du angehoerst, koennte es sein, dass Du einige dieser Funktionen nicht magst. Vielleicht willst Du nicht, dass Deine Workstations immer Zugriff auf Deine Server haben? Nimm diesen x12- Regelsatz: pass in quick on xl2 proto tcp keep state pass in quick on xl2 proto udp keep state pass in quick on xl2 proto icmp keep state block in quick on xl2 # nuh-uh, we're only passing tcp/udp/icmp sir. ... und aendere ihn nach diesem Muster: block in quick on xl2 from any to 20.20.20.0/24 pass in quick on xl2 proto tcp keep state pass in quick on xl2 proto udp keep state pass in quick on xl2 proto icmp keep state block in quick on xl2 # nuh-uh, we're only passing tcp/udp/icmp sir. Vielleicht willst Du ja nur, das sie die Server fuer das Versenden von Mail mittels IMAP benutzen? Leicht gemacht: pass in quick on xl2 proto tcp from any to 20.20.20.3/32 port=25 pass in quick on xl2 proto tcp from any to 20.20.20.3/32 port=143 block in quick on xl2 from any to 20.20.20.0/24 pass in quick on xl2 proto tcp keep state pass in quick on xl2 proto udp keep state pass in quick on xl2 proto icmp keep state block in quick on xl2 # nuh-uh, we're only passing tcp/udp/icmp Sir. Jetzt sind Deine Workstations und Server vor Zugriffen von aussen geschuetzt; ausserdem sind Deine Server vor Deinen Workstations geschuetzt. Vielleicht ist das Gegenteil richtig; es koennte sein, dass Deine Workstations Zugriff auf die Server haben sollen, aber nicht auf die Welt draussen. Vielleicht betrifft die naechste Exploit- Generation die Workstations und nicht die Server. In diesem Fall kannst Du die x12- Regeln so aendern, dass sie wie diese hier aussehen: pass in quick on xl2 from any to 20.20.20.0/24 block in quick on xl2 Jetzt sind die Server die Herrscher, aber die Clients koennen sich nur mit den Servern verbinden. Wir koennen die Schotten auf den Servern auch dichtmachen: pass in quick on xl1 from any to 20.20.20.0/24 -45- block in quick on xl1 Mit der Kombination dieser beiden koennen die Clients und Server miteinander reden, aber sie bekommen keinen Zugang zur Aussenwelt (Allerdings kann die Aussenwelt auf die paar Dienste von frueher zugreifen). Der gesamte Regelsatz sieht dann etwa so aus: pass in quick on xl0 proto udp from any to 20.20.20.2/32 port=53 keep state pass in quick on xl0 proto tcp from any to 20.20.20.2/32 port=5 flags S keep state pass in quick on xl0 proto tcp from any to 20.20.20.3/32 port=25 flags S keep state pass in quick on xl0 proto tcp from any to 20.20.20.7/32 port=80 flags S keep state block in quick on xl0 pass in quick on xl1 from any to 20.20.20.0/24 block in quick on xl1 pass in quick on xl2 from any to 20.20.20.0/24 block in quick on xl2 Man merke sich: Wenn Dein Netzwerk ein Chaos aus verschiedenen IP- Adressen und Rechnerklassen ist, koennen Filter- Bridges ein Problem loesen, mit dem man sonst leben muessete und vielleicht auch eines Tages angegriffen wird. 9.3. Drop-Safe- Logging mit dup-to und to. Bis jetzt haben wir daen Filter benutzt, um Pakete zu verwerfen. Anstatt sie einfach fallenzulassen, koennen wir diese Pakete auch auf ein anderes System umleiten und etwas nuetzliches mit ihren Informationen anstellen, indem wir sie mit IPMon aufzeichnen. Unser Firewall- System, sei es eine Bridge oder ein Router, kann so viele Interfaces haben, wie wir einbauen koennen. Wir koennen diese Information nutzen, um ein "drop-safe" fuer unsere Pakete zu schaffen. Ein gutes Beispiel waere es, ein Intrusion- Detection- Netzwerk zu implementieren. Fuer Anfaenger kann es entscheidend sein, unser Detection- Netzwerkes vor unserem realen Netzwerk zu verstecken, so dass wir verhindern koennen, entdeckt zu werden. Bevor wir anfangen: Es gibt ein paar Charakteristiken, die wir uns merken sollten. Wenn wir nur mit blockierten Paketen dealen wollen, koennen wir jeweils das "to"- oder das "fastroute"- Schluesselwort verwenden (Wir erklaeren den Unterschied zwischen diesen beiden spaeter). Wenn wir die Pakete passieren lassen, was wir im Normalfall wollen, brauchen wir eine Kopie des Paketes fuer unsere "drop-safe"- Aufzeichnung mittels des "dup-to"- Schluesselwortes. 9.3.1. Die dup-to Methode Wenn wir beispielsweise eine Kopie von allem, was ueber das x13- Interface auf ed0 in Richtung unseres "drop-safe"- Netzes verlaesst, benutzen wir diese Regel in unserer Filterliste: pass out on xl3 dup-to ed0 from any to any -46- Es kann auch sein, dass Du das Paket direkt zu einer bestimmten IP- Adresse in Deinem "drop-safe"- Netz schicken willst, anstatt nur eine Kopie davon zu machen und aus das Beste zu hoffen. Dafuer modifizieren wir unsere Regel ein wenig: pass out on xl3 dup-to ed0:192.168.254.2 from any to any Wir warnen aber davor, dass diese Methode die Zieladresse des kopierten Pakets aendern wird, was die Aufzeichnung unbrauchbar machen kann. Aus diesem Grund empfehlen wir die Methode mit den bekannten Adressen nur, wenn Du sicher bist, dass die Adresse, die Du aufzeichnest in irgendeiner Form mitteilt, fuer wen Du aufzeichnest (Beispiel: Benutze nicht dieselbe Adresse, um sowohl den Verkehr fuer den Webserver als auch den Mailserver aufzuzeichnen. Du wirst schwere Zeiten erleben, wenn Du spaeter herausfinden musst, welches System das Ziel fuer einen bestimmten Paketsatz gewesen ist.). Diese Technik kann auch effektiv genutzt werden, wenn Du eine IP- Adresse auf Deinem "drop-safe"- Netz in ziemlich demselben Weg verwendest, wie eine Multicast- Gruppe im realen Internet (Beispiel: 192.168.254.2 koennte der Kanal fuer Deinen HTTP- Traffic- Analysesystem sein; 23.23.23.23 waere vielleicht der Kanal fuer Telnet- Sitzungen; etc.). Du musst diesen Adressensatz zu Zeit nicht als eine Adresse oder ein Alias auf irgendeinem Deiner Analysen- Systeme setzen. Normalerweise wird die IPFilter- Maschine gebraucht, um fuer die neue Zieladresse zu ARPen (dup-to ed0:192.168.254.2 natuerlich). Aber wir koennen diese Entscheidung umgehen, indem wir einen statischen ARP- Eintrag fuer diesen Kanal In unserem IPFilter- System vornehmen. Grundsaetzlich ist "dup-to ed0" alles, was benoetigt wird, um eine neue Kopie des Paketes ueber unser "drop-safe"- Netz fuer Aufzeichnung und Ueberpruefung zu bekommen. 9.3.2. Die "to" Methode Die "dup-to"- Methode hat einen unmittelbaren Nachteil. Wenn es eine Kopie eines Paketes machen und dieses fuer das neue Ziel modifizieren soll, wird es eine Weile brauchen, um die ganze Arbeit zu tun und mit dem naechsten Paket zu dealen, das ueber das IPFilter- System hereinkommt. Wenn wir nicht darauf achten, dass das Paket die Firewall zu seinem normalen Ziel passiert und wir das irgendwie blockieren, koennen wir das "to"- Schluesselwort verwenden, um das Paket hinterher in die normale Routingtabelle zu druecken und es dahin treiben, dass es ueber ein anderes Interface als im Normalfall den Rechner verlaesst. block in quick on xl0 to ed0 proto tcp from any to any port < 1024 Wir benutzen "block quick" fuer das Interface- Routing; weil, wie fastroute, der "to- interface"- Code zwei Paketpfade durch IPFilter generieren wird, die mit "pass" benutzt werden und diese Dein System in Panik versetzen werden. Viel Spass damit!