zurück zum Artikel

Wie Skype & Co. Firewalls umgehen

Hintergrund

Peer-to-Peer-Software ist der Albtraum eines Netzwerk-Admins. Um möglichst direkt Pakete mit dem Gegenüber austauschen zu können, bohrt sie mit raffinierten Tricks Löcher in Firewalls, die eigentlich keine Pakete von draußen reinlassen sollen.

Hinter einer Firewall, die das System vor den Gefahren aus dem Internet schützen soll, sitzen immer mehr Rechner. Im Idealfall realisiert diese Firewall-Funktion ein Router, der auch noch die lokale Netzwerkadresse des PC passend auf die öffentliche IP-Adresse umsetzt (Network Adress Translation, NAT). So kann kein Angreifer von außen den PC erreichen - Verbindungsaufbau ist nur von drinnen nach draußen möglich.

Problematisch wird das natürlich, wenn zwei Rechner jeweils hinter so einer NAT-Firewall sitzen und trotzdem direkt miteinander reden sollen - beispielsweise weil ihre Besitzer via Voice over IP miteinander telefonieren wollen. Das Dilemma ist offensichtlich: Egal, wer von den beiden wen anruft - die Firewall des Gegenübers wehrt den vermeintlichen Angriff ab und wirft die Datenpakete einfach weg; ein Gespräch kommt nicht zustande. So würde das ein Netzwerkadministrator jedenfalls erwarten.

Aufgebohrt

Doch wer schon einmal die populäre Internet-Telefonie-Software Skype eingesetzt hat, weiß, dass die hinter einer NAT-Firewall genauso reibungslos funktioniert, als hinge der PC direkt am Internet. Denn die Erfinder von Skype & Co. haben sich für dieses Problem etwas einfallen lassen.

Selbstverständlich muss jede Firewall auch Pakete ins lokale Netz hereinlassen - schließlich will der Anwender Webseiten betrachten, E-Mails lesen und so weiter. Dazu muss die Firewall die zugehörigen Datenpakete von außen an den Arbeitsplatzrechner im LAN weiterleiten. Sie tut dies aber nur, wenn sie zu der Überzeugung gelangt, dass ein Paket die Antwort auf ein ausgehendes Datenpaket darstellt. Dazu führt ein NAT-Router Tabellen, welcher interne Rechner mit welchem externen gesprochen hat und welche Ports die beiden dabei verwendet haben.

Der Trick der VoIP-Software besteht nun darin, der eigenen Firewall vorzugaukeln, es existiere eine Verbindung, der sie die später eingehenden Datenpakete zuordnen soll. Zugute kommt Skype dabei die Tatsache, dass die Audiodaten für VoIP ohnehin über das verbindungslose UDP verschickt werden. Anders als bei TCP, das in jedem Paket zusätzliche Verbindungsinformationen transportiert, sieht eine Firewall bei UDP nur die Adressen und Ports von Quell- und Zielsystem. Stimmen die bei einem eingehenden UDP-Paket mit den Daten eines NAT-Tabelleneintrags überein, leitet sie das Paket guten Gewissens an den internen Rechner weiter.

Vermittlung

Eine wichtige Aufgabe beim Gesprächsaufbau mit Skype übernimmt ein Vermittlungsserver, mit dem beide Kommunikationspartner in ständigem Kontakt stehen. Dies geschieht über eine TCP-Verbindung, die die Clients selber aufbauen. Der Skype-Server weiß somit ständig, unter welcher Adresse ein Skyper aktuell im Internet zu erreichen ist. Die eigentlichen Telefonverbindungen laufen wenn irgend möglich nicht über den Skype-Server. Stattdessen tauschen die Clients diese Daten direkt aus.

Angenommen Alice will ihren Freund Bob anrufen. Ihr Skype-Client teilt diesen Wunsch dem Skype-Server mit. Der weiß dabei schon einiges über Alice: An der ankommenden Anfrage sieht er, dass Alice derzeit unter der IP-Adresse 1.1.1.1 zu erreichen ist und ein kurzer Test enthüllt, dass ihre Audiodaten immer von UDP-Port 1414 kommen. Diese Informationen übermittelt der Skype-Server an den Skype-Client von Bob, den er laut seiner Datenbank derzeit unter der IP-Adresse 2.2.2.2 erreicht und der bevorzugt den UDP-Port 2828 verwendet.

Alice ruft Bob an.
Schritt 1: Alice versucht den ebenfalls bei Skype angemeldeten Bob anzurufen.
Bob bohrt ein Loch
Schritt 2: Bob versucht Alice zu erreichen und bohrt dabei ein Loch in seine Firewall.

Bobs Skype-Programm bohrt daraufhin ein Loch in seine eigene Netzwerk-Firewall: Es schickt ein UDP-Paket an 1.1.1.1 Port 1414. Das wirft Alices Firewall zwar weg, aber das weiß ja Bobs Firewall nicht. Die denkt fürderhin, dass alles, was von 1.1.1.1 Port 1414 kommt und an Bobs IP-Adresse 2.2.2.2 und den Port 2828 gerichtet ist, schon seine Richtigkeit hat - es ist ja vermutlich die Antwort auf die eben verschickte Anfrage.

Erfolgreicher Anruf
Schritt 3: Durch dieses Loch erreicht Alice schliesslich Bobs Rechner.

Jetzt reicht der Skype-Server Bobs Koordinaten an Alice weiter, deren Skype dann versucht, ihn unter 2.2.2.2:2828 zu erreichen. Bobs Firewall sieht die bekannte Absenderadresse und leitet die vermeintliche Antwort nach drinnen zu Bobs PC weiter - es klingelt bei Bob.

Klinken putzen

Klinken putzen

Natürlich ist diese Beschreibung etwas vereinfacht und die Details hängen sehr stark von den konkreten Eigenschaften der eingesetzten Firewalls ab. Doch sie entspricht im Prinzip unseren Beobachtungen beim Verbindungsaufbau zwischen zwei Skype-Clients, die sich jeweils hinter einer Linux-Firewall befanden. Diese waren auf NAT für ein LAN konfiguriert und gestatteten ausgehenden UDP-Verkehr.

Die NAT-Funktionen von Linux haben nämlich die VoIP-freundliche Eigenschaft, die Ports ausgehender Pakete zunächst mal nicht zu ändern. Der NAT-Router ersetzt lediglich die private, lokale IP-Adresse durch seine eigene; der von Skype gewählte UDP-Quell-Port bleibt erhalten. Erst wenn mehrere Clients im lokalen Netz denselben Quell-Port verwenden, greift der NAT-Router ein und setzt ihn auf einen noch unbenutzten Wert um. Denn jeder Satz aus den jeweils zwei IP-Adressen und Ports muss sich jederzeit eindeutig einer Verbindung zwischen zwei Rechnern zuordnen lassen. Der Router muss unter anderem später aus dem Ziel-Port der Antwortpakete die interne IP-Adresse des ursprünglichen Absenders rekonstruieren.

Andere NAT-Router bilden Ports möglichst direkt auf einen bestimmten Bereich, beispielsweise den ab 30 000, ab und schreiben dabei den UDP-Port 1414 wenn möglich auf 31414 um. Das bereitet Skype natürlich keine Probleme; das oben skizzierte Szenario funktioniert damit analog und ohne Einschränkungen.

Etwas komplizierter wird es, wenn eine Firewall wie Checkpoints Firewall-1 die Ports einfach der Reihe nach vergibt: Die erste Verbindung bekommt 30001, die nächste 30002 und so weiter. Damit weiß der Skype-Server zwar, dass Bob mit ihm gerade auf Port 31234 spricht, die Verbindung zu Alice wird allerdings über einen anderen laufen. Doch auch in solchen Fällen kann Skype die Firewall austricksen. Es klappert dann einfach der Reihe nach Ports oberhalb von 31234 ab, in der Hoffnung, irgendwann den richtigen zu treffen. Funktioniert das nicht auf Anhieb, bleibt Skype hartnäckig: Bobs Skype öffnet auf dessen Anweisung eine neue Verbindung zum Skype-Server, deren Quellport dann sofort für eine neue Versuchsreihe herhalten muss.

packet dump
Zur Not geht Skype Klinken putzen und probiert alle Ports in einem ganzen Bereich aus. Hier wird es auf Port 38901 fündig.

Trotzdem kann es natürlich bei besonders aktiven Netzen passieren, dass Alice den richtigen Port mit dem Loch nicht trifft. Selbiges gilt auch für eine spezielle Firewall-Gattung, die jeder neuen Verbindung einen zufälligen Quellport zuweist. Damit kann der Skype-Server Alice keinen erfolgversprechenden Tipp mehr geben, wo ein passendes Loch in Bobs Firewall zu finden ist.

Doch selbst dann gibt Skype nicht auf. In solchen Fällen kommt ein Skype-Server als Vermittler (Relay) zum Einsatz. Er nimmt jeweils ankommende Verbindungen von Alice und Bob entgegen und leitet die Pakete entsprechend weiter. Diese Lösung lässt sich immer realisieren, sofern die Firewall ausgehenden UDP-Verkehr gestattet. Sie bedeutet allerdings eine zusätzliche Belastung der Infrastruktur, da die kompletten Audiodaten über Skype-Server laufen müssen. Die verlängerten Paketlaufzeiten machen sich unter Umständen auch als unangenehme Verzögerungen bemerkbar.

Das beschriebene Verfahren kommt keineswegs nur bei Skype zum Einsatz und ist als "UDP hole punching" bekannt. Auch andere Netzwerkdienste wie das Gamer-VPN Hamachi, das auf Peer-to-Peer-Kommunikation von Rechnern hinter Firewalls angewiesen ist, setzen auf ähnliche Verfahren. Eine weiterentwickelte Form hat es sogar in den Rang eines Quasistandards geschafft: RFC 3489 [1] beschreibt mit "Simple Traversal of UDP through NAT" - kurz STUN - ein Protokoll, mit dem zwei STUN-Clients unter Mithilfe eines STUN-Servers die Beschränkungen von NAT in vielen Fällen umgehen können. Der Entwurf Traversal Using Relay NAT (TURN [2]) beschreibt einen möglichen Standard für Vermittlungs-Server (Relays).

Selber bohren

UDP Hole Punching kann man mit ein paar kleinen Hilfsmitteln auch selbst ausprobieren. Die benötigten Tools hping2 und netcat finden sich in den meisten Linux-Distributionen. Dabei ist local ein Rechner hinter einer Linux-Firewall (local-fw) mit Stateful Firewall, die (UDP-)Verbindungen nur von drinnen nach draußen gestattet. Der Testrechner remote hing in unserem Test der Einfachheit halber ganz ohne Firewall direkt am Internet.

Zunächst mal auf der Konsole local/1 hinter der Firewall einen UDP-Listener auf UDP-Port 14141 starten:

local/1# nc -u -l -p 14141

Den versucht ein externer Rechner "remote" dann zu erreichen

remote# echo "hello" | nc -p 53 -u local-fw 14141

Doch da kommt wie erwartet nichts auf local/1 an und dank Firewall auch nichts zu remote zurück. Jetzt stanzt das Universal-Tool zum Erzeugen von IP-Paketen hping2 auf einer zweiten Konsole local/2 ein Loch in die Firewall:

local/2# hping2 -c 1 -2 -s 14141 -p 53 remote

Sofern sich remote anständig verhält, meldet er via ICMP "Port Unreachable" zurück - das spielt für das Weitere jedoch keine Rolle. Beim zweiten Übertragungsversuch

remote# echo "hello" | nc -p 53 -u local-fw 14141

spuckt der netcat-Listener auf Konsole local/1 das "hello" aus - das UDP-Paket von außen hat die Firewall passiert und gelangte zum Rechner dahinter.

Netzwerk-Administratoren, die diese Art von Löchern in ihrer Firewall nicht schätzen und Missbrauch fürchten, haben eigentlich nur eine Option: Sie müssen ausgehenden UDP-Verkehr sperren beziehungsweise auf notwendige Einzelfälle beschränken. UDP wird für die normale Internet-Kommunikation ohnehin nicht benötigt: Web, E-Mail und ähnliches arbeiten mit TCP. Probleme dürften vor allem Streaming-Protokolle bereiten, die aufgrund des geringeren Ballasts bevorzugt auf UDP setzen.

Das Löcherbohren funktioniert erstaunlicherweise auch mit TCP. Nach einem ausgehenden SYN-Paket befördert der Firewall/NAT-Router eingehende Pakete mit passenden IP-Adressen und Ports auch dann ins LAN, wenn sie keine oder die falsche Sequenznummer bestätigen (ACK). Zumindest Linux-Firewalls werten diese Information offenbar nicht konsequent aus. Der Aufbau einer TCP-Verbindung klappt jedoch auf diesem Weg nicht ohne Weiteres, da Alice die im ersten Paket von Bob gesendete Sequenznummer nicht kennt. Das Paket mit dieser Information hatte ja ihre eigene Firewall verworfen. (ju [3])


URL dieses Artikels:
http://www.heise.de/-270856

Links in diesem Artikel:
[1] http://www.ietf.org/rfc/rfc3489.txt
[2] http://www.jdrosen.net/midcom_turn.html
[3] mailto:ju@ct.de