Im Internet kursiert die weitverbreitete Meinung, dass ein einfaches Umstellen auf einen freien Domain-Name-Server das Problem der Zensursula beseitigt. Es wird regelrecht als das Allheilmittel im Kampf gegen die Zensur in Deutschland angepriesen, weshalb ich angefangen habe mich mit diesem Thema etwas genauer auseinander zu setzen.
Vielen ist nicht bewusst, dass es Problemlos möglich ist bestimmte Anfragen einfach umzuleiten. Solche Methoden kennt man zum Beispiel von transparenten Proxys. Für Alle welche nicht Wissen was Das ist: Transparenter_Proxy
Zunächst werden am Router die gewünschten Ports der Protokolle abgegriffen … und dann an einen Proxy weitergeleitet. Für den Anwender ist die Verbindung über einen transparenten Proxy in der Benutzung nicht von einer direkten Verbindung über den Router zu unterscheiden.
In UMTS Netzen wie von T-Mobile und Vodafone sind solche Proxys seit vielen Jahren schon Standard. Es wäre also ein leichtes auch Anfragen auf Port 53 UDP (DNS) auf einen eigenen Zensurserver umzuleiten. Gerüchten nach soll Vodafone im UMTS Netz DNS Anfragen seit Juni 2009 schon auf eigene Server umleiten. Selbst wenn dem nicht so ist, kann man davon ausgehen, dass auf Kurz oder Lang solche Portumleitungen zum Standard werden um die Zensur durchzusetzen.
Mögliche Lösungen des Problems
DNS über alternative Ports
Eine sehr einfache Lösung des Problems wäre die DNS Server einfach über einen anderen Port abzufragen. Auf der Seite von German Privacy Foundation sind einige DNS Server aufgelistet welche Anfragen über den Port 110 (POP3) entgegen nehmen. Auf den ersten Blick ist es eine gute Lösung, auf dem zweiten jedoch auf Dauer nutzlos. Warum? Ganz einfach. DNS Server sprechen standardmäßig über UDP nicht über TCP wie POP3 und die meisten anderen Protokolle. Die Verwendung von Port 110 UDP würde sehr schnell auffallen und könnte ohne POP3 negativ zu beeinflussen ebenfalls umgeleitet oder gesperrt werden. Wenn man schon einen alternativen Port verwendet, dann sollte man doch bitte wenigstens soweit mitdenken, dass man einen Port nehmen muss welcher auch häufig über UDP genutzt wird (z.B. SIP 5060 oder SIP-TLS 5061).
Selbst wenn man einen Port verwendet welcher breite Verwendung über UDP findet, könnte man durch Stichproben im Traffic auf diesen Ports die Verwendung als DNS erkennen und den Traffic auf diese IP automatisch Umleiten.
DNS über https
Eine weitere Lösung welche ebenfalls bei German Privacy Foundation zu lesen ist, beschreibt den Transport von DNS als html über https (später hoffentlich xml).
Zugegeben eine wirklich gute Lösung welche auch kaum detektierbar und simpel auf jedem Webserver einzurichten ist. Somit könnte jeder Seitenbetreiber mal eben einen DNS Proxy über https aufsetzen, insofern sein Server einen unkompromittierten DNS abfragen kann.
Was mir persönlich nicht gefällt ist, dass es sich nicht mehr um echte DNS Anfragen handelt und somit ohne großen Programmieraufwand nicht alles darüber möglich sein wird. Ich finde das man dies viel einfacher Lösen könnte, in dem man einfach den DNS Traffic an sich über http/SSL umleitet oder verpackt.
Insgesamt jedoch eine gelungene Lösung. Vielleicht setze ich mich auch eines Tages hin und entwickle einen xml Client-Daemon :-).
DNS über SSL Tunnel
Mein persönlicher Favorit ist das Tunneln von echten DNS Anfragen über SSL. Das Hauptproblem hierbei ist, dass DNS (meistens) nun mal über UDP und nicht über TCP transportiert wird.
Mein Erster Versuchsaufbau war ein SSL Tunnel über TCP Port 443. Als Tool kam hierfür die Software stunnel zum Einsatz. Das Ganze funzt ausgesprochen gut und ist wahnsinnig schnell für SSL! Der einzige und wohl auch gravierende Nachtteil ist das man auf die Art den DNS Server nur per TCP ansprechen kann.
Mit Tools wie dig ist es kein Problem TCP für DNS zu erzwingen. Hier eine Beispielanfrage über meinen Tunnel:
[Christian-MBP:~] christian% dig -4 +tcp krasseszeug.de @localhost
; <<>> DiG 9.6.0-APPLE-P2 <<>> -4 +tcp krasseszeug.de @localhost
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1203
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 0
;; QUESTION SECTION:
;krasseszeug.de. IN A
;; ANSWER SECTION:
krasseszeug.de. 10800 IN A 94.23.193.80
;; AUTHORITY SECTION:
krasseszeug.de. 10800 IN NS sdns1.ovh.net.
krasseszeug.de. 10800 IN NS rps8392.ovh.net.
;; Query time: 255 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sat Sep 26 12:37:17 2009
;; MSG SIZE rcvd: 97
Entweder man bringt nun dem Resolver des Betriebsystems bei immer per TCP anzufragen, oder man installiert zusätzlich einen DNS Cache welcher über tcp anfragt und per tcp und udp das Ganze dem OS zur Verfügung stellt. Letzteres müsste mit einem einfachen Patch von dnscache möglich sein.
Dem Resolver des Betriebsystems beizubringen immer per TCP anzufragen wäre jedoch die einfachere Lösung. Leider habe ich bisher nicht herausgefunden wie man unter Linux, MacOS oder Windows dies bewerkstelligt. Über Infos zu diesem Thema würde ich mich sehr freuen.
Ich habe noch zu Hauff weitere Tests mit TCP -> UDP Proxys und UDP Tunnel wie netcat, udptunnel, socat und zedebee unternommen. Das Beste Ergebnis hatte ich hier bisher mit socat. Leider bekomme ich es bisher nicht stabil für viele Anfragen zum Laufen. Socat baut mir bei SSL immer schon im voraus einen Tunnel, welcher auf Anfragen wartet und nicht erst für die Anfrage selbst aufgebaut wird. Ich werde mich mit socat noch ein paar h befassen und versuchen das Problem zu Lösen.
Meine derzeitigen Versuche mit Socat sehen so aus:
Server: socat -ls -d -d OPENSSL-LISTEN:443,bind=serverIP,method=SSLv3,reuseaddr,pf=ip4,fork,key=/etc/stunnel/dns-key.pem,cert=/etc/stunnel/dns.pem,verify=0 UDP:127.0.0.1:53
Client: socat -ls -d -d OPENSSL:serverIP:443,method=SSLv3,reuseaddr,pf=ip4,verify=0,fork udp4-listen:53,reuseaddr
Meine stunnel Konfiguration für TCP-DNS über SSL
Server:
cert = /etc/stunnel/dns.pem
key = /etc/stunnel/dns-key.pem
sslVersion = SSLv3
chroot = /var/lib/stunnel4/
setuid = stunnel4
setgid = stunnel4
pid = /stunnel4.pid
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1
debug = 7
syslog = no
output = /var/log/stunnel4/dns.log
foreground = yes
[dns]
accept = serverIP:443
connect = 53
session = 10
TIMEOUTbusy = 10
TIMEOUTclose = 10
TIMEOUTidle = 15
Client:
sslVersion = SSLv3
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1
debug = 7
output = /var/log/stunnel.log
syslog = no
foreground = yes
client = yes
[dns]
accept = 53
connect = serverIP:443
Ein erfolgreicher Query per TCP auf dem Client erfolgt zum Beispiel mit dig +tcp hostname @localhost.