detour - CLI + GUI hecho en Go para desviar de forma transparente en Windows el tráfico de una IP:PUERTO específica hacia otro destino
(github.com/LeeJeKyun)Hola. Es una herramienta que hice porque se repetía la situación en la que quería enviar temporalmente solo el tráfico de cierto puerto que va hacia un servidor externo
a un servidor mock levantado localmente. (con ayuda de Claude Code)
El archivo hosts no permite mapeo por puerto, y los proxys
solo funcionan si la aplicación
reconoce el proxy. Como detour intercepta los paquetes
un nivel más abajo (kernel),
la aplicación sigue funcionando pensando que hizo dial a la dirección original.
Cómo funciona
- Intercepta en el kernel los paquetes salientes con el driver WinDivert
y en userspace
realiza destination NAT → reescribedstaTO, recalcula el checksum
y los reinyecta - En los paquetes de respuesta vuelve a reescribir
srccomoFROM
y los devuelve,
por lo que la aplicación lo percibe como si hubiera respondido la dirección a la que hizodial - Se aplica a todo el sistema (sin filtrado por PID)
Componentes
detour.exe(CLI): aplica una regla en una sola línea con--from 1.2.3.4:5000 --to 127.0.0.1:5001,
y se desactiva con Ctrl+Cdetour-gui.exe: icono en la bandeja + tabla de múltiples reglas.
Guarda automáticamente las reglas en%APPDATA%\detour\rules.jsony las restaura en la siguiente ejecución.
Como cada regla ejecuta un par independiente de handles de WinDivert,
se pueden operar varios desvíos al mismo tiempo- UAC manifest embebido — al hacer doble clic aparece automáticamente el prompt de elevación de privilegios
WinDivert.dll/WinDivert64.systambién van embebidos en el binario —
no hace falta instalar un driver por separado
y todo queda resuelto con un solo exe
Stack
- Go 1.23+
- La GUI usa
lxn/walk(llamadas directas a Win32, sin dependencia de cgo, así que se puede hacer cross-compile desde macOS) - Los releases se empaquetan en un solo zip con GoReleaser (incluye CLI + GUI)
Limitaciones (v1)
- Solo IPv4 (sin soporte para IPv6)
- El tráfico local ↔ local (
127.0.0.1) puede comportarse de forma inconsistente porque el stack de red de Windows
lo trata de manera especial - TCP MSS clamping no está implementado — si la MTU de la ruta desviada es menor,
puede haber fragmentación
La licencia es GPLv3 (WinDivert depende de LGPLv3).
Se agradecen comentarios, casos de uso y reportes de bugs.
4 comentarios
¿O sea, es un proxy..?
Estrictamente hablando, más que un proxy, podría considerarse NAT de destino. Como lo de arriba era demasiado largo, les resumo abajo el caso en el que lo usé.
Quería enviar las solicitudes no al destino del programa cliente ya compilado (1.2.3.4.:5000), sino al servidor de mi PC local (172.16.100.201:5000).
Como la ruta de la solicitud estaba hardcodeada, en muchos casos para cambiarla había que pedirle al desarrollador del cliente que recompilara.
Quería resolverlo cambiando, a nivel del kernel del SO y no de la capa de aplicación, el destino y los headers de llegada del tráfico que va a una IP y puerto específicos (1.2.3.4.:5000) por la IP y el puerto deseados (172.16.100.201:5000).
Desarrollo de detour
¿También se pueden proxyear las solicitudes ingresadas con una dirección de dominio?
En el caso de las solicitudes ingresadas con una dirección de dominio, consideré que la complejidad de implementación aumentaba, así que desde el principio se configuró para que no se pudiera ingresar... Como fue desarrollado para pruebas internas, no admite funciones de uso general.
Es posible encontrar la IP de un dominio específico con
nslookupy configurarla.Intentaré aplicarlo en una actualización futura.