2 points par GN⁺ 2024-04-03 | 1 commentaires | Partager sur WhatsApp
  • Wireproxy est un client WireGuard entièrement en espace utilisateur qui se connecte à un pair WireGuard puis s’expose sur la machine locale sous forme de proxy SOCKS5/HTTP ou de tunnel
  • Il vise les cas où l’on veut envoyer uniquement le trafic de certains sites vers un pair WireGuard sans configurer de nouvelle interface réseau, ou lorsque l’on ne veut pas utiliser de privilèges root pour modifier la configuration WireGuard
  • Les fonctionnalités incluent le routage statique TCP, les proxys SOCKS5/HTTP et un proxy TLS transparent basé sur le SNI ; le proxy HTTP ne prend actuellement en charge que CONNECT
  • La configuration reprend la sémantique de [Interface] et [Peer] de wg-quick, permet d’importer un fichier de configuration WireGuard existant via WGConfig ou de router plusieurs pairs avec AllowedIPs
  • Pour l’exploitation, un health endpoint basé sur --info/-i est fourni, avec /metrics et /readyz pour vérifier l’état de WireGuard et l’état de disponibilité basé sur CheckAlive

Ce que fait Wireproxy

  • wireproxy est une application en espace utilisateur qui se connecte à un pair WireGuard et expose sur la machine locale un proxy SOCKS5/HTTP ou un tunnel
  • Il peut être utilisé lorsqu’on souhaite accéder à certains sites uniquement via un pair WireGuard, sans créer de nouvelle interface réseau
  • Il fonctionne de manière totalement séparée de l’interface réseau et ne nécessite pas de privilèges root pour sa configuration
  • Les utilisateurs ayant besoin d’un usage similaire à Amnezia VPN peuvent utiliser le fork wireproxy-awg

Fonctionnalités prises en charge et manquantes

  • Fonctionnalités prises en charge
    • Routage statique TCP pour le client et le serveur
    • Proxy SOCKS5/HTTP
      • HTTP ne prend actuellement en charge que CONNECT
    • Proxy TLS transparent utilisant le Server Name Indication
  • Fonctionnalités restant en TODO
    • Prise en charge de l’UDP pour SOCKS5
    • Routage statique UDP

Exécution et installation

  • Le format d’exécution de base est ./wireproxy [-c path to config]
  • Options principales
    • -c, --config : spécifie le chemin du fichier de configuration
      • Les chemins par défaut sont /etc/wireproxy/wireproxy.conf, $HOME/.config/wireproxy.conf
    • -s, --silent : mode silencieux
    • -d, --daemon : exécution en arrière-plan
    • -i, --info : spécifie l’adresse et le port pour exposer l’état de santé
    • -v, --version : affiche la version
    • -n, --configtest : vérifie uniquement la validité du fichier de configuration
  • La compilation s’effectue en clonant le dépôt puis en lançant make
  • Exemple d’installation : go install github.com/windtf/wireproxy/cmd/wireproxy@v1.1.2 ou @latest

Modèle de configuration

  • Les paramètres [Interface] et [Peer] ont la même signification que dans la configuration wg-quick
  • Address doit utiliser un sous-réseau /32 pour IPv4 et /128 pour IPv6
  • PrivateKey peut aussi référencer une variable d’environnement
  • Si vous avez déjà une configuration WireGuard existante, vous pouvez l’importer avec WGConfig = <path to the wireguard config>

Configuration des tunnels et proxys

  • TCPClientTunnel
    • Transmet via WireGuard le trafic TCP reçu sur la machine locale vers une destination spécifiée
    • Exemple de flux : <appli LAN> → localhost:25565 → WireGuard → play.cubecraft.net:25565
  • TCPServerTunnel
    • Transmet vers une destination spécifiée du réseau local le trafic TCP reçu depuis le réseau WireGuard
    • Exemple de flux : <appli réseau WireGuard> → WireGuard → 172.16.31.2:3422 → localhost:25545
  • STDIOTunnel
    • Connecte l’entrée et la sortie standard du processus wireproxy à une cible TCP via WireGuard
    • Utile pour le paramètre ProxyCommand de openssh
  • Socks5
    • Crée un proxy SOCKS5 sur le LAN local et route tout le trafic via WireGuard
    • Si un nom d’utilisateur et un mot de passe sont spécifiés, l’authentification du proxy est activée
  • http
    • Crée un proxy HTTP sur le LAN local et route tout le trafic via WireGuard
    • Si un nom d’utilisateur et un mot de passe sont spécifiés, l’authentification est activée
    • Si CertFile et KeyFile sont spécifiés, HTTPS est activé
  • SNI
    • Crée un proxy TLS transparent sur le LAN local et envoie le trafic via WireGuard en utilisant le SNI comme destination de routage

Plusieurs pairs et routage

  • Il est possible d’utiliser plusieurs pairs WireGuard
  • Lorsqu’on utilise plusieurs pairs, il faut définir AllowedIPs pour que wireproxy sache vers quel pair transmettre
  • L’exemple de configuration utilise plusieurs [Peer] avec des AllowedIPs différents ainsi que plusieurs TCPServerTunnel
  • Un exemple UDPProxyTunnel est également inclus
    • BindAddress définit l’adresse locale de binding
    • Target définit l’adresse cible
    • Si InactivityTimeout vaut 0, aucun timeout n’est appliqué
  • [Resolve] configure la stratégie de résolution DNS
    • ipv4 : donne la priorité aux enregistrements A
    • ipv6 : donne la priorité aux enregistrements AAAA
    • auto : valeur par défaut ; si l’interface WireGuard n’a qu’une adresse IPv4, cela équivaut à ipv4, sinon à ipv6
  • Une configuration [Peer] sans Endpoint peut permettre à un pair de se connecter à wireproxy

Health endpoint

  • --info/-i accepte une adresse et un port, par exemple localhost:9080, et expose un serveur HTTP fournissant des métriques d’état de santé
  • Deux endpoints sont actuellement implémentés
    • /metrics : expose les informations du démon WireGuard et fournit des informations similaires à wg show
    • /readyz : renvoie en JSON l’heure de réception du dernier pong depuis l’IP spécifiée dans CheckAlive
  • Si CheckAlive est configuré, un ping est envoyé via WireGuard vers l’adresse indiquée toutes les CheckAliveInterval secondes
    • La valeur par défaut de CheckAliveInterval est de 5 secondes
    • Si aucun pong n’est reçu dans la dernière fenêtre de CheckAliveInterval secondes, avec une marge de latence supplémentaire de 2 secondes, la réponse est 503
    • Si la condition est remplie, la réponse est 200
  • Si CheckAlive n’est pas configuré, /readyz renvoie un objet JSON vide avec un code 200
  • Le pair par lequel les paquets ICMP ping sont routés dépend du paramètre AllowedIPs de chaque pair

1 commentaires

 
GN⁺ 2024-04-03
Avis sur Hacker News
  • Petit outil, mais excellent. Je l’utilise avec les multi-account containers de Firefox pour sélectionner seulement certains onglets et les proxifier vers un routeur domestique qui prend en charge WireGuard, mais pas les proxys au niveau applicatif ni SSH.

    • Je viens d’apprendre que multi-account containers prend en charge les paramètres de proxy par conteneur.
      Je pensais qu’il fallait une extension séparée comme https://addons.mozilla.org/en-GB/firefox/addon/container-pro... pour configurer ça, mais non, et apparemment ce genre de méprise vaut maintenant des votes négatifs.
    • Je serais curieux de voir une bonne ressource expliquant comment mettre en place ce type de configuration.
  • Pour ce que je voulais faire avec WireGuard, https://github.com/dariost/soks convenait mieux. Il fait à peu près la même chose, mais réutilise une interface WireGuard existante.
    J’ai détaillé son utilisation dans cet article : https://www.nicoco.fr/blog/2023/09/10/wireguard/

    • C’est assez différent. wireproxy semble inclure une implémentation de TCP et de WireGuard en espace utilisateur, tandis que soks ressemble davantage à un routeur IP qui ne peut gérer que TCP.
      On dirait qu’au lieu d’utiliser la table de routage comme mécanisme de contrôle, il décide d’utiliser ou non le proxy SOCKS5.
    • Je suis curieux de savoir pourquoi cette solution convenait mieux.
      Par le passé, je faisais quelque chose de similaire avec un conteneur Docker sur Raspberry Pi, mais une solution en espace utilisateur semble bien préférable, car elle peut fonctionner sur n’importe quel système d’exploitation et garantit de ne pas casser par erreur la table de routage de l’hôte.
  • Il y a aussi onetun : https://github.com/aramperes/onetun

  • Je me demande s’il existe aussi une implémentation serveur entièrement en espace utilisateur. Pour faire ça sans périphérique tun/tap, il faudrait sans doute une sorte de pile IP en espace utilisateur, mais je n’en suis pas sûr.

  • Ce serait bien pour remplacer les tunnels SSH que j’utilisais quand j’avais besoin d’une autre IP.
    Dans les outils apparentés, il y a aussi pproxy, qui peut notamment « convertir » différents protocoles de tunnel entre eux et propose aussi des fonctions de routage. Je l’ai utilisé pour transformer un SOCKS5 SSH en proxy HTTP : https://github.com/moreati/pproxy

  • Je me suis dit : « Ça devrait être assez facile à faire en Go, non ? », et effectivement, c’était écrit en Go.

  • Plusieurs clients proxy multiprotocoles prennent en charge cette fonctionnalité. Parmi les exemples open source notables, on trouve sing-box, clash-meta et d’autres clients basés sur clash, ainsi que xray.
    Côté clients propriétaires, il y a Surge Mac/iOS.

    • C’est vrai. Ces proxys multiprotocoles ont probablement été créés pour contourner le pare-feu chinois, et forment un petit écosystème intéressant.
      Ils offrent beaucoup de possibilités de routage du trafic peu connues, et il existe aussi des implémentations Android. Je m’en étais servi autrefois pour ouvrir un hotspot avec une SIM qui ne prenait pas en charge le partage de connexion, sur un Android non rooté.
      Cela dit, ils intègrent beaucoup de code récupéré un peu partout sur Internet, et la communauté de développeurs est assez particulière pour diverses raisons, donc je me demande toujours à quel point on peut leur faire confiance.
    • Côté propriétaire, Cloudflare WARP peut aussi fonctionner en mode proxy. Si l’on convertit la configuration WARP en configuration WireGuard standard, on peut même l’utiliser ainsi avec un compte gratuit.
    • En Chine, clash + v2ray semble à peu près la seule solution qui fonctionne de manière fiable. La plupart des grands fournisseurs de VPN prétendent fonctionner en Chine, mais en pratique ce n’est pas le cas.
      Je n’ai pas creusé en détail son fonctionnement, mais j’aime bien l’idée de décider via des groupes de règles quels domaines doivent être proxifiés par le VPN.
  • Je suis curieux de connaître les performances. De mémoire, le SOCKS « vanilla » est très facile à configurer — en gros, il suffit de lancer SSH avec les bonnes options et de dire à l’application de l’utiliser — mais il était assez lent.
    Cet outil semble destiné aux cas où l’on n’a pas de serveur SOCKS/SSH classique, mais je me demande s’il apporte aussi un avantage de ce côté-là.

    • Je me demande ce que signifie SOCKS « vanilla ». Je ne vois pas à quelle autre implémentation de SOCKS cela s’oppose.
      Dans mon cas, SOCKS au-dessus de SSH a toujours eu de très bonnes performances, et ce n’était pas comparable à des approches qui empilent TCP sur TCP, comme le mode TUN d’OpenSSH.
    • Ce serait intéressant de comparer les deux. Pour l’instant, je me connecte à WireGuard puis je crée un proxy SOCKS avec SSH, et ça fonctionne étonnamment bien.
      Cela dit, cette solution m’intéresse beaucoup.
  • Je venais justement de me dire qu’il me faudrait un outil pour proxifier toutes les connexions e-mail de Thunderbird via un exit node Tailscale, sans pour autant envoyer tout le trafic vers cet exit node.

    • On peut utiliser le CLI tailscale comme proxy SOCKS : https://tailscale.com/kb/1113/aws-lambda
      Il suffit de le mettre dans une image de conteneur et d’exposer le port SOCKS sur lequel tailscale écoute, et on obtient directement un proxy.
    • On peut aussi installer 3proxy ou squid proxy sur la machine qui exécute l’exit node. Toutes les machines du tailnet pourront le voir.
  • Si vous avez besoin de quelque chose comme ça spécifiquement pour Mullvad VPN, j’ai essayé https://github.com/imiric/mullvad-proxy et j’ai trouvé ça bien.
    Ce n’est pas mon projet, je l’ai seulement forké pour des mises à jour. Son avantage, c’est qu’il intègre l’outil CLI de Mullvad, ce qui rend le changement de serveur très simple, et que tout est isolé de la machine hôte. En plus, ce n’est « que » nginx avec quelques scripts, donc la prise en charge de SOCKS5 devrait aussi être correcte.