
Go 기반 MITM HTTP/HTTPS 프록시로, HTTP/2 및 HTTP/1.1 가로채기, 로컬 CA/호스트별 인증서 생성, CONNECT/WebSocket 터널링, 디스크 캐싱, 관리자 대시보드, 트래픽 캡처, 차단 정책, 그리고 선택적 AI 기반 위협 스캐닝(교정, 격리, 감사 로깅 포함)을 제공합니다.
Go로 작성된 가볍고 개발자 친화적인 중간자(MITM) HTTP/HTTPS 프록시입니다. HTTP/1.1 및 HTTP/2, CONNECT 터널링, WebSocket 터널링(ws/wss), 유연한 필터를 지원하는 디스크 기반 응답 캐싱, 그리고 실시간 설정 리로드를 지원합니다.

Go MITM Proxy는 디버깅, 테스트, 학습, 그리고 HTTP(S) 트래픽의 통제된 가로채기를 목적으로 하는 인터셉팅 프록시입니다. MITM이 활성화되면 로컬 CA가 서명한 호스트별 리프 인증서를 동적으로 생성하여 프록시가 HTTPS 트래픽을 복호화하고 검사할 수 있게 합니다. MITM이 비활성화되거나 제외된 도메인/포트의 경우 투명한 TCP 터널로도 작동할 수 있습니다.
중요: 이 애플리케이션은 HTTPS 트래픽을 복호화하기 위한 TLS 인증서의 생성 및 사용을 포함하여 능동적인 중간자(MITM) 가로채기를 수행합니다. 관할권과 네트워크 환경에 따라, 영향을 받는 모든 사용자로부터 명확하고 사전 동의 없이 트래픽을 가로채는 것은 불법일 수 있으며 개인정보 보호, 직장 정책 또는 규제 요구사항을 위반할 수 있습니다.
이 소프트웨어를 자신의 로컬 머신이 아닌 환경에서 사용하기 전에:
이 프록시가 트래픽을 가로챌 수 있는 모든 네트워크의 사용자는 HTTP(S) 가로채기 및 검사가 수행된다는 사실을 명확히 고지받아야 합니다. 동의는 명시적이어야 하며 이상적으로는 문서화되어야 합니다.
소유, 관리, 또는 테스트나 모니터링에 대한 명시적 권한이 없는 네트워크에서 이 소프트웨어를 실행하지 마십시오.
많은 지역에서는 사용자 데이터의 가로채기, 로깅, 저장을 규율하는 엄격한 법률이 있습니다(예: GDPR, CCPA, 통신 감청법). 귀하는 귀하의 사용이 모든 적용 가능한 규정을 준수하도록 할 책임이 있습니다.
생성된 CA 개인 키(보통 ca-key.pem)를 보유한 사람은 해당 인증서를 신뢰하는 사용자에 대해 모든 도메인을 사칭할 수 있습니다.
이 프록시는 개발, 디버깅, 통제된 테스트 또는 교육 목적으로 설계되었습니다 — 은밀한 모니터링이나 무단 감시를 위한 것이 아닙니다.
이 소프트웨어를 사용함으로써, 귀하는 귀하의 사용이 합법적이고 윤리적이며 모든 영향을 받는 사용자에게 적절히 고지되도록 할 전적인 책임을 인정하고 수락합니다.
전제 조건:
클론 및 빌드: ```bash git clone https://github.com/Welfordian/mitm-proxy.git cd mitm-proxy go build ./
이렇게 하면 프로젝트 루트에 mitm-proxy(Windows에서는 mitm-proxy.exe) 바이너리가 생성됩니다.
## 빠른 시작
1) 기본 설정으로 프록시를 실행합니다(:8080에서 수신 대기): ```bash
./mitm-proxy
처음 시작하면 로컬 CA가 생성되어 ca-cert.pem 및 ca-key.pem에 저장됩니다.
브라우저나 curl이 http://localhost:8080의 프록시를 사용하도록 구성합니다.
HTTPS 가로채기를 허용하려면 OS/브라우저에서 생성된 CA 인증서(ca-cert.pem)를 신뢰합니다. 로컬 CA 신뢰하기를 참조하세요.
프록시를 통해 HTTPS 사이트를 방문하고 로그를 확인합니다. 자세한 내용은 verbose 모드를 사용하세요: ```bash ./mitm-proxy --verbose
## 사용법
### 명령줄 플래그
- --config string: config.json 파일 경로
- --listen string: 수신 주소 (config 재정의)
- --ca-cert string: 기존 CA 인증서 경로 (config 재정의)
- --ca-key string: 기존 CA 키 경로 (config 재정의)
- --mitm bool: MITM 인터셉트 활성화 (기본값 true; false로 설정 시 터널링 강제)
- --verbose bool: 상세 로깅 활성화
- --watch-config bool: config.json의 변경 사항을 감시하고 자동 적용 (기본값 true)
- --admin-enabled bool: 로컬 관리 API/대시보드 활성화 (기본값 true)
- --admin-addr string: 관리 API/대시보드 수신 주소 (기본값 127.0.0.1:9090)
- --admin-token string: 관리자 bearer 토큰 (생략 시 시작 시 생성)
- --admin-read-token string: GET/HEAD/OPTIONS 관리 액세스용 읽기 전용 bearer 토큰
- --admin-ui bool: 내장 관리 UI 제공 (기본값 true)
- --admin-store string: 관리 SQLite 저장소 경로 (기본값 dashboard.db)
명시된 항목의 경우 CLI 플래그가 구성 파일 값을 재정의합니다.
### 구성 (config.json)
예제 config.json이 저장소에 포함되어 있습니다: ```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
}
}
참고:
관리자 서버는 기본적으로 http://127.0.0.1:9090/admin/에서 대시보드를 제공합니다. API 경로에는 Authorization: Bearer <token>이 필요합니다. 로컬 브라우저 사용의 경우 /admin/?token=<token>이 토큰을 브라우저 로컬 저장소에 저장합니다.
초기 대시보드/API 포함 범위는 다음과 같습니다.
대시보드에는 첫 실행 시 책임 있는 사용 확인 절차가 포함됩니다. CA 개인 키는 관리자 API를 통해 노출되지 않습니다.
대시보드 상태는 기본적으로 dashboard.db의 SQLite에 저장됩니다. 대시보드를 통해 변경된 설정은 즉시 적용되며, 구성된 JSON 파일 또는 프록시가 기본값으로 시작된 경우 config.json에 다시 기록됩니다.
관리자 프런트엔드는 internal/admin/ui에 있는 Vite/React 앱입니다. 프로덕션 빌드는 internal/admin/ui/dist로 출력되어 Go 바이너리에 포함됩니다. 대시보드 자산을 업데이트하려면:```bash
cd internal/admin/ui
npm install
npm run build
### 업스트림 프록시 체이닝
아웃바운드 트래픽은 Burp, ZAP 또는 기업용 이그레스 프록시와 같은 업스트림 HTTP 또는 HTTPS 프록시를 통해 체이닝될 수 있습니다. 활성화되면 일반 HTTP(S) 포워딩, CONNECT 패스스루 터널, WebSockets 및 Repeater 전송은 호스트가 `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
}
}
v1에서는 http:// 및 https:// 업스트림 프록시 URL만 지원됩니다. Basic 인증이 필요한 경우 username을 설정하고, 명명된 환경 변수를 통해 비밀번호를 제공하세요. URL에 포함된 자격 증명은 거부되며 대시보드 설정에 표시되지 않습니다. 업스트림 프록시가 활성화되어 있지만 사용할 수 없는 경우, 영향을 받는 요청은 직접 연결로 자동 폴백하지 않고 오류를 명확히 드러내며 실패합니다.
대시보드의 Access Control 보기는 클라이언트 프록시 사용자와 순서가 지정된 허용/거부 ACL 규칙을 관리합니다. 프록시 사용자는 bcrypt 비밀번호 해시와 함께 SQLite에 저장됩니다. 평문 비밀번호는 사용자를 생성하거나 재설정할 때만 허용되며 API로 절대 반환되지 않습니다.
config.json의 proxy_auth 또는 Settings 보기를 통해 Basic 프록시 인증을 활성화하세요. 활성화되면 루프백 클라이언트가 면제되지 않는 한 클라이언트는 Proxy-Authorization: Basic ...을 전송해야 합니다. ACL 규칙은 우선순위에 따라 평가되며 사용자 이름, 소스 IP/CIDR, 호스트 또는 와일드카드 호스트, 포트 또는 포트 범위, 메서드 및 연구 범위를 매칭할 수 있습니다. 빈 매처 목록은 "any"(모두)를 의미합니다.
Proxy-Authorization은 전달, 업스트림 체이닝, 트래픽 캡처, 캐시 조회, 위협 스캔 및 Repeater 복제 전에 제거됩니다. 캡처된 트래픽에는 사용 가능한 경우 proxy_user 귀속 정보가 포함되며, Traffic 검색 상자에서 프록시 사용자 이름을 매칭할 수 있습니다.
대시보드의 Repeater 보기를 사용하면 보안 연구원이 캡처된 HTTP 트래픽을 저장된 편집 가능한 케이스로 복제할 수 있습니다. 케이스에는 메서드, URL, 헤더, 본문 샘플, 타임아웃 및 선택적 소스 트래픽 흐름 ID가 저장됩니다. 전송할 때마다 상태, 기간, 응답 헤더, 크기가 제한된 응답 본문 샘플 및 업스트림 오류가 포함된 실행(run)이 저장됩니다.
캡처된 요청 본문은 캡처 시점에 traffic_capture.store_bodies가 활성화된 경우에만 미리 채워집니다. 본문 마스킹(redaction)이 활성화된 경우 Repeater는 마스킹된 샘플을 받게 됩니다. 캡처되지 않은 본문은 비어 있는 상태로 유지되며 수동으로 편집할 수 있습니다.
레거시 POST /api/traffic/{id}/replay 엔드포인트는 일회성 재생을 위해 계속 사용할 수 있으며, Repeater는 반복 가능한 요청 변형과 응답 비교를 위한 것입니다.
대시보드의 Pentest Toolkit 보기는 캡처된 트래픽에서 수동적 대상 맵을 구축합니다. 맵을 다시 구축하면 선택된 범위에 대해 저장된 트래픽만 분석하고, 정규화된 경로별로 엔드포인트를 그룹화하며, 쿼리/본문/쿠키/헤더 파라미터를 추출하고, 반사(reflected) 및 관심(interesting) 파라미터를 기록하며, 누락된 보안 헤더, 쿠키 속성 누락, 허용적인 CORS 및 상세 오류와 같은 수동적 힌트를 추가합니다.
펜테스트 맵은 SQLite에 저장되며 독립적으로 삭제할 수 있습니다. 이 툴킷은 요청을 전송하거나, 크롤링하거나, 퍼징하거나, 대상을 변형하지 않습니다. 엔드포인트 증거는 수동 테스트를 위해 Repeater로 복제할 수 있습니다.
대시보드의 Scopes 보기를 사용하면 연구원이 호스트, URL 하위 문자열 및 선택적 메서드 패턴으로 이름이 지정된 대상 경계를 정의할 수 있습니다. 활성화된 스코프는 트래픽이 캡처될 때 자동으로 매칭되며, 매칭된 흐름, 복제된 Repeater 케이스 및 위협 스캐너 이벤트는 단일 scope_id를 받습니다.
전역 스코프 선택기는 모든 트래픽, 선택된 활성 스코프 또는 범위 외 항목에 대해 Traffic, Repeater 및 Threat Scanner 보기를 필터링합니다. 스코프를 삭제하면 캡처된 트래픽, Repeater 케이스, 실행 또는 위협 데이터는 삭제하지 않고 관련 scope_id 값만 지워집니다.
스코프 필터는 scope_id=<id> 또는 scope_id=__out_of_scope__와 함께 GET /api/traffic, GET /api/repeater/cases 및 GET /api/threats/events에서 사용할 수 있습니다. 선택된 스코프 옆에 범위가 지정되지 않은 행을 포함하려면 include_out_of_scope=true를 추가하세요.
대시보드의 AI Copilot 보기는 Traffic, Repeater 케이스, 실행, 범위 또는 위협 이벤트에 연결된 AI 생성 연구 노트를 저장합니다. Traffic 상세 정보에서 코파일럿에게 요청을 설명하거나 다음 수동 테스트를 제안하도록 요청할 수 있습니다. Repeater는 저장된 케이스에 대한 테스트를 제안하거나 최신 두 실행을 비교할 수 있습니다.
코파일럿은 조언 제공 전용입니다. 코파일럿은 절대 트래픽을 전송하거나, Repeater 케이스를 편집하거나, 스코프를 변경하거나, 설정을 변경하거나, 데이터를 삭제하지 않습니다. 범위 외 트래픽은 설명할 수 있지만, 적극적인 테스트 제안은 의도적으로 제공되지 않습니다.
config.json의 ai_copilot 또는 Settings 보기를 통해 활성화하세요:```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"
}
}
OpenAI API 키는 구성된 환경 변수에서 읽어오며 대시보드나 구성 파일에 저장되지 않습니다. `redact_before_ai`가 활성화되면 AI 컨텍스트가 전송되기 전에 민감한 헤더, 본문 샘플 및 쿼리 값이 삭제됩니다. 저장된 노트에는 모델, 프롬프트 해시, 요약 및 구조화된 AI 출력이 포함되며 전체 프롬프트는 포함되지 않습니다.
### AI 위협 스캐닝
위협 스캐너는 로컬 휴리스틱으로 HTTP 요청과 응답을 검사할 수 있으며, 구성된 경우 의심스러운 트래픽을 차단하기 전에 OpenAI에 두 번째 의견을 요청할 수 있습니다.
1. OpenAI API 키를 생성하고 프록시 프로세스에 노출합니다:```powershell
$env:OPENAI_API_KEY = "sk-..."
macOS/Linux에서:```bash export OPENAI_API_KEY="sk-..."
2. `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"
}
}
대시보드의 **Threat Scanner** 보기에는 스캔된 요청/응답 수, AI 호출 수, 탐지 결과, 판정 세부 정보, 상위 로컬 규칙 및 재정의 작업이 표시됩니다.
스캐너 모드:
- `suspicious_only`: 기본값. 로컬 휴리스틱이 AI 호출 시점을 결정합니다.
- `all_text`: 텍스트형 트래픽에 대해 AI를 호출합니다.
- `paranoid`: 텍스트형 트래픽에도 AI를 호출하며, 고감도 테스트를 위해 설계되었습니다.
- `metadata_only`: AI 본문 검토 없이 헤더, URL, 호스트 및 메타데이터를 사용합니다.
- `off`: 스캐닝을 비활성화합니다.
유용한 안전 및 개인정보 보호 제어:
- `redact_before_ai`: OpenAI로 증거를 보내기 전에 일반적인 비밀 값과 개인 데이터를 마스킹합니다.
- `max_ai_body_bytes`: AI 증거에 포함되는 본문 샘플의 크기를 제한합니다.
- `require_ai_confirmation_for_block`: AI가 확인하지 않는 한 로컬 휴리스틱이 차단하지 못하도록 합니다. 단, `block_critical_local_on_ai_failure`가 활성화된 경우 중요한 로컬 증거에 대해서는 차단이 허용됩니다.
- `fail_open`: 스캐너가 실패하면 트래픽을 허용합니다. 단, 더 엄격한 차단 설정이 적용되는 경우는 예외입니다.
- `trusted_domains` 및 `allowlist_domains`: 알려진 양호한 호스트에 대한 오탐(false positive)을 줄입니다.
- `malicious_domains` 및 `malicious_file_hashes`: AI를 기다리지 않고 로컬 위협 인텔리전스 적중 항목을 추가합니다.
- `debug_log_path`: 디버깅을 위해 스캐너 결정 사항을 로컬 JSONL 스타일 로그에 기록합니다.
API 키에 다른 환경 변수 이름을 사용하려면 `openai_api_key_env`를 설정하고 프록시를 시작하기 전에 해당 변수를 export하세요. API 키를 `config.json`에 직접 넣지 마세요.
### 로컬 CA 신뢰하기
HTTPS를 가로채려면 OS/브라우저에서 ca-cert.pem을 가져와 신뢰하세요:
- macOS: Keychain Access → 로그인/시스템 → 인증서 → ca-cert.pem 가져오기 → 항상 신뢰로 설정.
- Windows: certmgr.msc → 신뢰할 수 있는 루트 인증 기관 → 인증서 → ca-cert.pem 가져오기.
- Linux(배포판마다 다름): 예: update-ca-certificates 또는 브라우저별 저장소(Firefox: 설정 → 개인 정보 및 보안 → 인증서 → 인증 기관 보기 → 가져오기).
CA를 신뢰하지 않으면 브라우저는 가로챈 사이트에 대해 인증서 경고를 표시합니다.
### 프록시 사용
HTTP/HTTPS 프록시를 수신 주소(기본값: http://localhost:8080)로 설정하세요.
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 참고 사항:
캐시는 파일 기반이며, 활성화된 경우 HTTP GET 요청만 고려합니다. 선택 기준은 다음과 같이 제어됩니다:
캐시 적중 시 응답에는 다음이 포함됩니다:
캐시 디렉터리는 시작 시와 구성 변경 시 확인됩니다. 디렉터리가 설정되지 않은 경우 기본값은 ./cache입니다.
go build ./ ./mitm-proxy --config ./config.json
The server binds to the configured listen_addr and handles HTTP + HTTPS with ALPN.
## Roadmap
- Proxy authentication (Basic/NTLM) and ACLs
- Upstream proxy/chaining support
- PAC file generation and helper scripts
- UI for inspecting flows and cache entries
- TLS fingerprinting controls and JA3 styling
- Metrics/health endpoints and Prometheus integration
## Contributing
이슈와 풀 리퀘스트를 환영합니다. 중요한 변경 사항이 있으면 먼저 이슈를 열어 범위와 설계를 논의해 주세요.
코딩 스타일: 변경 사항을 최소화하고 집중하세요. 명확성과 작고 조합 가능한 함수를 선호합니다.