3 Punkte von GN⁺ 2024-10-06 | 1 Kommentare | Auf WhatsApp teilen
  • 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
  • WireGuard und der local mode können ebenfalls HTTP/3 nutzen
    • Beispielbefehle:
      mitmproxy --mode wireguard
      mitmproxy --mode local
      
  • 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 getaddrinfo und 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_servers lassen sich die Ziel-Nameserver für die Weiterleitung festlegen
    mitmdump --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_file lässt sich steuern, ob eine hosts-Datei wie /etc/hosts unter 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

 
GN⁺ 2024-10-06
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.

    • Es war wirklich absurd, wie viele Core-Entwickler in diesem Issue gegen die Änderung waren.
    • Für mich ist es bis heute enorm nützlich, aber erstaunlich viele Leute, die es eigentlich kennen müssten, wissen kaum etwas über Mitmproxy.
      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?

    • Meine Vermutung: Weil Google sowohl den Client als auch große Server-Endpunkte (Google Search, Youtube usw.) kontrolliert, wollen sie frei mit QUIC-Änderungen experimentieren können.
      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
    • Middleboxes (https://en.m.wikipedia.org/wiki/Middlebox) sind eine bekannte Ursache für Protokollverknöcherung.
      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.
    • Gemeint sein könnte auch der bekannte Fall, dass Finanzinstitute gegen TLS 1.3 waren. Die Motivation war, dass sie die für Compliance nötige Man-in-the-Middle-Software nicht aktualisieren wollten: https://mailarchive.ietf.org/arch/msg/tls/CzjJB1g0uFypY8UDdr6P9SCQBqA/
    • Einer der Gründe für HTTP/2 und HTTP/3 war ebenfalls, dass Änderungen an HTTP 1.1 zu schwierig waren.
      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.
    • QUIC existiert, um die Auslieferungsrate von Werbung zu erhöhen; den Nutzern Freiheit zu geben, steht diesem Ziel entgegen.
  • 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?

    • Ja. HTTP/2 oder HTTP/3 erhöhen die Zuverlässigkeit der Verbindung zwischen Client und Reverse Proxy.
      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.
    • Der Transport zwischen Reverse Proxy und Backend ist auch nicht immer HTTP. Python nutzt zum Beispiel mitunter uWSGI, PHP FastCGI.
      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.
    • Wahrscheinlich ist das hier nicht so wichtig, aber mitmproxy ist kein Reverse Proxy für Produktionsumgebungen.
      Es ist ein Tool, das man lokal ausführt, um Low-Level-Protokolle oder Web-Security-Themen zu testen.
    • Ein Punkt fehlt noch: Webbrowser begrenzen die Zahl der Verbindungen pro Domain auf 6.
      Ab HTTP/2 werden mehrere gleichzeitige Requests über eine einzige Verbindung abgewickelt.
    • Ja. Es gibt auch andere Performance-Vorteile, aber HTTP/3 kombiniert den TCP- und TLS-Handshake und spart beim Verbindungsaufbau eine Round-Trip-Zeit.
  • 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

    • Dann ist Firefox wohl kein typischer Browser mehr.
  • Danke für die Erwähnung von Hickory. Es ist immer spannend zu sehen, was Leute damit bauen, und das ist gut gemachte Arbeit.

    • Danke für die Arbeit an Hickory. Durch die Python↔Rust-Interoperabilität von PyO3 ist es wirklich interessant geworden, produktionsreife DNS-Libraries wie Hickory und robuste Userspace-Networking-Stacks wie smoltcp aus Python heraus nutzen zu können.
      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?

    • Theoretisch ja. In der Praxis ist mitmproxy in Python geschrieben, und da die Sprache nicht besonders schnell ist, entsteht Latenz.
      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?

  • Hm: https://github.com/mitmproxy/mitmproxy/issues/4170