Show GN: detour - Go로 만든 Windows에서 특정 IP:PORT 트래픽을 다른 목적지로 투명하게 우회시키는 CLI + GUI
(github.com/LeeJeKyun)안녕하세요. 외부 서버로 향하는 특정 포트 트래픽만 잠깐
로컬에 띄운 mock 서버로
보내고 싶은 상황이 반복돼서 만든 도구입니다.(클로드코드 활용)
hosts 파일은 포트 단위 매핑이 안 되고, 프록시는
애플리케이션이 프록시를
인식해줘야 동작합니다. detour는 한 계층 아래(커널)에서
패킷을 가로채기 때문에
애플리케이션은 자기가 원래 주소로 dial한 줄 알고 그대로
동작합니다.
동작 방식
- WinDivert 드라이버로 outbound 패킷을 커널에서 가로채서
userspace에서
destination NAT 수행 → dst를TO로 rewrite, 체크섬
재계산 후 재주입 - 응답 패킷은 src를
FROM으로 다시 rewrite해서
돌려보내므로,
애플리케이션은 자기가 다이얼한 주소가 응답한 것처럼 인식 - 시스템 전체에 적용 (PID 필터링 없음)
구성
detour.exe(CLI):--from 1.2.3.4:5000 --to 127.0.0.1:5001한 줄로 룰 적용,
Ctrl+C로 해제detour-gui.exe: 트레이 아이콘 + 멀티 룰 테이블.
룰을%APPDATA%\detour\rules.json에 자동 저장하고 다음
실행 시 복원.
룰마다 독립된 WinDivert 핸들 쌍이 돌아서 여러 우회를
동시에 운용 가능- UAC manifest 임베드 — 더블클릭하면 자동으로 권한 상승
프롬프트 - WinDivert.dll / WinDivert64.sys 도 바이너리에 임베드 —
별도 드라이버 설치
없이 단일 exe로 끝남
스택
- Go 1.23+
- GUI는
lxn/walk(Win32 직접 호출, cgo 의존성 없어서
macOS에서 cross-compile 가능) - 릴리스는 GoReleaser로 단일 zip (CLI + GUI 동봉)
한계 (v1)
- IPv4 전용 (IPv6 미지원)
- 로컬 ↔ 로컬(127.0.0.1) 트래픽은 Windows 네트워킹 스택이
특별 취급해서
일관성 없게 동작할 수 있음 - TCP MSS clamping 미구현 — 우회 경로 MTU가 작으면
fragmentation 가능
라이센스는 GPLv3 (WinDivert는 LGPLv3 의존).
피드백 / 사용 사례 / 버그 리포트 환영합니다.
댓글과 토론
엄밀히 말하면 프록시라기보단 Destination NAT이라고 볼 수 있습니다. 위에 말이 너무 길어서 제가 사용한 케이스를 아래에 정리해드리겠습니다.
-
이미 빌드된 클라이언트 프로그램의 목적지(1.2.3.4.:5000)가 아닌 내 로컬 PC의 서버(172.16.100.201:5000)으로 요청을 보내고자 함.
-
요청 경로가 하드코딩되어있어 변경하려면 클라이언트 개발자에게 재빌드를 요청해야하는 경우가 다수 발생
-
애플리케이션단이 아닌 OS커널단에서 특정 IP, Port(1.2.3.4.:5000)로 가는 트래픽의 목적지, 도착지 헤더를 원하는 IP, Port(172.16.100.201:5000)로 변경하여 해결하고자함.
-
detour 개발