Stateful Packet Inspection
Unter Stateful Packet Inspection (SPI; deutsch Zustandsorientierte Paketüberprüfung) versteht man eine dynamische Paketfiltertechnik, bei der jedes Datenpaket einer bestimmten aktiven Session zugeordnet wird.
Die Datenpakete werden analysiert und der Verbindungsstatus wird in die Entscheidung einbezogen. Bei dieser Technik, die in Firewalls eingesetzt wird, werden die Datenpakete (eigentlich: Segmente) während der Übertragung auf der Vermittlungsschicht (3. Schicht des OSI-Modelles) analysiert und in dynamischen Zustandstabellen gespeichert. Auf Basis des Zustands der Datenverbindungen werden die Entscheidungen für die Weiterleitung der Datenpakete getroffen. Datenpakete, die nicht bestimmten Kriterien zugeordnet werden können oder eventuell zu einer DoS-Attacke gehören, werden verworfen. Firewalls mit SPI-Technik sind daher in sicherheitsrelevanten Anwendungen den reinen Paketfilter-Firewalls überlegen.
Die Firma Check Point Software Technologies Ltd. nimmt für sich in Anspruch, diese Technik im Jahr 1993 erfunden zu haben.[1]
Funktionsweise
Kommuniziert ein Rechner A mit einem Rechner B über einen einfachen Paketfilter (also ohne Stateful Packet Inspection), so muss dieser in seinem Regelwerk zwei Verbindungen erlauben:
- Quelle A nach Ziel B mit Dienst HTTP (für die Anfrage, z. B. „Schicke mir Webseite www.example.com“)
- Quelle B nach Ziel A mit Dienst HTTP (für die Antwortpakete, in diesem Beispiel der Inhalt von www.example.com)
Dadurch ist das Regelwerk unsicherer als eigentlich nötig, da B jederzeit an A senden darf, auch wenn A gar keine Webseite angefordert hat (Bei Netfilter kann mit Hilfe des 'Sync-Flags' verhindert werden, dass B zu A eine Verbindung aufbaut).
Bei der zustandsgesteuerten Filterung (also mit Stateful Packet Inspection) wird nur eine Regel benötigt (bzw. die zweite wird über eine allgemeine Regel (ESTABLISHED/RELATED) erlaubt). Damit wird der Regelsatz wesentlich übersichtlicher:
- Quelle A nach Ziel B
Der Paketfilter merkt sich, wenn Rechner A mit Rechner B kommuniziert, und erlaubt nur dann Antworten darauf von Rechner B an Rechner A. Rechner B kann dadurch nicht ohne Anforderung von A beginnen.
Die Regeln für Antwortpakete werden dynamisch erzeugt und nach Eintreffen der Antwort oder nach einem Timeout automatisch gelöscht.
Noch weitergehende Systeme prüfen zusätzlich, ob ein Paket zu einem bestimmten Zeitpunkt in der Kommunikation überhaupt erlaubt ist (zum Beispiel weitere Pakete schicken, obwohl der andere Teilnehmer die Kommunikation bereits abgeschlossen hat).
Stateful Inspection bei UDP-Paketen
Auf den ersten Blick sieht eine Stateful Packet Inspection bei UDP-Paketen wie ein Widerspruch aus, da UDP im Gegensatz zu TCP zustandslos arbeitet. Die meisten Implementierungen (z. B. Linux-Netfilter) behandeln UDP trotzdem als stateful, in dem Sinne, dass beim Versenden einer Anforderung per UDP für kurze Zeit eine dynamische Firewall-Regel für die Antwortpakete erzeugt wird. Im Beispiel DNS-Anfragen werden dadurch nur Antwortpakete von den Nameservern erlaubt, die man selbst gefragt hat.
Manche Programme – z. B. Skype – benutzen dies in einem als Hole Punching bezeichneten Verfahren, um durch Firewalls Punkt-zu-Punkt-Verbindungen aufzubauen. Beide Teilnehmer erfahren vom Skype-Server, auf welcher IP-Adresse und welchem Port Skype bei der Gegenseite arbeitet. Dann schicken beide ein UDP-Paket an die Gegenseite. Dort werden diese Pakete beim Eintreffen zwar verworfen, weil keine Input-Regel existiert, erzeugen aber auf der Firewall des ausgehenden Rechners eine Regel, die ab dann 'Antworten' erlaubt. Danach können beide Seiten miteinander kommunizieren. Mit TCP würde das (trivial) nicht funktionieren, da die Firewall aufgrund von Sequenznummern echte Antwortpakete erkennen kann.
Stateful Inspection bei ICMP
Wer Ping-Anfragen senden will, aber nicht auf Ping antworten möchte, definiert zuerst eine ausgehende Regel für ICMP, und danach eine eingehende Regel, die generell alle eingehenden Pakete zulässt, für die es bereits ausgehende Verbindungen gibt (RELATED). Die Antwort wird durchgelassen, wenn die Firewall eine bestehende Verbindung erkennt. Dann kann er selbst pingen, erlaubt aber keinen eingehenden Ping. Dies funktioniert, obwohl ICMP anders als TCP ein verbindungsloses Protokoll ist. Verbindungslos bedeutet, dass die einzelnen Pakete in keinem Zusammenhang zueinander stehen.
Stateful Inspection bei FTP
FTP ist problematisch. Es werden zwei Ports, 'ftp' und 'ftp-data' (21 und 20), verwendet. 'ftp' wird für die Übertragung von Kommandos verwendet, während ftp-data für Datenübertragung (Dateiinhalte oder Verzeichnisinhalte) verwendet wird. Hierbei gibt es zwei verschiedene Arten (active mode und passive mode), in welcher Richtung die Datenverbindung (ftp-data) aufgebaut wird. Im Linux-Kernel gibt es ein Kernelmodul, welches das Zusammenspiel beider Ports beherrscht.
Timeout
Sowohl TCP- als auch UDP-Verbindungen haben bei Stateful Packet Inspection immer einen zugewiesenen Timeout. Bei UDP, weil nicht erkennbar ist, wenn eine Verbindung beendet worden ist; bei TCP, weil es passieren kann, dass Verbindungen nicht ordnungsgemäß abgebaut werden. Der UDP-Timeout liegt üblicherweise im Bereich 20–40 Sekunden, bei TCP 15–60 Minuten.
Ist der Timeout nicht lang genug und werden legitime Verbindungen dadurch von der Firewall beendet, gibt es zwei Lösungsmöglichkeiten. Eine Verlängerung des Timeouts hilft zwar, erhöht aber auch den Speicherbedarf des Systems und reduziert die Sicherheit. Die bevorzugte Methode sollte daher der Einsatz von Keep-Alive-Paketen sein. Diese lassen sich in manchen Applikationen wie SSH-Clients oder auch im Betriebssystem konfigurieren.
Setzen des TCP-Keep-Alives unter Linux auf alle 120 Sekunden:
echo 120 > /proc/sys/net/ipv4/tcp_keepalive_time
Implementierungen von Stateful Firewalls
- Check Point Firewall-1 (Solaris, Windows, IPSO, RHEL, SPLAT)
- Pf (Paketfilter) (OpenBSD)
- Ipfw (FreeBSD)
- Iptables (Linux ab 2.4)
- Fritzbox
- OPNsense (basierend auf FreeBSD und ASLR von HardenedBSD)