Saltar al contenido principal
de/blog/obscura/research/mitm-approaches/

obscura/research/mitm-approaches

3 Min. Lesezeit

Übersicht

Obscura benötigt einen MitM (Man-in-the-Middle)-Proxy, um HTTPS-Datenverkehr abzufangen und zu modifizieren. Dieses Dokument bewertet die verfügbaren Optionen.

Ansätze

Ansatz 1: Go mitmproxy-Bibliothek

Bibliothek: github.com/elazarl/goproxy

Vorteile:

  • Ausgereift, gut getestet
  • Behandelt CONNECT-Tunnel automatisch
  • Unterstützt Antwortmodifikation
  • MITM mit On-the-Fly-Zertifikatserstellung

Nachteile:

  • HTTP/2-Unterstützung ist eingeschränkt
  • Großer Abhängigkeitsbaum
  • Nicht für transparente Proxys ausgelegt

Ansatz 2: Eigener Rust-Proxy mit tokio + rustls

Vorteile:

  • Vollständige Kontrolle über TLS-Stack
  • Leistung (Zero-Cost-Abstractions)
  • tokio-rustls für TLS-Terminierung
  • Hyper für HTTP/1 und HTTP/2
  • Kann utls für TLS-Fingerprint-Spoofing integrieren

Nachteile:

  • Höherer Entwicklungsaufwand
  • Zertifikatserstellung muss manuell erfolgen
  • HTTP/2-Frame-Level-Parsing erforderlich

Ansatz 3: Squid + Externe Modifikation

Vorteile:

  • Kampferprobter Proxy
  • SSL Bump für MITM
  • ICAP/eCAP für Inhaltsmodifikation

Nachteile:

  • Komplexe Konfiguration
  • EOL-Versionen noch im Einsatz
  • Nicht für JS-Injection ausgelegt
  • Großes Container-Image

Ansatz 4: Envoy Proxy mit Wasm-Filter

Vorteile:

  • Hohe Leistung
  • L4/L7-Proxy
  • WebAssembly (Wasm)-Filter für Modifikation
  • Natives HTTP/2 und HTTP/3

Nachteile:

  • Komplexe Konfiguration
  • Wasm-Filter-Entwicklungsaufwand
  • Nicht für clientseitige JS-Injection ausgelegt
  • Überdimensioniert für kleine Bereitstellungen

Ansatz 5: Eigenes TCP-Level-Interception

Raw-Socket-Interception + TLS-Terminierung:

  1. iptables TPROXY verwenden, um Datenverkehr umzuleiten
  2. Raw-TCP-Socket lesen
  3. Manueller TLS-Handshake (via rustls/crypto/tls)
  4. HTTP/1.1- oder HTTP/2-Parsing
  5. Header-Modifikation + JS-Injection
  6. An Upstream weiterleiten

Vorteile:

  • Maximale Kontrolle
  • Keine Abhängigkeit von Proxy-Frameworks
  • Kann alle Grenzfälle behandeln

Nachteile:

  • Maximaler Entwicklungsaufwand
  • Muss HTTP/2- und HTTP/3-Handling implementieren
  • Muss Connection Pooling korrekt handhaben

Empfehlung

Für Obscura ist eine eigene Rust-Implementierung (Ansatz 2) der beste Kompromiss:

  • Go's goproxy fehlt HTTP/2 und TLS-Spoofing
  • Rust bietet feinkörnige Kontrolle über TLS (utls-Integration)
  • Leistung ist für ein Netzwerk-Gateway wichtig
  • Rust's Sicherheitsgarantien reduzieren Proxy-Fehler

Zertifikatserstellung

Für MITM muss der Proxy TLS-Zertifikate on-the-fly erstellen:

  1. Ein CA-Zertifikat wird beim ersten Start erstellt
  2. Für jede neue Domain wird ein Blattzertifikat von der CA signiert
  3. Der Client muss dem CA-Zertifikat vertrauen
Obscura CA (privater Schlüssel)
   *.example.com (Blatt, bei erster Anfrage erstellt)
   *.anotherexample.com (Blatt, bei erster Anfrage erstellt)

Zertifikatsspeicher

/var/lib/obscura/certs/
 ca.pem          # CA-Zertifikat (öffentlich)
 ca-key.pem      # CA-privater Schlüssel
 cache/          # Erstellte Blattzertifikate
    example.com.pem
    ...
 serial          # Zertifikatsseriennummer-Zähler

Einschränkungen

  • HPKP (HTTP Public Key Pinning): Inzwischen in Chrome veraltet, aber manche Websites verwenden es noch
  • HSTS-Preloading: Websites in der HSTS-Preload-Liste (z. B. google.com, stripe.com) werden MITM-Zertifikate ablehnen. Muss zuerst auf DNS-/Netzwerkebene abgefangen werden.
  • Certificate Transparency: Manche Websites benötigen CT-Protokolle. Der Proxy muss SCTs einbetten.
  • HTTP/3 (QUIC): Läuft über UDP und ist Ende-zu-Ende verschlüsselt. Muss auf Netzwerkebene blockiert werden.

Schlussfolgerungen

  • Rust mit tokio-rustls + hyper ist der empfohlene Proxy-Stack
  • TLS-Fingerprint-Spoofing erfordert utls-Integration
  • HSTS-vorgeladene Websites müssen auf DNS-/Netzwerkebene behandelt werden
  • HTTP/3 muss blockiert werden (QUIC umgeht den Proxy)