Einleitung
Moderne Content-Filter-Systeme für Unternehmen von namhaften Herstellern wie Cisco, BlueCoat und FireEye haben viel gemeinsam mit ihren leistungsstärkeren Gegenstücken - DPI-Systemen, die auf nationaler Ebene intensiv implementiert werden. In beiden Fällen geht es darum, nach eingehendem und ausgehendem Internetverkehr zu suchen und auf der Grundlage von Black- / White-Listen zu entscheiden, ob die Internetverbindung gesperrt werden soll. Und da sich beide in den Grundlagen ihrer Arbeit auf ähnliche Prinzipien stützen, werden die Möglichkeiten, sie zu umgehen, auch vieles gemeinsam haben.
Eine der Technologien, mit denen DPI- und Unternehmenssysteme effizient umgangen werden können, ist die domänenorientierte Technologie. Die Essenz liegt in der Tatsache, dass wir zu einer gesperrten Ressource gehen, die sich hinter einer anderen gemeinfreien Domain mit einem guten Ruf versteckt und die offensichtlich von keinem System wie google.com gesperrt wird.
Es wurden bereits viele Artikel über diese Technologie geschrieben und viele Beispiele angeführt. DNS-over-HTTPS- und verschlüsselte SNI-Technologien sowie die kürzlich diskutierten Technologien und die neue Version des TLS 1.3-Protokolls bieten jedoch die Möglichkeit, eine andere Variante des Domain-Front-Facing in Betracht zu ziehen.
Wir beschäftigen uns mit Technologie
Lassen Sie uns zunächst ein wenig über die grundlegenden Konzepte entscheiden, damit jeder versteht, wer wer ist und warum dies alles benötigt wird. Wir haben den eSNI-Mechanismus erwähnt, dessen Arbeit später erörtert wird. Der eSNI-Mechanismus (Encrypted Server Name Indication) ist eine sichere Version von SNI, die nur für das TLS 1.3-Protokoll verfügbar ist. Der Hauptpunkt ist die Verschlüsselung, einschließlich der Information, an welche Domain die Anfrage gesendet wird.
Schauen wir uns nun an, wie der eSNI-Mechanismus in der Praxis funktioniert.
Nehmen wir an, wir haben eine Internet-Ressource, die von einer modernen DPI-Lösung blockiert wird (zum Beispiel der berühmte Torrent-Tracker - rutracker.nl). Wenn wir versuchen, auf die Site des Torrent-Trackers zuzugreifen, sehen wir den Standard-Stub des Anbieters, der die Ressource blockiert:

Auf der ILV-Website ist diese Domain in der Tat in den Stopplisten aufgeführt:

Wenn Sie whois anfordern, können Sie sehen, dass die Domain selbst hinter dem Cloud-Anbieter Cloudflare „versteckt“ ist.

Aber im Gegensatz zu den „Spezialisten“ von ILV haben die technisch versierteren beeline-Mitarbeiter (oder die bitteren Erfahrungen unserer berühmten Aufsichtsbehörde) die Website nicht dumm nach IP-Adresse gesperrt, sondern den Domainnamen in die Sperrliste eingetragen. Dies ist leicht zu überprüfen, wenn Sie sich ansehen, welche anderen Domänen sich hinter derselben IP-Adresse verstecken, eine von ihnen besuchen und feststellen, dass der Zugriff nicht blockiert ist:

Aber wie kommt es dazu? Wie erfährt der Anbieter DPI, zu welcher Domain mein Browser wechselt, da die gesamte Kommunikation über das https-Protokoll erfolgt und wir die Ersetzung von https-Zertifikaten von beeline noch nicht bemerkt zu haben scheinen? Ist er hellsichtig oder wird er von mir verfolgt?
Versuchen wir, diese Frage zu beantworten, indem wir den Verkehr durch Wireshark betrachten

Der Screenshot zeigt, dass zuerst der Browser die IP-Adresse des Servers über DNS empfängt, dann ein standardmäßiger TCP-Handshake mit dem Zielserver stattfindet und dann versucht der Browser, eine SSL-Verbindung zum Server herzustellen. Dazu sendet es das SSL-Client-Hello-Paket, das den Quelldomänennamen in Klartext enthält. Dieses Feld wird vom Cloudflare-Front-End-Server benötigt, um die Verbindung ordnungsgemäß weiterzuleiten. Hier fängt uns der Anbieter DPI auf und unterbricht unsere Verbindung. Gleichzeitig erhalten wir keinen Stub vom Anbieter und es wird ein Standardbrowserfehler angezeigt, als ob die Site getrennt worden wäre oder einfach nicht funktioniert:

Lassen Sie uns nun den eSNI-Mechanismus im Browser aktivieren, wie in den Anweisungen für
Firefox beschrieben :
Dazu öffnen wir die Firefox-Konfigurationsseite
about: config und aktivieren die folgenden Einstellungen:
network.trr.mode = 2; network.trr.uri = https://mozilla.cloudflare-dns.com/dns-query network.security.esni.enabled = true
Danach werden wir die Richtigkeit der Einstellungen auf der Cloudflare-Website über den
Link überprüfen und den Fokus mit unserem Torrent-Tracker erneut versuchen.

Voila. Unser Lieblingstracker wurde ohne VPNs oder Proxys geöffnet. Schauen wir uns jetzt die Müllkippe in Wireshark an, was passiert ist.

Dieses Mal enthält das SSL-Client-Hallo-Paket nicht explizit die Zieldomäne, sondern ein neues Feld im Paket - verschlüsselter_Servername -. Hier ist der Wert von rutracker.nl enthalten, und nur der Front-End-Cloudflare-Server kann dieses Feld entschlüsseln. Und wenn ja, dann hat der Anbieter DPI keine andere Wahl, als sich die Hände zu waschen und solchen Verkehr zuzulassen. Es gibt jedoch keine anderen Optionen für die Verschlüsselung.
Also, wie die Technologie im Browser funktioniert - wir haben nachgesehen. Versuchen wir nun, es auf spezifischere und interessantere Dinge anzuwenden. Und für den Anfang werden wir dieselbe Locke beibringen, eSNI für die Arbeit mit TLS 1.3 zu verwenden, und gleichzeitig werden wir sehen, wie die auf eSNI basierende Front-End-Domain selbst funktioniert.
Domain Frontend mit eSNI
Da curl für die Verbindung über https die Standard-OpenSSL-Bibliothek verwendet, müssen wir dort zunächst eSNI-Unterstützung bereitstellen. Es gibt noch keine Unterstützung für eSNI in den OpenSSL-Master-Zweigen. Daher müssen wir den speziellen OpenSSL-Zweig herunterladen, kompilieren und installieren.
Wir klonen das Repository vom Github und kompilieren wie gewohnt:
$ git clone https://github.com/sftcd/openssl $ cd openssl $ ./config $ make $ cd esnistuff $ make
Als Nächstes klonen wir das Repository mit curl und konfigurieren seine Kompilierung mithilfe unserer assemblierten openssl-Bibliothek:
$ cd $HOME/code $ git clone https://github.com/niallor/curl.git curl-esni $ cd curl-esni $ export LD_LIBRARY_PATH=/opt/openssl $ ./buildconf $ LDFLAGS="-L/opt/openssl" ./configure --with-ssl=/opt/openssl --enable-esni --enable-debug
Es ist wichtig, alle Verzeichnisse, in denen sich openssl befindet, korrekt anzugeben (in unserem Fall / opt / openssl /) und sicherzustellen, dass der Konfigurationsprozess fehlerfrei verläuft.
Bei erfolgreicher Konfiguration sehen wir die Zeile:
WARNUNG: esni ESNI aktiviert, aber als EXPERIMENTAL markiert. Mit Vorsicht verwenden! $ make
Nach dem erfolgreichen Erstellen des Pakets verwenden wir eine spezielle openssl-Bash-Datei, um curl zu konfigurieren und auszuführen. Kopieren Sie es zur Vereinfachung mit curl in das Verzeichnis:
cp /opt/openssl/esnistuff/curl-esni
Führen Sie eine Test-https-Anfrage an den Cloudflare-Server aus und schreiben Sie gleichzeitig DNS- und TLS-Pakete an Wireshark.
$ ESNI_COVER="www.hello-rkn.ru" ./curl-esni https://cloudflare.com/
In der Antwort des Servers erhalten wir neben vielen Debugging-Informationen von openssl und curl eine HTTP-Antwort mit dem Code 301 von cloudflare.
HTTP/1.1 301 Moved Permanently < Date: Sun, 03 Nov 2019 13:12:55 GMT < Transfer-Encoding: chunked < Connection: keep-alive < Cache-Control: max-age=3600 < Expires: Sun, 03 Nov 2019 14:12:55 GMT < Location: https://www.cloudflare.com/
Dies zeigt an, dass unsere Anfrage erfolgreich an den Zielserver gesendet, gehört und verarbeitet wurde.
Schauen wir uns nun den Verkehrsdump in Wireshark an, d.h. was der Anbieter DPI in diesem Fall gesehen hat.

Es ist zu sehen, dass sich die erste Locke an den DNS-Server wandte, um den öffentlichen eSNI-Schlüssel für den Cloudflare-Server zu erhalten - TXT-DNS-Anforderung an _esni.cloudflare.com (Paket Nr. 13). Anschließend sendete curl unter Verwendung der openssl-Bibliothek eine TLS 1.3-Anfrage an den Cloudflare-Server, auf dem das SNI-Feld mit dem im vorherigen Schritt erhaltenen öffentlichen Schlüssel (Paket Nr. 22) verschlüsselt wurde.
Zusätzlich zum eSNI-Feld wurde im Rahmen des SSL-hallo-Pakets ein Feld mit der üblichen offenen SNI eingefügt, die wir in beliebiger Reihenfolge angeben können (in diesem Fall - www.hello-rkn.ru ).Dieses Feld des offenen SNI wurde bei der Verarbeitung durch Cloudflare-Server nicht berücksichtigt und war nur eine Tarnung für den Anbieter DPI. Der Cloudflare-Server hat unser ssl-hello-Paket erhalten, den eSNI entschlüsselt, den ursprünglichen SNI daraus extrahiert und verarbeitet, als wäre nichts passiert (er hat alles genau so gemacht, wie es bei der Entwicklung von eSNI geplant war).
Das einzige, woran Sie sich in diesem Fall in Bezug auf DPI festhalten können - die primäre DNS-Abfrage unter _esni.cloudflare.com. Wir haben die DNS-Abfrage jedoch nur geöffnet, um zu zeigen, wie dieser Mechanismus von innen funktioniert.
Um den Boden unter dem DPI endgültig auszuschalten, verwenden wir den bereits erwähnten DNS-over-HTTPS-Mechanismus. Eine kleine Erklärung - DOH - ein Protokoll, mit dem Sie sich vor einem Mann im mittleren Angriff schützen können, indem Sie eine DNS-Abfrage über HTTPS senden.
Wir werden die Anfrage erneut ausführen, aber dieses Mal erhalten wir die öffentlichen eSNI-Schlüssel über das https-Protokoll und nicht über das DNS:
ESNI_COVER="www.hello-rkn.ru" DOH_URL=https://mozilla.cloudflare-dns.com/dns-query ./curl-esni https://cloudflare.com/
Der Request Traffic Dump ist im folgenden Screenshot dargestellt:

Es ist zu erkennen, dass curl zuerst über das DoH-Protokoll (https-Verbindung zum Server 104.16.249.249) auf den Server mozilla.cloudflare-dns.com zugreift, um die Werte des öffentlichen Schlüssels für die SNI-Verschlüsselung abzurufen, und dann auf den unter der Domäne versteckten Zielserver
www.hello-rkn.ru .
Neben dem oben angegebenen mozilla.cloudflare-dns.com-Resolver DoH können wir auch andere beliebte DoH-Dienste verwenden, beispielsweise vom berühmten bösen Konzern.
Wir führen folgende Anfrage aus:
ESNI_COVER="www.kremlin.ru" DOH_URL=https://dns.google/dns-query ./curl-esni https://rutracker.nl/
Und wir bekommen die Antwort:
< HTTP/1.1 301 Moved Permanently < Date: Sun, 03 Nov 2019 14:10:22 GMT < Content-Type: text/html < Transfer-Encoding: chunked < Connection: keep-alive < Set-Cookie: __cfduid=da0144d982437e77b0b37af7d00438b1a1572790222; expires=Mon, 02-Nov-20 14:10:22 GMT; path=/; domain=.rutracker.nl; HttpOnly; Secure < Location: https://rutracker.nl/forum/index.php < CF-Cache-Status: DYNAMIC < Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct" < Server: cloudflare < CF-RAY: 52feee696f42d891-CPH

In diesem Fall haben wir uns mit dem dns.google DoH-Resolver an den blockierten Server rutracker.nl gewandt (es gibt keinen Tippfehler, jetzt hat das berühmte Unternehmen eine eigene First-Level-Domain) und uns mit einer anderen Domain abgedeckt, deren Blockierung von allen DPI strengstens untersagt ist aus Angst vor der Todesstrafe. Anhand der Antwort können Sie nachvollziehen, dass unsere Anfrage erfolgreich bearbeitet wurde.
Als zusätzliche Überprüfung, dass der Anbieter DPI auf ein offenes SNI reagiert, das wir als Deckung übergeben, können wir eine Anfrage an rutracker.nl hinter einer anderen verbotenen Ressource ausführen, zum Beispiel einem anderen „guten“ Torrent-Tracker:
$ ESNI_COVER="rutor.info" DOH_URL=https://dns.google/dns-query ./curl-esni https://rutracker.nl/
Wir erhalten keine Antwort vom Server, wie Unsere Anfrage wird vom DPI-System blockiert.
Ein kleiner Abschluss zum ersten Teil
So konnten wir mit openssl und curl den Zustand von eSNI nachweisen und die Funktionsweise des domänenbasierten Frontends auf Basis von eSNI testen. Auf die gleiche Weise können wir unsere Lieblingstools mithilfe der openssl-Bibliothek so anpassen, dass sie unter dem Deckmantel anderer Domänen arbeiten. Mehr dazu in unseren nächsten Artikeln.