Mitmproxy 11: vollständige HTTP/3-Unterstützung
(mitmproxy.org)- Da der Anteil von QUIC- und HTTP/3-Traffic wächst, erweitert mitmproxy 11 mit standardmäßig aktiviertem HTTP/3 den Analysebereich für modernen Web-Traffic
- HTTP/3 funktioniert nicht nur in transparenten Proxys und Reverse Proxys, sondern auch mit WireGuard und im local mode, sodass es sich in verschiedenen Capture-Umgebungen einsetzen lässt
- Chrome vertraut bei QUIC keiner vom Nutzer hinzugefügten Certificate Authority, daher muss man zwischen einem öffentlich vertrauenswürdigen Zertifikat, Kommandozeilen-Switches oder einem Fallback auf HTTP/2 wählen
- Die DNS-Implementierung wurde auf Hickory DNS umgestellt und behandelt Abfragen jenseits von A/AAAA, HTTPS records, DNS-over-TCP, die Steuerung der hosts-Datei sowie das Entfernen von ECH-Schlüsseln
- Privacy-Funktionen wie ECH erschweren den Zertifikatserzeugungs-Flow eines Man-in-the-Middle-Proxys, aber mitmproxy erhält durch Anpassung von DNS-Antworten die Funktionsfähigkeit aufrecht
Umfang der HTTP/3-Unterstützung
- mitmproxy 11 unterstützt HTTP/3 im transparenten Proxy- und im Reverse-Proxy-Modus
- Beim Reverse Proxy empfängt eine einzelne mitmproxy-Instanz sowohl TCP- als auch UDP-Pakete und verarbeitet die weitergeleitete HTTP-Version
- Beispielbefehl:
mitmproxy --mode reverse:https://http3.is
- Beispielbefehl:
- WireGuard und der local mode können ebenfalls HTTP/3 nutzen
- Beispielbefehle:
mitmproxy --mode wireguard mitmproxy --mode local
- Beispielbefehle:
- Tests mit Firefox, Chrome, verschiedenen cURL-Builds und anderen Clients verringern Kompatibilitätsprobleme
- Die Arbeit an der HTTP/3-Unterstützung wurde 2022 von Manuel Meitinger und Maximilian Hils begonnen und ist in mitmproxy 11 standardmäßig aktiviert
QUIC-Zertifikatseinschränkung in Chrome
- Die derzeit bekannte wichtigste Einschränkung ist, dass Chrome bei QUIC einer vom Nutzer hinzugefügten Certificate Authority nicht vertraut
- Um HTTP/3-Traffic in Chrome zu verarbeiten, ist eine der folgenden Optionen nötig
- Ein öffentlich vertrauenswürdiges Zertifikat wie von Let’s Encrypt bereitstellen
- Chrome mit den entsprechenden Kommandozeilen-Switches starten
- Das Fallback-Verhalten auf HTTP/2 akzeptieren
- Firefox zeigt dieses Verhalten nicht
- Tipps zur Fehlerbehebung bei HTTP/3-Problemen gibt es unter #7025
Neuimplementierung auf Basis von Hickory DNS
- Mit dem Aufkommen von Privacy-Funktionen wie DNS HTTPS records und Encrypted Client Hello(ECH) ist die Bedeutung der DNS-Verarbeitung in mitmproxy gestiegen
- Die bisherige DNS-Implementierung nutzte
getaddrinfound hatte dadurch Einschränkungen- Sie unterstützte nur A/AAAA-Abfragen für IPv4- und IPv6-Adressen
- Sie konnte nicht auf Abfragen wie HTTPS records antworten, die HTTP/3-Unterstützung signalisieren
- mitmproxy 11 implementiert die DNS-Unterstützung neu auf Basis von Hickory DNS, einer Rust-basierten DNS-Bibliothek
- Über Hickory werden unter Windows, Linux und macOS die Standard-Nameserver des Betriebssystems ermittelt, und Nicht-A/AAAA-Abfragen werden an diese Nameserver weitergeleitet
- Mit der neuen Option
dns_name_serverslassen sich die Ziel-Nameserver für die Weiterleitung festlegenmitmdump --mode dns --set dns_name_servers=8.8.8.8
Steuerung der hosts-Datei und DNS-over-TCP
- Mit der Umstellung auf Hickory wurde eine Option hinzugefügt, um die systemweite hosts-Datei zu ignorieren
- Mit der neuen Option
dns_use_hosts_filelässt sich steuern, ob eine hosts-Datei wie/etc/hostsunter Linux berücksichtigt wird - Auch die interne DNS-Auflösung von mitmproxy soll auf Hickory umgestellt werden; danach wird diese Funktion nützlich, wenn bestimmte Domains auf derselben Maschine transparent umgeleitet werden
- Derzeit wird die hosts-Datei immer berücksichtigt, sodass mitmproxy bei Redirect-Konfigurationen auf derselben Maschine rekursiv eine Verbindung zu sich selbst aufbauen kann
- Beispielverhalten:
echo "192.0.2.1 mitmproxy.org" >> /etc/hosts mitmdump --mode dns dig @127.0.0.1 +short mitmproxy.org 192.0.2.1 mitmdump --mode dns --set dns_use_hosts_file=false dig @127.0.0.1 +short mitmproxy.org 3.161.82.13 - DNS verwendet standardmäßig UDP, doch für Records, die nicht in ein einzelnes UDP-Paket passen, kann TCP nötig sein
- Da mitmproxy 11 beliebige Abfragetypen unterstützt, sind Nachrichtengröße und TCP-Verarbeitung wichtiger geworden; auch DNS-over-TCP funktioniert
Entfernen von ECH-Schlüsseln und Zertifikatserzeugung
- Wenn kein nutzerdefiniertes Zertifikat vorhanden ist, verwendet mitmproxy die Server Name Indication(SNI) aus dem TLS ClientHello, um ein gültiges Zertifikat zu erstellen
- Ohne SNI kann es sein, dass kein Zertifikat erzeugt werden kann, dem der Client vertraut
- Encrypted Client Hello(ECH) funktioniert so, dass der Client über DNS HTTPS records einen ECH-Schlüssel erhält und anschließend die anfängliche ClientHello-Handshake-Nachricht mit diesem Schlüssel verschlüsselt
- Wenn sowohl DNS-Abfrage als auch Handshake verschlüsselt sind, kann ein passiver Man-in-the-Middle die Zieldomain nicht erkennen und sieht nur die Ziel-IP-Adresse
- Bei Shared Hosting und Content Delivery Networks lässt sich die Zieldomain allein anhand der IP-Adresse nur schwer bestimmen
- Diese Privacy-Verbesserung kollidiert mit der Art, wie mitmproxy Zertifikate erzeugt
- mitmproxy 11 entfernt ECH-Schlüssel aus HTTPS records, um die für die Zertifikatserzeugung nötigen Domaininformationen zu erhalten
- Der Client erhält keinen Schlüssel zum Verschlüsseln der anfänglichen Handshake-Nachricht
- mitmproxy kann die Zieldomain erkennen und ein passendes Zertifikat erstellen
- ECH kann die Nutzung von mitmproxy erschweren, ist aber als Veränderung zu sehen, die die Privacy im Web insgesamt erhöht
1 Kommentare
Meinungen auf Hacker News
Schön zu sehen, dass Mitmproxy noch weiterentwickelt wird. Dieses Tool hat indirekt meine Karriere geprägt.
2011 lernte ich API-Entwicklung, indem ich Requests mobiler Apps abfing, und entdeckte dabei, dass die Airbnb-API für eine Rails-Mass-Assignment-Schwachstelle (https://github.com/rails/rails/issues/5228) anfällig war. Nachdem ich ein paar harmlose Attribute geändert hatte, kontaktierte ich das Unternehmen; daraus wurde ein Vorstellungsgespräch, und der Rest ist buchstäblich Geschichte.
Manchmal ist es einfacher, mit mitmproxy eine bestehende Implementierung zu untersuchen, als die Dokumentation zu lesen.
Interessant ist, dass Chrome bei QUIC keine vom Nutzer hinzugefügten Zertifizierungsstellen vertraut.
Im verlinkten Issue sagt das Chrome-Team: „Wir erlauben nicht ausdrücklich öffentlich nicht vertrauenswürdige Zertifikate, um die Verbreitung von Software/Hardware zum Abfangen von QUIC zu verhindern. Andernfalls würde das langfristig die Evolvierbarkeit des QUIC-Protokolls beeinträchtigen. Anwendungsfälle, die auf Zertifikate angewiesen sind, die nicht öffentlich vertrauenswürdig sind, können TLS+TCP statt QUIC verwenden.“
Ich verfolge die Protokollentwicklung nicht, aber mir ist nicht ganz klar, wie das Blockieren benutzerdefinierter Zertifikate mit Evolvierbarkeit zusammenhängt. Weiß jemand den Grund?
Sie können eine leicht modifizierte QUIC-Version in Chrome einbauen, sie an Orten wie Youtube unterstützen und dann auf Basis dieser Metriken eine „echte“ Standardänderung vorschlagen oder die Spezialversion nur in ihren eigenen Diensten weiter betreiben.
Wenn benutzerdefinierte Zertifikate erlaubt wären, bestünde das Risiko, dass Unternehmen, die den Traffic ihrer Mitarbeiter mit Dingen wie ZScaler ZIA per Man-in-the-Middle inspizieren, bei Protokolländerungen kaputtgehen. Wenn der Datenstrom vollständig verschlüsselt und für Middleboxes undurchsichtig ist, kann Google im Grunde fast tun, was es will.
Verwandtes Konzept: https://en.wikipedia.org/wiki/Protocol_ossification
Bei erweiterbaren Protokollen müssen normalerweise nur Client und Server aktualisiert werden, aber mit Middleboxes müssen potenziell auch N Geräte mit aktualisiert werden. Nutzer und Serviceanbieter haben einen Anreiz, neue Funktionen einzuführen, die Besitzer von Middleboxes möglicherweise nicht. Dadurch wird die Weiterentwicklung eines Protokolls schwierig.
Es gab viel Middleware, die stark von Implementierungsdetails abhing, sodass kleine Änderungen leicht unbeabsichtigt die Nutzererfahrung kaputtmachen konnten. Bei der neuen Version scheint man ähnliche Situationen vermeiden zu wollen.
Ich frage mich, ob HTTP/2 oder HTTP/3 einen Vorteil bringt, wenn es nur im Reverse Proxy unterstützt wird und nicht im eigentlichen Webserver.
Die meisten Mainstream-Frameworks in JS/Python/Ruby unterstützen die neuen HTTP-Standards nicht. Wird der Webserver dann nicht zum Flaschenhals der Reverse-Proxy-Verbindung?
Die Verbindung zwischen Reverse Proxy und dem eigentlichen Webserver ist in der Regel deutlich schneller und stabiler, daher ist der Nutzen eines Upgrades dieses Abschnitts auf HTTP/2 oder HTTP/3 viel geringer.
Selbst wenn HTTP verwendet wird, kann der Reverse Proxy deutlich schneller Verbindungen zum Backend aufbauen als zum tatsächlichen Remote-Client. Deshalb ist es weiterhin vorteilhaft, auf dem langsamen Abschnitt HTTP/2-Streams zu verwenden.
Es ist ein Tool, das man lokal ausführt, um Low-Level-Protokolle oder Web-Security-Themen zu testen.
Ab HTTP/2 werden mehrere gleichzeitige Requests über eine einzige Verbindung abgewickelt.
Es gibt weiterhin das Problem des Fingerprintings. Solange man den TLS-Handshake eines typischen Browsers nicht nachahmen kann, sieht man auf etwa 80 % des Webs Seiten wie „Just a quick check...“ oder „Sorry, it looks like you're a bot“.
https://github.com/mitmproxy/mitmproxy/issues/4575
Danke für die Erwähnung von Hickory. Es ist immer spannend zu sehen, was Leute damit bauen, und das ist gut gemachte Arbeit.
Solche Dinge wären mit reinem Python ursprünglich schwer zu erreichen gewesen.
Ich frage mich, ob man Mitmproxy ähnlich wie Privoxy/Proxomitron/Yarip verwenden kann.
Könnte man zum Beispiel beim Browsen mit Ungoogled Chromium Mitmproxy als Proxy einsetzen und die script-Tags bestimmter Websites entfernen? Welche Auswirkungen hätte das auf die Performance?
Beim Anzeigen einer Webseite können sich kleine Verzögerungen hunderte Male summieren und spürbar werden.
Trotzdem kann es für Leute, die an so einem Einsatzzweck interessiert sind, eine Option sein. Technisch spricht nichts dagegen.
Beim Umschreiben von JavaScript-Dateien besteht ein kleines Risiko, Subresource-Integrity-Prüfungen zu beeinträchtigen, aber wenn das tatsächlich zum Problem wird, könnte man vermutlich auch die Hashes neu schreiben.
Kann mitmproxy eine Alternative zu Fiddler sein?
https://docs.mitmproxy.org/stable/addons-overview/
Hm: https://github.com/mitmproxy/mitmproxy/issues/4170