2 pontos por zxsi2003 12 일 전 | 4 comentários | Compartilhar no WhatsApp

Olá. Esta é uma ferramenta que criei porque se repetia uma situação em que eu queria, por um momento, enviar apenas o tráfego de uma porta específica que iria para um servidor externo
para um servidor mock iniciado localmente. (com uso do Claude Code)

O arquivo hosts não permite mapeamento por porta, e proxies
só funcionam se a aplicação
reconhecer o proxy. Como o detour intercepta os pacotes um nível abaixo (no kernel),
a aplicação continua funcionando
como se tivesse feito dial para o endereço original.

Como funciona

  • Intercepta no kernel os pacotes de saída com o driver WinDivert e, no userspace,
    executa destination NAT → reescreve o dst para TO, recalcula o checksum
    e reinjeta o pacote
  • Os pacotes de resposta têm o src reescrito de volta para FROM
    antes de serem devolvidos, então
    a aplicação entende como se a resposta tivesse vindo do endereço para o qual ela fez dial
  • Aplicado ao sistema inteiro (sem filtragem por PID)

Componentes

  • detour.exe (CLI): aplica a regra em uma linha com --from 1.2.3.4:5000 --to 127.0.0.1:5001,
    e desfaz com Ctrl+C
  • detour-gui.exe: ícone na bandeja + tabela com múltiplas regras.
    Salva as regras automaticamente em %APPDATA%\detour\rules.json e as restaura na próxima
    execução.
    Como cada regra roda com um par independente de handles do WinDivert, é possível operar vários redirecionamentos
    ao mesmo tempo
  • Manifesto UAC embutido — ao dar duplo clique, aparece automaticamente o prompt de elevação de privilégio
  • WinDivert.dll / WinDivert64.sys também embutidos no binário —
    termina em um único exe, sem necessidade de instalação separada
    do driver

Stack

  • Go 1.23+
  • A GUI usa lxn/walk (chamadas diretas à Win32, sem dependência de cgo, então
    é possível fazer cross-compile a partir do macOS)
  • Os releases são gerados com GoReleaser em um único zip (CLI + GUI incluídos)

Limitações (v1)

  • Somente IPv4 (sem suporte a IPv6)
  • Tráfego local ↔ local (127.0.0.1) pode se comportar de forma inconsistente, porque a stack de rede do Windows
    o trata de forma especial
  • TCP MSS clamping não implementado — se o MTU do caminho de redirecionamento for menor,
    pode haver fragmentação

A licença é GPLv3 (o WinDivert depende de LGPLv3).
Feedback / casos de uso / relatórios de bug são bem-vindos.

4 comentários

 
kaydash 11 일 전

É um proxy, então..?

 
zxsi2003 11 일 전

A rigor, isso pode ser visto mais como Destination NAT do que como um proxy. Como a descrição acima ficou longa demais, vou resumir abaixo o caso de uso que tive.

  1. Eu queria enviar as requisições não para o destino do programa cliente já compilado (1.2.3.4.:5000), mas para um servidor no meu PC local (172.16.100.201:5000).

  2. Como o caminho da requisição estava hardcoded, em muitos casos seria preciso pedir ao desenvolvedor do cliente para recompilar a aplicação para mudar isso.

  3. A ideia era resolver isso não na camada da aplicação, mas na camada do kernel do SO, alterando o destino e os cabeçalhos de chegada do tráfego que vai para um IP e porta específicos (1.2.3.4.:5000) para o IP e porta desejados (172.16.100.201:5000).

  4. Desenvolvimento do detour

 
findnamo 11 일 전

Também é possível fazer proxy para requisições inseridas com endereço de domínio?

 
zxsi2003 11 일 전

No caso de solicitações inseridas como endereço de domínio, entendemos que a complexidade da implementação aumentaria, então desde o início foi definido que esse tipo de entrada não seria permitido... Como foi desenvolvido para testes internos, ele não oferece funcionalidades genéricas.
É possível descobrir o IP de um domínio específico com nslookup e configurar dessa forma.

Vamos tentar aplicar isso em uma atualização futura.