Gratis Internet (1): Australien, DNS- und ICMP-Tunnel
Auf meiner Australienreise im Dezember musste ich fast 4 Wochen mehr oder weniger ohne Internet auskommen. Und das ist gar nicht so leicht für einen Telematikstudenten ;-) Verschärft hat sich die Situation dadurch, dass es fast in jedem Hotel (und sogar in kleinen Motels an der Great Ocean Road!) entweder ein LAN Kabel im Zimmer gab oder WLAN. Und dabei hatten wir noch einen Notebook dabei! Zu meiner Ernüchterung waren alle Zugänge sehr teuer. Aber alle Systeme hatten eines gemeinsam: Sie benutzten eine Art “Hotspot-System” ähnlich wie Chilispot. Man musste sich einen Zugang kaufen und konnte sich dann per Webinterface einloggen. Bei allen Zugängen konnte ich eines feststellen: Es gab immer einen internen DNS Server, der alle Anfragen - auch ins Internet - beantwortete, obwohl die Firewall sonst alles gesperrt hat. Ich konnte z.B. “gate.nobaq.net” auflösen und die Antwort kam (wahrscheinlich) von meinem eigenen Server zu Hause, da dort der Primary DNS für diese Domäne läuft. Manche Hotels gestatteten sogar ICMP Zugriff, d.h. ich konnte meinen Rechner zu Hause sogar pingen! Da war mir natürlich sofort klar: Man hatte einen Kanal nach aussen durch die Anfrage, einen nach innen durch die Antwort. D.h. durch einen Tunnel könnte man langsamen aber zumindest gratis Zugriff aufs Internet bekommen. Voller Euphorie hab ich diese Erkenntnisse meiner Schwester erzählt. Auf die Aufforderung: “Naja, wir ham eh den ganzen Abend Zeit, mach…” musste ich leider mit “naja, so schnell geht das dann auch nicht. Das ist ja nur einmal Theorie”. Zu Hause angekommen hab ich mich dem Thema einmal angenommen...
Zu ICMP hab ich gar nichts mehr gesucht, denn das war nur einmal erlaubt. DNS jedoch immer. Die erste Suche nach Lösungen für DNS Tunnel brachte zwar Erfolge, zeigte jedoch, dass der Aufwand sehr, sehr hoch ist und keine fertige “out-of-the-Box” Lösung existierte.
Doch wie funktioniert das ganze nun?
DNS (Domain Name Service) ist das Protokoll im Internet, das Namen (z.B. www.nobaq.net.) in die dazugehörige IP Adresse (193.154.229.55) umsetzt. Jeder Computer im Internet wird mit einer IP Adresse adressiert, da dies das Routing ermöglicht. Da sich der Mensch jedoch leichter Namen merkt, wurde das DNS System entworfen, um zwischen den beiden Adressierungsarten umzurechnen.
DNS ist eine globale, verteilte, nach einer Baumstruktur aufgebaute Datenbank. Die Wurzel bilden die DNS-Root-Server, die für die Zone “.” verantwortlich sind. Für jeden Unterzone (z.B. *.net.) wird nun mit einem sogenannten NS Record an einen weiteren Nameserver delegiert. Die ursprüngliche Abfragemethode für DNS nennt man “iterativ”. Dabei hat jeder Computer die IP Adresse eines Root-Servers gespeichert und stellt dorthin seine Anfrage (z.B. www.nobaq.net.). Der Root-Server antwortet: “Ich kenne die Antwort zwar nicht, aber ich liefere die den NS Record für net. wo du weitere Informationen findest”. Nun fragt der Computer diesen Server. Dieser antwortet wiederum: “Für nobaq.net. bin ich nicht zuständig, aber ich kann dir den NS Record für diese Zone liefern, den du dann befragen kannst” usw. Dieses System überlässt die komplette Abfragearbeit dem eigenen Computer (bzw. der Resolver-Library) und erfordert, dass Port 53 (DNS) in der Firewall offen ist, da ja jeder beliebige DNS Server kontaktiert werden muss. Diese Abfragemethode lässt sich z.B. mit
dig +trace www.nobaq.net.
untersuchen. Eine andere Methode ist die sogenannte “rekursive”. Dabei befragt der Resolver nicht direkt die root-Server sondern einen zugewiesenen DNS Server, z.B. den des Providers oder eben einen internen. Dieser gibt wiederum die Anfrage weiter oder löst sie selbst auf. Diese Methode verwenden alle normalen Computer. Man kann sie mit
dig +recurse @dns-server www.nobaq.net.
untersuchen. Die Firewall braucht nun nicht mehr Port 53 offen haben sondern es reicht, wenn der interne DNS Server Zugriff nach aussen auf Port 53 hat.
Im oben genannten Beispiel der Hotspots im Hotel ist es genau so: Jeglicher Traffic nach aussen wird von der Firewall gesperrt. Den internen DNS Server kann ich jedoch verwenden. Anfragen für externe Hosts gibt dieser aber nach aussen weiter (vermutlich um für jede Seite auf die Portalseite umlenken zu können). So entsteht ein sehr schmalbandiges Übertragungssystem nach aussen :-)
Der Upstream
Als Upstream steht die normale Anfrage an einen Nameserver zu Verfügung, also im Endeffekt der Domainname. z.B. können Daten verpackt werden in dasisteinegrossemengeandaten.tunnel.nobaq.net. Da dabei nur die Buchstaben und Zahlen vorkommen dürfen, wird die Bandbreite weiter sehr eingeschränkt. Da DNS nicht zwischen Groß- und Kleinschreibung unterscheidet muss hier eine Base32 Kodierung vorgenommen werden.
Der Downstream
Um Daten zu empfangen gibt es die Antwort des DNS Servers. In den meisten Fällen ist so eine Antwort ein A Record, der eine IP Adresse angibt. Da eine IP Adresse nur 32 Bit lang ist, können nur 4 Byte pro Anfrage transportiert werden was wiederum eine sehr schlechte Bandbreite ergeben würde. Besser ist es, den TXT Record zu verwenden. Dieser kann 512 Bytes an Daten beinhalten. Da hier auch wieder nur normale ASCII Zeichen vorkommen dürfen (hier aber zwischen Groß- und Kleinschreibung unterschieden wird), werden die Nutzdaten per Base64 codiert.
Die Lösung: Ozymandns
Dan Kaminsky hat auf http://www.doxpara.com/ozymandns_src_0.1.tgz einen Satz von Perl Scripts zu Verfügung gestellt die das Tunneln über DNS übernehmen. Der Client ist “droute.pl”. Er nimmt von STDIN Daten, codiert diese mit Base32 und generiert daraus eine Domain, fügt eine Sequenznummer hinzu und stellt für diese eine DNS Anfrage auf den betreffenden TXT Record. Die Antwort kommt dann im TXT Record. Diese wird dekodiert und auf STDOUT ausgegeben. Der Server, nomde.pl funktioniert ähnlich: Er bildet einen DNS Server nach, der für eine bestimmte Domain (z.B. tunnel.nobaq.net) an Port 53 authoritiv antwortet. Normalerweise gibt ein DNS Server Antworten aus seiner Datenbank. Der DNS Server von ozymandns jedoch gibt die dekodierten Daten per STDOUT aus und holt sich die Antwort per STDIN.
Was man daraus machen kann ist simpel: Auf der Serverseite braucht man nur mehr ein Programm, das ähnlich wie Programme die über den inetd gestartet werden, die Daten von STDIN entgegen nimmt und die Ausgaben nach STDOUT schreibt. Standardmäßig öffnet “nomde.pl” einen ssh-Prozess (wenn die Domain den Präfix sshdns trägt) und leitet Ein- und Ausgabe passend um.
Auf der Clientseite bräuchte man dann nur mehr droute.pl starten und die Ein-/Ausgabe in ein Socket schreiben.
Für Linux ist die Gschicht' sehr einfach:
Der Server
Serverseitig braucht man nun einen Server mit statischer (!) IP Adresse. Das muss deswegen so sein, weil ein anderer DNS Server dann mittels NS Record delegieren muss. Dort horcht einfach nomde.pl an Port 53 und simuliert einen DNS Server:
./nomde.pl -i 193.154.229.55 .tunnel.nobaq.net.
Damit beantwortet der Server authoritiv alle DNS Fragen für die Domain .tunnel.nobaq.net. Als “secret” nimmt man am besten ein Passwort damit nicht jeder sofort den Tunnel nutzen kann ;-).
Der “-i” Parameter erwartet eine IP Adresse die einfach ausgegeben werden soll, wenn man die eine Anfrage auf einen A Record innerhalb der Domain stellt. Dieser ist für die Funktion nicht von Bedeutung und kann beliebig gewählt werden (z.B. auch 0.0.0.0). Ich nehme aber meine offizielle IP damit man bei der Falschen Anwahl wenigstens auf meinen Server kommt ;-)
Stellt man nun eine Anfrage auf einen TXT-Record, so wird testweise die aktuelle Zeit ausgegeben. Getestet werden sollte das gleich mit:
dig @statische-server-ip test.passwort.tunnel.nobaq.net. A
bzw.
dig @statische-server-ip test.passwort.tunnel.nobaq.net. TXT
ist jetzt “passwort” und “statische-server-ip” ist die IP Adresse des DNS Servers. Bekommt man bei diesen Tests (am besten von einem andren Rechner im Internet) die per “-i” angegebene IP Adresse bzw. die aktuelle Zeit beim TXT Record zurück, so ist der Serverpart fertig eingerichtet :-)
Nun muss man es noch schaffen, dass man, ohne den DNS Server direkt zu befragen, an die Daten kommt. Dafür muss man die Subdomain für die tunnel-Domain von der Parentdomain delegiert werden. Beispielsweise muss in der Zone für “nobaq.net.” stehen, dass die Subdomain “tunnel” an den Ozymandns Server delegiert werden soll. In der Zone für nobaq.net. steht dann z.B.:
tunnel IN NS 193.154.229.55
also die statische IP. Hat man keine eigene Domain mit voller Kontrolle über die Zone zu Verfügung, so nimmt man am besten “dnstunnel.de”. Dieser Service macht genau das: Er erstellt eine Subdomain und delegiert diese an die angegebene IP Adresse.
Der Client
Am Client braucht man jetzt nur mehr “droute.pl” starten:
./droute.pl -r DNS-Server-IP sshdns.passwort.tunnel.nobaq.net
Das Präfix “sshdns” weist den Server an, direkt eine SSH Session aufzubauen. Nach Eingabe dieses Befehls sollte bald der Gruß des SSH Servers kommen, z.B.: “SSH-1.99-OpenSSH_4.3p2 Debian-9″. Falls Fehlermeldungen kommen, müssen die passenden Libraries (z.B. von CPAN) nachinstalliert werden.
Um noch die vollständige SSH Session zu bekommen, weist man “ssh” an, als “Proxy” droute.pl zu verwenden: ssh schreibt nun die Daten die es senden will nach STDOUT, statt sie über ein Netzwerksocket zu senden und liest sie von STDIN, statt sie von einem Netzwerksocket zu empfangen:
ssh -o ProxyCommand="./droute.pl -r DNS-Server-IP sshdns.passwort.tunnel.nobaq.net" domain.invalid.
Soweit so gut, das funktioniert relativ einfach und gut unter optimalen Bedingungen (Root Server, statische IP, Port 53 noch nicht verwendet, kein Windows, …) und ist überall recht gut erklärt (z.B. unter dnstunnel.de). Wie man aber die andren Probleme beseitigt beschreibe ich im folgenden Artikel.
Kommentare
<comments />
Lisa Calighan meinte …
<comment date="2013-08-05T06:55:09Z" name="Lisa Calighan" url="http://www.herbrich.org"> Tolle Anleitung, kann ich auch mit ASP.NET auf einen Webspace Server ein DNS Tunnel machen um das RDP Session Protocol irgendwie über DNS zu tunneln? </comment>
Niki meinte …
<comment date="2013-08-05T17:34:05Z" name="Niki"> Ich befuercht leider nicht (falls du nur Webspace auf dem Server hast). Die Serverkomponente muesste als Prozess im Hintergrund laufen und macht auch einen Port auf (TCP/UDP 53). Darueber laesst dich RDP dann natuerlich schon tunneln.
Ich habe es selbst nie probiert nomde (die Serverkomponente) unter Windows laufen zu lassen, aber nachdem es Perl ist muesste es schon irgendwie gehen. </comment>
Lisa Calighan meinte …
<comment date="2013-08-11T23:18:11Z" name="Lisa Calighan" url="http://www.herbrich.org?coment=1&onPage=niki.hammler.info"> Hallo,
Es ist erstens nur ein Webspace, zweitens ist es aber auch mein Server, nur Port 53 ist etwas schwer, da läuft der DNS für meine ganzen Domains drauf. Giebt es da nen anderen weg, ich dache an einen HTTP Tunnel?? </comment>
Niki meinte …
<comment date="2013-08-13T22:01:47Z" name="Niki" signature="Niki"> Nein, leider nicht. DNS benoetigt zwingend 53. Ich hatte das gleiche Problem dass ich an einer IP bereits meinen offiziellen DNS hatte. Hab aber zum Glueck mehrere IPs.
Du koenntest sonst noch den ptunnel probieren, der tunnelt halt ueber ICMP und nicht DNS und deswegen ist die Wahrscheinlichkeit ungleich geringer dass du damit wo durchkommst. Manchmal ist aber ICMP offen, v.a. auf Kreuzfahrtsschiffen :)
www.cs.uit.no/~daniels/PingTunnel/ http://www.linuxscrew.com/2008/04/10/ptunnel-sendreceive-tcp-traffic-via-icmp-reliably/
</comment>
Leseratte10 meinte …
<comment date="2013-10-05T20:06:24Z" name="Leseratte10"> Das"Problem" mit dem besetzten Port 53 (BIND9 fürs Netzwerk) hatte ich auch - ich habe dann einfach auf dem Linux-Rechner dnsmasq installiert, OzymanDNS auf 10053 horchen lassen und BIND9 auf 20053, und habe dann in der /etc/dnsmasq.conf eingestellt, dass alle Anfragen für (Beispiel) "tunnel.nobaq.net" auf 127.0.0.1#10053 landen und alle anderen auf 127.0.0.1#20053.
Schon funktionieren OzymanDNS und ein beliebiger anderer DNS-Server gleichzeitig auf Port 53. </comment>
Niki meinte …
<comment date="2013-10-12T20:33:35Z" name="Niki"> @Leseratte10: Stimmt, danke, das hatte ich am Anfang auch so laufen!
Allerdings war mir das dann zu unreliable und umstaendlich. Da es sich um einen offiziellen DNS Server handelte (AFXR etc, non-/recursive Abfragen etc.). Ausserdem musste jede Zone "doppelt" in die Konfiguration von dnsmasq eingetragen werden was bei vielen Zonen umstaendlich ist.
Ich finde es schade, dass diese Weiterleitung mit bind nicht geht ... :( </comment>
Lemur meinte …
<comment date="2014-04-07T02:26:09Z" name="Lemur"> Die Sourcen liegen jetzt auf: http://s3.amazonaws.com/dmk/ozymandns_src_0.1.tgz
Grüße Lemur </comment>