Hole Punching (englisch für ‚Lochstanzen‘) ist eine Technik, um in einem Rechnernetz eine Ende-zu-Ende-Verbindung zwischen zwei Rechnern herzustellen, auch wenn beide sich hinter restriktiven Firewalls oder NAT-Routern befinden. Im Regelfall wird Hole Punching für UDP-basierte Anwendungen verwendet. Für TCP wird Hole Punching seltener eingesetzt, da es durch das zustandsbehaftete Protokoll schwieriger zu realisieren ist.
Genutzt wird diese Technik für Anwendungen wie Online-Spiele, Peer-to-peer-Netzwerke und IP-Telefonie.
UDP Hole Punching
Zwei Clients, die eine UDP-Kommunikation herstellen wollen, senden ein UDP-Paket an einen uneingeschränkt erreichbaren Server, der dadurch die IP-Adressen und Port-Nummern beider Clients erfährt. Hierfür kann beispielsweise das STUN-Protokoll verwendet werden. Diese Informationen gibt der Server dem jeweils anderen Client weiter.
Beide Clients senden nun jeweils ein UDP-Paket an den anderen Client. Wesentlich dabei ist, dass die eigene Stateful-Paket-Inspection-Firewall des Senders dadurch eine Regel erzeugt, die im weiteren Verlauf den Empfang von Antwortpaketen des Adressaten zulässt. Der Inhalt des Pakets ist dagegen für das Hole-Punching-Verfahren unerheblich und kann, sofern das Paket überhaupt die Firewall des Zielrechners passiert, vom Zielrechner ignoriert werden. Sobald auf beiden Seiten eine Firewall-Regel die Kommunikation zulässt, können beide Clients direkt via UDP miteinander kommunizieren.
Beispiel
Alice möchte Dateien direkt an Bob verschicken. Hierfür nutzen sie einen Client mit Serverinfrastruktur. Die Serverinfrastruktur hält einen Anmeldeserver, erreichbar unter der Adresse 1.2.3.4 bereit.
Alice und Bob sind beide an diesem Server angemeldet. Alice schickt eine Austauschanfrage mit dem Inhalt Ihrer IP-Adresse und Wunschport (IP 2.2.2.2, Port 49000) für Bob an den Server 1.2.3.4. Da Bob an dem Server ebenfalls angemeldet ist und eine Verbindung zu diesem hält, kann der Server Bobs Client erreichen. Bobs Client schickt nun ein UDP Paket von seiner IP(1.1.1.1) mit dem ausgehenden Port 50000 an Alice (2.2.2.2:49000). Dadurch wartet er auf eine Antwort an seinem ausgehenden Port. Seine Firewall muss den Port für eine gewisse Zeit offen halten, da sie aufgrund der Eigenschaften des UDP-Protokolls nicht genau wissen kann, wann die Verbindung zu Ende ist. Das Paket wird allerdings zunächst von Alice Firewall geblockt. Deshalb schickt Bob an den Server 1.2.3.4 nun die Aussage, dass er Port 50.000 bei sich geöffnet hat. Daraufhin erhält Alice Client die Nachricht ein UDP-Paket von Port 49.000 an Bobs IP(1.1.1.1, Port 50000) zu schicken. Alice Client erledigt dies und wartet nun ebenfalls auf eine Antwort, hier allerdings von Bobs IP-Adresse 1.1.1.1 von Port 50000. Bob empfängt Alice’ Nachricht, da diese, dank des vorher geschlagenen Lochs, nicht mehr von seiner Firewall verworfen wird. Bobs Antworten an Alice zu Port 49.000 kommen nun auch an und Alice kann Ihre Dateien nun direkt an Bob schicken und Bob den Empfang direkt bestätigen.
TCP Hole Punching
TCP Hole Punching nutzt dieselbe Grundidee wie UDP Hole Punching: zwei Clients unternehmen gleichzeitig einen gegenseitigen Verbindungsversuch. Die Erfolgsaussicht ist allerdings geringer, da ein zustandsbehafteter Paketfilter beim zustandsbehafteten TCP die Kommunikation wirkungsvoller als beim zustandslosen UDP filtern kann. In der Regel lassen NAT-Router ausgehende TCP-Verbindungen uneingeschränkt zu, blockieren jedoch eingehende TCP-Verbindungen, für die keine explizite Portweiterleitung eingerichtet wurde. Je nach Implementierung gibt es verschiedene Arten der Netzwerkadressübersetzung, die sich anhand der Portzuordnung und der Endpunktfilterung unterscheiden lassen.
Die Portzuordnung gibt an, ob und unter welchen Umständen ein NAT-Router denselben Port für ausgehende Verbindungen wiederverwendet. Die Endpunktfilterung gibt an, nach welchen Kriterien bei einer bestehenden Portzuordnung eingehende TCP-Pakete gefiltert werden. Untersuchungen zeigen, dass die meisten NAT-Router auch bei einer bestehenden Portzuordnung eingehende Verbindungen restriktiv filtern, sodass eine Verbindung nur zustande kommen kann, wenn beide Clients gleichzeitig einen ausgehenden TCP-Verbindungsaufbau initiieren. Ob dies gelingt, hängt vom Verhalten der beiden NAT-Router in Randfällen ab, die vom gewöhnlichen Drei-Wege-Handshake abweichen. Durch das Ausnutzen von Tricks, die beispielsweise IP-Spoofing oder Raw Sockets erfordern, lässt sich die Erfolgswahrscheinlichkeit auf Kosten einer erhöhten Komplexität verbessern.
Eine Alternative für Anwendungen, die ein zuverlässiges Transportprotokoll benötigen, ist die Verwendung von Reliable UDP. Hiermit werden einerseits Eigenschaften von TCP nachgebildet und andererseits ist die Nutzung des einfacheren UDP Hole Punching möglich, da Reliable UDP auf UDP basiert.
Literatur
Einzelnachweise
- 1 2 3 Saikat Guha, Paul Francis: Characterization and Measurement of TCP Traversal through NATs and Firewalls. In: Proceedings of the 5th ACM SIGCOMM Conference on Internet Measurement. 2005 (cornell.edu [PDF]).
- ↑ Sebastian Holzapfel et al.: SYNI – TCP Hole Punching Based on SYN Injection. In: IEEE 10th International Symposium on Network Computing and Applications. 2011 (wander.science [PDF]).