Ü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-rustlsfür TLS-Terminierung- Hyper für HTTP/1 und HTTP/2
- Kann
utlsfü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:
- iptables
TPROXYverwenden, um Datenverkehr umzuleiten - Raw-TCP-Socket lesen
- Manueller TLS-Handshake (via rustls/crypto/tls)
- HTTP/1.1- oder HTTP/2-Parsing
- Header-Modifikation + JS-Injection
- 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:
- Ein CA-Zertifikat wird beim ersten Start erstellt
- Für jede neue Domain wird ein Blattzertifikat von der CA signiert
- 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+hyperist 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)