Redirection de port sous Linux : 1/2

J'ai depuis quelques temps une problématique à résoudre pour un client : accéder depuis l'extérieur à un sous-réseau, ou tout au moins à certains services, sur un réseau pour lequel je ne peux pas être routé. Pour Microsoft la chose était facile, on installe un serveur PPTP sur le réseau autorisé (routé) et à partir de là tout devient facile. Sauf qu'en 2021 même Microsoft déconseille le PPTP, et pour cause ! Et bien sur il n'est pas question d'exposer ces services sur internet via une simple redirection de ports...

J'ai pensé bien sur à une solution de type SDN (Zerotier, Wireguard ou Tailscale pour faire facile). Tous les 3 vont me permettre de router des réseaux distants, mais ça ne fonctionnera pas car je ne peux pas disposer du routage inverse, donc dans le meilleur des cas je pourrais atteindre le réseau distant. De plus je serais vu comme une adresse source suspecte, l'IP Zerotier par exemple...

Afin qu'elle soit valide sur les sous réseaux distants, il faut que mon adresse source soit une IP autorisée, donc une IP du réseau distant.

L'alternative pourrait être de faire un bridge (niveau 2) à l'entrée du réseau distant. C'est possible (ici par exemple avec Zerotier), mais, comme chacun le sait, l'inconvénient d'un bridge est de laisser transiter beaucoup trop de saloperies, à moins de sérieusement les filtrer. A explorer. Bref j'en était là peu avant minuit en explorant comment me dépatouiller de cette affaire, je suivait une piste TCP PROXY quand je suis tombé sur un site d'un gentil hacker qui expose sa trousse à outils dans laquelle on trouve RineTD. A noter que TCPProxy sous OpenWRT ou UbuProxy sous Ubuntu sont des déclinaisons plus ou moins améliorées et supportant IPV6, permettant même l'encapsulation dans un tunnel IPV6..

RineTD

Dans la pratique RineTD agit plus ou moins comme les redirecteur de ports que l'on trouve sur un classique routeur grand public, sauf qu'ici il est capable de le faire sur une machine Linux. Il peut s'utiliser sur tous les ports, sauf le FTP qui lui demande des sockets sur les ports différents. Il présente cependant un défaut qui pour moi devient une qualité : l'adresse source sera toujours l'IP LAN de la machine sur laquelle il est installée. Et c'est justement ce que je souhaite.

On part du principe que Zerotier est configuré et on installe :

sudo apt-get install rinetd

Et ensuite on va éditer le fichier de configuration : 

sudo nano /etc/rinetd.conf
#localip localport remoteip remoteport

0.0.0.0      80  192.168.1.90  8080  # Ecoute sur toutes les IP sur le port 80 et redirection vers 192.168.1.90 sur le port 8080
10.146.50.50 25  192.168.1.50  25    # Ecoute sur toutes l'IP 10.146.50.50 sur le port 25 et redirection vers 192.168.1.50 sur le port 25

logfile /var/log/rinetd.log          # Le fichier de log...

allow IP                             # Ici on gère les IP source autorisée à utiliser le service...
deny 192.168.2.15
allow 10.146.50.*

Et il faudra relancer le service à chaque changement de configuration :

sudo /etc/init.d/rinetd restart

Et c'est tout !

Maintenant si depuis la machine 10.146.50.10 de mon réseau Zerotier je fais un telnet 10.146.50.50 25 je vais tomber sur le serveur SMTP qui se trouve en 192.168.1.50 et lui me verra comme étant 192.168.100.50 qui est l'IP LAN de la machine sur laquelle tourne RineTD.

TCP Proxy sous OpenWRT

Bon, maintenant j'aimerais bien faire la même chose sur OpenWRT. Ici ce qui m'intéresse c'est de faire tourner ça sur un micro routeur, le GL-MT300N car avec sa taille proche d'une boite d'allumettes pour une vingtaine d'€uros on va pouvoir le caser l'importe ou...

On le mets donc à jour dans sa dernière version et on commence par lui installer Zerotier en SSH :

opkg update
opkg install zerotier

Ensuite on édite le fichier de configuration idoine avec vi. (Confidence, je crois que c'est ma première avec VI ! ESC + :wq! pour sauvegarder et ESC + :q! pour juste quitter...)

vi /etc/config/zerotier
# cat /etc/config/zerotier
config zerotier 'sample_config'
    option enabled '1'
    list join 'd5e5fb6537869a7d'  # Que l'on remplace par son ID Zerotier

On passe ensuite à la configuration du firewall si on veut accéder au LAN

vi /etc/config/firewall

Et on ajoute :

config zone 'vpn_zone'
    option name 'zerotier'
    option input 'ACCEPT'
    option forward 'REJECT'
    option output 'ACCEPT'
    option device 'zt+'
    option masq '1'
    option mtu_fix '1'

config forwarding
    option dest 'zerotier'
    option src 'lan'

config forwarding
    option dest 'lan'
    option src 'zerotier'

Et on redémarre tout ça avec :

/etc/init.d/zerotier restart
/etc/init.d/firewall restart

Normalement à ce stade on doit pouvoir pinguer l'IP Zerotier et LAN du routeur depuis puis un client distant.

On passe donc à l'installation de TCPProxy :

opkg install tcpproxy

 Ensuite on édite sa configuration

vi /etc/config/tcpproxy
config listen
  option disabled 0                    # 1 ou 0 pour activer ce port car il peut y en avoir plusieurs
  option local_port '9000'             # Le port d'écoute
  option resolv 'ipv4'                 # Ca peut aussi travailler en IPV6...
  option remote_addr '192.168.210.16'  # L'IP du serveur distant
  option remote_port '8000'            # Son port
  option local_addr '10.147.80.48'     # L'IP locale sur laquelle on écoute​
Et bien sur on redémarre le service :
/etc/init.d/tcpproxy restart

Pour mon test j'ai installé un mini serveur web afin de valider l'adresse source, donc http://10.147.80.48:9000 et quand je vais dans son log je constate que l'IP source est bien 192.168.210.48 qui est l'IP LAN de mon micro routeur.

Alternative

Vous avez noté que je suis toujours passé par Zerotier, par habitude surement. Mais on peu aussi passer par WireGuard qui est de base installé sur ces micro routeurs.

Du coup j'ai acheté un autre micro routeur, le GL-AR300M qui lui est noir et un peu plus puissant. L'interface permet de configurer le serveur WireGuard et de générer la configuration du client qu'il suffira de copier sur le poste distant :

[Interface]
Address = 10.0.0.2/32
ListenPort = 13925
PrivateKey = +LsVmc6LVmdjfggmjgfmjùsgsdkfg3+A0hNncpxcHw=
DNS = 64.6.64.6

[Peer]
AllowedIPs = 192.168.10.0/0, 10.0.0.1/32  # Ici les réseaux que je vais router sur le client
Endpoint = 69.69.69.69:51820
PersistentKeepalive = 25
PublicKey = yeNCdjgfùsjdfùgjùfj*gsd*fgklsfkgsfdg k807pxs6iidhM=

Pour mon usage je pourrais me contenter de renseigner uniquement 10.0.0.1/32 dans AllowedIPs puisque TCPProxy prendra le relais...

Débit

GL-iNet nous assure qu'il est possible de soutenir 50 Mbps avec WireGuard en opposition aux 15 Mbps possibles avec OpenVPN.

Bonus

  • Si votre routeur de test n'est pas en en bridge ou en DMZ, pensez à rediriger vers lui le port UDP idoine pour Zerotier ou WireGuard.
  • Curieusement sur ces micro routeurs le serveur DHCP n'est pas facilement désactivable depuis l'interface, et dans mes bricolages j'ai déjà un serveur DHCP et je ne voudrais pas que celui ci interfère. On doit pouvoir faire ça en éditant /etc/config/dhcp, mais on peu également dans les options avancées installer LUCI, éditer l'interface LAN et lui dire d'ignorer le DHCP sur cette interface.
  • Ce n'était pas mon besoin, mais ces micro routeurs peuvent également êtres configurés en client VPN (WireGuard ou OpenVPN), en client Tor, voire même en répéteur WI-FI très pratique quand on est à l'hôtel avec une seule connexion possible. Dans ce dernier cas il vaut mieux également combiner avec le client VPN...
  • J'ai fait ces manips sur ces routeurs, mais n'importe quel Linux fera tourner WireGuard, une petit tuto ici ou en site to site ici.

Voilà !

Les barbus vont surement trouver à redire et me proposer une autre façon de faire et je serais curieux de qu'ils vont me proposer. En attendant je suis content de moi et ma pauvre culture Windows...

Il semblerait que Rinetd comporte une limitation du nombre de connexions. Il existe également Socat, plus de connexion, mais plus de RAM, ou en encore Redir qui semble moins gourmand. Et bien sur pour un usage plus conséquent il ne faut oublier HAProxy qui est surtout un équilibreur de charge http, https et TCP, mais peut être utilisé pour transférer le trafic Tcp uniquement en utilisant légèrement le processeur et la RAM. Mais HAProxy vous ne l'installerez pas sur un petit routeur...

Mais il existe une autre voie : IpTables ! Son utilisation ne consomme pas de CPU et très peu de RAM, et surtout ça fait partie du système d’exploitation ! Ce sera l'objet du prochain article...

Idées...

On l'a vu ces petits routeurs sont très discrets. Pour mes tests ils sont configurés avec deux interfaces LAN et WAN, LAN et WAN pouvant très bien être WLAN et WWAN... Mais prenons un autre cas de figure, vous devez accéder à un réseau de façon discrète (discrète mais autorisée, je vous rappelle que ce genre de délit relève du pénal et est passible de la case prison). Bref, par exemple le responsable d'une entreprise cliente vous demande (demande écrite pour vous couvrir) une telle solution à l'insu de son service informatique, vous préconfigurez un tel routeur en client DHCP sur le LAN et en serveur Wireguard et le tour est joué. Accès possible au LAN, voire plus via TCPProxy. Et bien sur l'administration du routeur en web et ssh reste possible via le client Wireguard...