
Go-basierter MITM-HTTP/HTTPS-Proxy mit HTTP/2- und HTTP/1.1-Abfangfunktion, lokaler CA-/pro-Host-Zertifikatsgenerierung, CONNECT/WebSocket-Tunneling, Festplatten-Caching, Admin-Dashboard, Verkehrserfassung, Blockierrichtlinien und optionalem KI-gestütztem Bedrohungsscannen mit Schwärzung, Quarantäne und Audit-Protokollierung.
Ein leichtgewichtiger, entwicklerfreundlicher Man‑in‑the‑Middle (MITM) HTTP/HTTPS-Proxy in Go. Er unterstützt HTTP/1.1 und HTTP/2, CONNECT-Tunneling, WebSocket-Tunneling (ws/wss), Caching von Antworten auf der Festplatte mit flexiblen Filtern und dynamisches Neuladen der Konfiguration.

Go MITM Proxy ist ein abfangender Proxy, der für Debugging, Tests, Lernen und kontrolliertes Abfangen von HTTP(S)-Verkehr konzipiert ist. Wenn MITM aktiviert ist, generiert er dynamisch pro-Host-Zertifikate, die von einer lokalen CA signiert werden, sodass der Proxy HTTPS-Verkehr entschlüsseln und inspizieren kann. Er kann auch als transparenter TCP-Tunnel fungieren, wenn MITM deaktiviert ist oder für ausgeschlossene Domänen/Ports.
Wichtig: Diese Anwendung führt aktives Man-in-the-Middle (MITM) Abfangen durch, einschließlich der Erstellung und Verwendung von TLS-Zertifikaten zur Entschlüsselung von HTTPS-Verkehr. Abhängig von Ihrer Rechtsordnung und Netzwerkumgebung kann das Abfangen von Verkehr ohne klare vorherige Zustimmung aller betroffenen Benutzer illegal sein und gegen Datenschutz-, Arbeitsplatzrichtlinien oder gesetzliche Vorschriften verstoßen.
Bevor Sie diese Software in einer anderen Umgebung als Ihrem eigenen lokalen Rechner verwenden:
Alle Benutzer eines Netzwerks, in dem dieser Proxy Verkehr abfangen könnte, müssen klar informiert werden, dass HTTP(S)-Abfangen und -Inspektion stattfinden werden. Die Zustimmung sollte ausdrücklich und idealerweise dokumentiert sein.
Führen Sie diese Software nicht in Netzwerken aus, die Sie weder besitzen noch verwalten oder für die Sie keine ausdrückliche Berechtigung zum Testen oder Überwachen haben.
In vielen Regionen gelten strenge Gesetze zum Abfangen, Protokollieren und Speichern von Benutzerdaten (z. B. DSGVO, CCPA, Abhörgesetze). Sie sind verantwortlich dafür, dass Ihre Nutzung allen geltenden Vorschriften entspricht.
Der generierte private CA-Schlüssel (normalerweise ca-key.pem) erlaubt es dem Inhaber, jede Domäne zu imitieren, für Benutzer, die dem entsprechenden Zertifikat vertrauen.
Dieser Proxy ist für Entwicklung, Debugging, kontrollierte Tests oder Bildungszwecke konzipiert – nicht für verdeckte Überwachung oder unbefugte Überwachung.
Durch die Nutzung dieser Software erkennen Sie an und übernehmen die volle Verantwortung dafür, dass Ihre Nutzung rechtmäßig, ethisch und allen betroffenen Benutzern ordnungsgemäß mitgeteilt wird.
Voraussetzungen:
Klonen und bauen: ```bash git clone https://github.com/Welfordian/mitm-proxy.git cd mitm-proxy go build ./
Dies erzeugt eine mitm-proxy (oder mitm-proxy.exe unter Windows) Binärdatei im Projektstammverzeichnis.
## Schnellstart
1) Führen Sie den Proxy mit den Standardeinstellungen aus (hört auf :8080): ```bash
./mitm-proxy
Beim ersten Start wird eine lokale CA erstellt und in ca-cert.pem und ca-key.pem gespeichert.
Konfigurieren Sie Ihren Browser oder curl, um den Proxy unter http://localhost:8080 zu verwenden.
Vertrauen Sie dem generierten CA-Zertifikat (ca-cert.pem) in Ihrem Betriebssystem/Browser, um HTTPS-Abfangen zu ermöglichen. Siehe Vertrauen in die lokale CA.
Besuchen Sie eine HTTPS-Website über den Proxy und beobachten Sie die Logs. Verwenden Sie den ausführlichen Modus für mehr Details: ```bash ./mitm-proxy --verbose
## Verwendung
### Kommandozeilen-Flags
- --config string: Pfad zur config.json-Datei
- --listen string: Lauschadresse (überschreibt Konfiguration)
- --ca-cert string: Pfad zum vorhandenen CA-Zertifikat (überschreibt Konfiguration)
- --ca-key string: Pfad zum vorhandenen CA-Schlüssel (überschreibt Konfiguration)
- --mitm bool: MITM-Abfang aktivieren (Standard true; auf false gesetzt erzwingt Tunneling)
- --verbose bool: Ausführliche Protokollierung aktivieren
- --watch-config bool: Überwacht config.json auf Änderungen und wendet diese automatisch an (Standard true)
- --admin-enabled bool: Lokale Admin-API/-Dashboard aktivieren (Standard true)
- --admin-addr string: Admin-API/-Dashboard-Lauschadresse (Standard 127.0.0.1:9090)
- --admin-token string: Admin-Bearer-Token (wird beim Start generiert, falls nicht angegeben)
- --admin-read-token string: Schreibgeschützter Bearer-Token für GET/HEAD/OPTIONS-Adminzugriff
- --admin-ui bool: Eingebettete Admin-Oberfläche bereitstellen (Standard true)
- --admin-store string: Admin-SQLite-Speicherpfad (Standard dashboard.db)
CLI-Flags überschreiben die Konfigurationsdateiwerte, wo angegeben.
### Konfiguration (config.json)
Eine Beispiel-config.json ist im Repository enthalten: ```json
{
"listen_addr": ":8080",
"proxy_name": "MITM-Proxy",
"ca_cert_path": null,
"ca_key_path": null,
"ca_cert_output_path": "ca-cert.pem",
"ca_key_output_path": "ca-key.pem",
"enable_mitm": true,
"admin_enabled": true,
"admin_addr": "127.0.0.1:9090",
"admin_token": "",
"admin_read_token": "",
"admin_ui": true,
"admin_store": "dashboard.db",
"excluded_domains": [],
"blocked_ports": [25, 445, 3389],
"blocked_domains": [],
"blocked_ips": [],
"block_action": "deny",
"block_response_status": 403,
"traffic_capture": {
"store_bodies": false,
"max_body_bytes": 32768,
"redact_bodies": true,
"store_headers": true,
"redacted_headers": ["Authorization", "Cookie", "Proxy-Authorization", "Set-Cookie", "X-Api-Key"],
"store_cookies": true,
"redacted_cookies": []
},
"proxy_auth": {
"enabled": false,
"realm": "MITM Proxy",
"require_auth_for_loopback": false,
"default_action": "allow"
},
"verbose_logging": true,
"log_requests": true,
"max_idle_conns": 200,
"idle_conn_timeout_seconds": 90,
"tls_handshake_timeout_seconds": 10,
"min_tls_version": "1.2",
"tls_next_protos": ["h2", "http/1.1"],
"cache": {
"enabled": true,
"directory": "/var/cache/mitm-proxy",
"include_domains": [],
"exclude_domains": [],
"include_extensions": ["jpg", "png", "webp", "css", "js"],
"exclude_extensions": [],
"ttl": 3600
}
}
Anmerkungen:
ca_cert_path/ca_key_path nicht angegeben werden, schreibt der Proxy ein generiertes CA-Zertifikat nach ca-cert.pem / ca-key.pem.excluded_domains unterstützt Platzhalter (siehe IsDomainExcluded in internal/config).admin_addr standardmäßig auf localhost. Wenn admin_token leer ist, wird ein pro-Lauf gültiger Token generiert und beim Start ausgegeben.admin_read_token kann für schreibgeschützte Dashboard-/API-Clients gesetzt werden.traffic_capture.store_bodies ist standardmäßig deaktiviert; wenn aktiviert, sind Body-Beispiele standardmäßig größenbegrenzt und geschwärzt.traffic_capture.store_headers und traffic_capture.store_cookies steuern, ob erfasste Metadaten persistent gespeichert werden. redacted_headers schwärzt gesamte Header-Werte, während redacted_cookies vor der Speicherung passende einzelne Cookie- und Set-Cookie-Namen schwärzt.proxy_auth aktiviert die Basic-Client-Proxy-Authentifizierung, die auf SQLite-verwalteten Benutzern und geordneten ACL-Regeln basiert.blocked_domains unterstützt exakte Namen und Platzhaltermuster wie *.example.com; blocked_ips unterstützt einzelne IPs und CIDR-Bereiche.cache.include_domains und cache.exclude_domains schließen sich gegenseitig aus, ebenso wie include_extensions und exclude_extensions.--config übergebene Datei oder die Standarddatei ./config.json und wendet Änderungen heiß über Proxy.SetConfig an.Der Admin-Server stellt das Dashboard standardmäßig unter http://127.0.0.1:9090/admin/ bereit. API-Routen erfordern Authorization: Bearer <token>; für die lokale Browsernutzung speichert /admin/?token=<token> den Token im lokalen Speicher des Browsers.
Die anfängliche Dashboard-/API-Abdeckung umfasst:
GET /api/health und GET /api/versionGET /api/auditGET /api/traffic, GET /api/traffic/stats, GET /api/traffic/{id}, GET /api/traffic/stream, DELETE /api/traffic und POST /api/traffic/{id}/replayGET /api/traffic/export?format=har für den HAR-ExportGET/POST/PUT/DELETE /api/repeater/cases und POST /api/repeater/cases/{id}/send für gespeicherte bearbeitbare WiedergabefälleGET/POST/PUT/DELETE /api/scopes plus Scope-Zuweisungsendpunkte für Traffic und Repeater-FälleGET/POST/DELETE /api/pentest/maps plus Endpunkt-Klonaktionen für passive ZielkartenGET/POST/PUT/DELETE /api/proxy-auth/users und /api/proxy-acl/rules plus POST /api/proxy-acl/test für die Proxy-Client-ZugriffssteuerungPOST /api/ai/traffic/{id}/explain, POST /api/ai/traffic/{id}/suggest-tests, POST /api/ai/repeater/cases/{id}/suggest-tests, POST /api/ai/repeater/cases/{id}/compare-runs und GET/POST/DELETE /api/ai/notes für AI-Research-Copilot-NotizenGET /api/certificates/ca, GET /api/certificates/ca/download, POST /api/certificates/ca/rotate, POST /api/certificates/ca/import und GET /api/certificates/leafGET/POST/DELETE Blockregeln für Ports, Domains und IPsGET /api/deployments/current, POST /api/deployments/current/reload, GET /api/logs, GET /api/cache mit zwischengespeicherten Einträgen und Treffer-/Fehltrefferzahlen, POST /api/cache/purge und GET/PUT /api/settingsGET /api/threats/events, GET /api/threats/stream, GET /api/threats/config, POST /api/threats/test und Threat-Override-EndpunkteGET /metrics für Prometheus-kompatible Prozess-/Admin-/Threat-ZählerDas Dashboard enthält eine Bestätigung zur verantwortungsvollen Nutzung beim ersten Start. Der private CA-Schlüssel wird niemals über die Admin-API offengelegt.
Der Dashboard-Zustand wird standardmäßig in SQLite unter dashboard.db gespeichert. Über das Dashboard geänderte Einstellungen werden sofort angewendet und in die konfigurierte JSON-Datei zurückgeschrieben, bzw. in config.json, wenn der Proxy mit den Standardeinstellungen gestartet wurde.
Das Admin-Frontend ist eine Vite/React-App in internal/admin/ui. Ihr Produktionsbuild wird nach internal/admin/ui/dist ausgegeben und in das Go-Binary eingebettet. So aktualisieren Sie die Dashboard-Assets:```bash
cd internal/admin/ui
npm install
npm run build
### Upstream-Proxy-Verkettung
Ausgehender Datenverkehr kann durch einen vorgelagerten HTTP- oder HTTPS-Proxy verkettet werden, wie z. B. Burp, ZAP oder einen Corporate-Egress-Proxy. Wenn aktiviert, verwenden normales HTTP(S)-Forwarding, CONNECT-Passthrough-Tunnel, WebSockets und Repeater-Sends den vorgelagerten Proxy, es sei denn, ein Host entspricht `no_proxy`.```json
{
"upstream_proxy": {
"enabled": true,
"url": "http://127.0.0.1:8080",
"username": "",
"password_env": "UPSTREAM_PROXY_PASSWORD",
"no_proxy": ["localhost", "127.0.0.1", "*.internal"],
"chain_tunnels": true,
"apply_to_repeater": true
}
}
Only http:// and https:// upstream proxy URLs are supported in v1. If Basic auth is needed, set username and provide the password through the named environment variable; credentials embedded in the URL are rejected and are never shown in dashboard settings. If the upstream proxy is enabled but unavailable, affected requests fail visibly instead of silently falling back to direct connections.
The dashboard's Access Control view manages client proxy users and ordered allow/deny ACL rules. Proxy users are stored in SQLite with bcrypt password hashes; plaintext passwords are accepted only when creating or resetting a user and are never returned by the API.
Enable Basic proxy authentication through proxy_auth in config.json or the Settings view. When enabled, clients must send Proxy-Authorization: Basic ... unless loopback clients are exempt. ACL rules are evaluated by priority and can match username, source IP/CIDR, host or wildcard host, port or port range, method, and research scope. Empty matcher lists mean "any".
Proxy-Authorization is stripped before forwarding, upstream chaining, traffic capture, cache lookup, threat scanning, and Repeater cloning. Captured traffic includes proxy_user attribution when available, and the Traffic search box can match proxy usernames.
The dashboard's Repeater view lets security researchers clone captured HTTP traffic into saved editable cases. A case stores the method, URL, headers, body sample, timeout, and optional source traffic flow ID. Each send stores a run with status, duration, response headers, a capped response body sample, and any upstream error.
Captured request bodies are only prefilled when traffic_capture.store_bodies was enabled at capture time. If body redaction was enabled, the repeater receives the redacted sample; uncaptured bodies remain empty and can be edited manually.
The legacy POST /api/traffic/{id}/replay endpoint remains available for one-shot replay, while the repeater is intended for repeatable request mutation and response comparison.
The dashboard's Pentest Toolkit view builds passive target maps from captured traffic. Rebuilding a map analyzes only stored traffic for the selected scope, groups endpoints by normalized path, extracts query/body/cookie/header parameters, records reflected and interesting parameters, and adds passive hints such as missing security headers, cookie attribute gaps, permissive CORS, and verbose errors.
Pentest maps are persisted in SQLite and can be deleted independently. The toolkit never sends requests, crawls, fuzzes, or mutates targets; endpoint evidence can be cloned into Repeater for manual testing.
The dashboard's Scopes view lets researchers define named target boundaries with host, URL substring, and optional method patterns. Enabled scopes are matched automatically when traffic is captured; matching flows, cloned Repeater cases, and threat scanner events receive a single scope_id.
The global scope selector filters Traffic, Repeater, and Threat Scanner views across all traffic, a selected enabled scope, or out-of-scope items. Deleting a scope clears related scope_id values without deleting captured traffic, Repeater cases, runs, or threat data.
Scope filters are available on GET /api/traffic, GET /api/repeater/cases, and GET /api/threats/events with scope_id=<id> or scope_id=__out_of_scope__. Add include_out_of_scope=true to include unscoped rows beside a selected scope.
The dashboard's AI Copilot view stores AI-generated research notes linked to Traffic, Repeater cases, runs, scopes, or threat events. Traffic detail can ask the copilot to explain a request or suggest next manual tests; Repeater can suggest tests for a saved case or compare the latest two runs.
The copilot is advisory only. It never sends traffic, edits Repeater cases, changes scopes, changes settings, or purges data. Out-of-scope traffic can be explained, but active testing suggestions are intentionally withheld.
Enable it through ai_copilot in config.json or the Settings view:```json
{
"ai_copilot": {
"enabled": true,
"provider": "openai",
"model": "gpt-5.4-nano",
"timeout_ms": 10000,
"max_body_bytes": 32768,
"redact_before_ai": true,
"openai_api_key_env": "OPENAI_API_KEY"
}
}
Der OpenAI-API-Schlüssel wird aus der konfigurierten Umgebungsvariable ausgelesen und nicht im Dashboard oder in der Konfigurationsdatei gespeichert. Sensitive Header, Body-Beispiele und Abfragewerte werden geschwärzt, bevor der KI-Kontext gesendet wird, wenn `redact_before_ai` aktiviert ist. Gespeicherte Notizen enthalten das Modell, den Prompt-Hash, die Zusammenfassung und die strukturierte KI-Ausgabe, nicht den vollständigen Prompt.
### KI-Bedrohungsscan
Der Bedrohungsscanner kann HTTP-Anfragen und -Antworten mit lokalen Heuristiken überprüfen und, falls konfiguriert, vor dem Blockieren verdächtigen Datenverkehrs eine zweite Meinung von OpenAI einholen.
1. Erstellen Sie einen OpenAI-API-Schlüssel und machen Sie ihn dem Proxy-Prozess zugänglich:```powershell
$env:OPENAI_API_KEY = "sk-..."
Auf macOS/Linux:```bash export OPENAI_API_KEY="sk-..."
2. Aktivieren Sie den Scanner in `config.json`:```json
{
"threat_scanner": {
"enabled": true,
"mode": "suspicious_only",
"provider": "openai",
"model": "gpt-5.4-nano",
"second_opinion_model": "gpt-5.4-mini",
"scan_requests": true,
"scan_responses": true,
"max_body_bytes": 131072,
"max_ai_body_bytes": 32768,
"ai_timeout_ms": 750,
"block_threshold": 0.85,
"warn_threshold": 0.65,
"require_ai_confirmation_for_block": true,
"block_critical_local_on_ai_failure": true,
"fail_open": true,
"scan_content_types": [
"text/html",
"text/plain",
"application/json",
"application/javascript",
"text/javascript",
"application/xml"
],
"skip_content_types": [
"image/",
"video/",
"audio/",
"font/",
"application/octet-stream"
],
"trusted_domains": [
"accounts.google.com",
"login.microsoftonline.com",
"github.com"
],
"allowlist_domains": [],
"malicious_domains": [],
"malicious_file_hashes": [],
"threat_intel_updated": "",
"quarantine_dir": "quarantine",
"debug_log_path": "threats.log",
"redact_before_ai": true,
"store_bodies": false,
"openai_api_key_env": "OPENAI_API_KEY"
}
}
Die Ansicht **Threat Scanner** des Dashboards zeigt die Anzahl der gescannten Anfragen/Antworten, KI-Aufrufzahlen, Erkennungen, Entscheidungsdetails, wichtigste lokale Regeln und Überschreibungsaktionen.
Scanner-Modi:
- `suspicious_only`: Standard; lokale Heuristiken entscheiden, wann die KI aufgerufen wird.
- `all_text`: ruft KI für textähnlichen Verkehr auf.
- `paranoid`: ruft ebenfalls KI für textähnlichen Verkehr auf und ist für Tests mit hoher Sensitivität gedacht.
- `metadata_only`: verwendet Header, URL, Host und Metadaten ohne KI-Überprüfung des Inhalts.
- `off`: deaktiviert das Scannen.
Nützliche Sicherheits- und Datenschutzkontrollen:
- `redact_before_ai`: schwärzt häufige Geheimnisse und persönliche Daten, bevor Belege an OpenAI gesendet werden.
- `max_ai_body_bytes`: begrenzt die Körperprobe, die in KI-Belege aufgenommen wird.
- `require_ai_confirmation_for_block`: verhindert, dass lokale Heuristiken blockieren, es sei denn, die KI bestätigt, außer wenn `block_critical_local_on_ai_failure` für kritische lokale Belege aktiviert ist.
- `fail_open`: erlaubt Datenverkehr, wenn der Scanner fehlschlägt, es sei denn, strengere Blockierungseinstellungen greifen.
- `trusted_domains` und `allowlist_domains`: reduzieren Fehlalarme für bekannte gute Hosts.
- `malicious_domains` und `malicious_file_hashes`: fügen lokale Threat-Intelligence-Treffer hinzu, ohne auf KI zu warten.
- `debug_log_path`: schreibt Scanner-Entscheidungen in ein lokales JSONL-ähnliches Log zur Fehlerbehebung.
Um einen anderen Umgebungsvariablennamen für den API-Schlüssel zu verwenden, setzen Sie `openai_api_key_env` und exportieren Sie diese Variable, bevor Sie den Proxy starten. Setzen Sie API-Schlüssel nicht direkt in `config.json`.
### Vertrauen in die lokale Zertifizierungsstelle
Um HTTPS abzufangen, importieren und vertrauen Sie ca-cert.pem in Ihrem Betriebssystem/Browser:
- macOS: Schlüsselbundverwaltung → Anmeldung/System → Zertifikate → ca-cert.pem importieren → Immer vertrauen einstellen.
- Windows: certmgr.msc → Vertrauenswürdige Stammzertifizierungsstellen → Zertifikate → ca-cert.pem importieren.
- Linux (variiert): z.B. update-ca-certificates oder browserspezifischer Speicher (Firefox: Einstellungen → Datenschutz & Sicherheit → Zertifikate → Anzeigen → Zertifizierungsstellen → Importieren).
Ohne Vertrauen in die Zertifizierungsstelle zeigen Browser Zertifikatswarnungen für abgefangene Websites an.
### Verwenden des Proxys
Setzen Sie Ihren HTTP/HTTPS-Proxy auf die Lauschadresse (Standard http://localhost:8080).
Beispiele mit curl: ```bash
# HTTP
curl -x http://localhost:8080 http://example.com/
# HTTPS (after trusting the CA for full MITM)
curl -x http://localhost:8080 https://example.com/
# Disable MITM and tunnel only
./mitm-proxy --mitm=false
# Change listen address
./mitm-proxy --listen=127.0.0.1:9090
WebSocket-Hinweise:
Der Cache ist dateibasiert und berücksichtigt nur HTTP-GET-Anfragen, wenn er aktiviert ist. Die Auswahl wird gesteuert durch:
Bei einem Cache-Treffer enthalten die Antworten:
Das Cache-Verzeichnis wird beim Start und bei Konfigurationsänderungen sichergestellt. Wenn kein Verzeichnis festgelegt ist, wird standardmäßig ./cache verwendet.
go build ./ ./mitm-proxy --config ./config.json
Der Server bindet an die konfigurierte listen_addr und handhabt HTTP + HTTPS mit ALPN.
## Fahrplan
- Proxy-Authentifizierung (Basic/NTLM) und ACLs
- Upstream-Proxy/Chaining-Unterstützung
- PAC-Dateigenerierung und Hilfsskripte
- UI zur Überprüfung von Flows und Cache-Einträgen
- TLS-Fingerprinting-Steuerung und JA3-Stil
- Metriken/Health-Endpunkte und Prometheus-Integration
## Mitwirken
Issues und Pull Requests sind willkommen. Bei größeren Änderungen bitte zuerst ein Issue eröffnen, um Umfang und Design zu besprechen.
Codierungsstil: Änderungen minimal und fokussiert halten; Klarheit und kleine, zusammensetzbare Funktionen bevorzugen.