2 points par zxsi2003 12 일 전 | 4 commentaires | Partager sur WhatsApp

Bonjour. C’est un outil que j’ai créé parce que je me retrouvais souvent dans une situation où je voulais, pendant un moment, envoyer uniquement le trafic d’un port précis à destination d’un serveur externe vers un serveur mock lancé en local. (avec l’aide de Claude Code)

Le fichier hosts ne permet pas de faire du mapping au niveau du port, et un proxy ne fonctionne que si l’application sait reconnaître le proxy. Comme detour intercepte les paquets un niveau plus bas, dans le noyau, l’application continue simplement à fonctionner en pensant qu’elle a établi la connexion vers l’adresse d’origine.

Fonctionnement

  • Interception des paquets sortants dans le noyau avec le pilote WinDivert, puis exécution d’un destination NAT en espace utilisateur → réécriture de la destination vers TO, recalcul du checksum, puis réinjection
  • Pour les paquets de réponse, la source est réécrite de nouveau vers FROM avant renvoi, de sorte que l’application croit recevoir une réponse de l’adresse qu’elle a appelée
  • S’applique à tout le système (pas de filtrage par PID)

Composition

  • detour.exe (CLI) : application d’une règle en une seule ligne avec --from 1.2.3.4:5000 --to 127.0.0.1:5001, désactivation avec Ctrl+C
  • detour-gui.exe : icône dans la zone de notification + tableau multi-règles. Les règles sont enregistrées automatiquement dans %APPDATA%\detour\rules.json et restaurées au prochain lancement. Chaque règle exécute sa propre paire de handles WinDivert, ce qui permet d’utiliser plusieurs redirections en parallèle
  • Manifest UAC embarqué — double-clic pour afficher automatiquement l’invite d’élévation de privilèges
  • WinDivert.dll / WinDivert64.sys également embarqués dans le binaire — pas besoin d’installer un pilote séparé, un seul .exe suffit

Stack

  • Go 1.23+
  • Pour la GUI, lxn/walk (appel direct à Win32, sans dépendance cgo, donc cross-compilation possible depuis macOS)
  • Release sous forme d’un zip unique avec GoReleaser (CLI + GUI inclus)

Limites (v1)

  • IPv4 uniquement (pas de prise en charge d’IPv6)
  • Le trafic local ↔ local (127.0.0.1) peut se comporter de manière incohérente, car la pile réseau Windows le traite de façon particulière
  • TCP MSS clamping non implémenté — si le MTU du chemin de redirection est plus petit, une fragmentation peut se produire

La licence est GPLv3 (WinDivert dépend de LGPLv3).
Les retours / cas d’usage / rapports de bugs sont les bienvenus.

4 commentaires

 
kaydash 11 일 전

C’est donc un proxy, non ?

 
zxsi2003 11 일 전

À proprement parler, on peut davantage voir cela comme du NAT de destination que comme un proxy. Comme l’intitulé ci-dessus est un peu trop long, je récapitule ci-dessous le cas d’usage que j’ai eu.

  1. Je voulais envoyer les requêtes non pas vers la destination du programme client déjà compilé (1.2.3.4.:5000), mais vers le serveur de mon PC local (172.16.100.201:5000).

  2. Comme le chemin de la requête était codé en dur, il fallait souvent demander au développeur du client de refaire un build pour le modifier.

  3. Je voulais résoudre cela non pas au niveau de l’application, mais au niveau du noyau de l’OS, en modifiant la destination et l’en-tête de destination du trafic allant vers une IP et un port spécifiques (1.2.3.4.:5000) vers l’IP et le port souhaités (172.16.100.201:5000).

  4. Développement de detour

 
findnamo 11 일 전

Est-ce qu’il est aussi possible de proxifier les requêtes saisies sous forme d’adresse de domaine ?

 
zxsi2003 11 일 전

Dans le cas des requêtes saisies sous forme d’adresse de domaine, nous avons estimé que la complexité de l’implémentation augmentait, donc la saisie est bloquée dès le départ... Comme cela a été développé pour des tests internes, cela ne prend pas en charge des fonctionnalités génériques.
Il est possible de trouver l’IP correspondant à un domaine donné avec nslookup, puis de la configurer.

Nous essaierons de l’intégrer dans une prochaine mise à jour.