Trafic UDP via le tunnel SSH

66

Le titre le résume assez bien. Je souhaite envoyer du trafic UDP via un tunnel SSH. Plus précisément, je dois pouvoir envoyer des paquets UDP via le tunnel et que le serveur puisse me les renvoyer de l'autre côté. Je sais comment faire pour les connexions TCP. Est-ce possible avec UDP?

lourd
la source

Réponses:

36

Ce petit guide explique comment envoyer du trafic UDP via SSH à l'aide d'outils fournis en standard (ssh, nc, mkfifo) avec la plupart des systèmes d'exploitation de type UNIX.

Réalisation de tunnels UDP via une connexion SSH

Étape par étape Ouvrez un port de transfert TCP avec votre connexion SSH

Sur votre ordinateur local (local), connectez-vous à l'ordinateur distant (serveur) via SSH, avec l'option -L supplémentaire afin que SSH avec transfert de port TCP:

local# ssh -L 6667:localhost:6667 server.foo.com

Cela permettra aux connexions TCP sur le numéro de port 6667 de votre ordinateur local d'être transférées vers le numéro de port 6667 sur server.foo.com via le canal sécurisé. Configurez le transfert TCP vers UDP sur le serveur

Sur le serveur, nous ouvrons un écouteur sur le port TCP 6667 qui transférera les données au port UDP 53 d’une adresse IP spécifiée. Si vous voulez faire le transfert DNS comme moi, vous pouvez utiliser l'adresse IP du premier serveur de noms que vous trouverez dans /etc/resolv.conf. Mais d’abord, nous devons créer un fifo. Le fifo est nécessaire pour établir une communication bidirectionnelle entre les deux canaux. Un canal de communication simple ne communiquerait que la sortie standard du processus de gauche avec l'entrée standard du processus de droite.

server# mkfifo /tmp/fifo
server# nc -l -p 6667 < /tmp/fifo | nc -u 192.168.1.1 53 > /tmp/fifo

Cela permettra au trafic TCP sur le port 6667 du serveur d'être transféré au trafic UDP sur le port 53 de 192.168.1.1 et aux réponses de revenir. Configurez l'UDP pour le transfert TCP sur votre machine

Maintenant, nous devons faire le contraire de ce qui a été fait en haut sur la machine locale. Vous devez disposer d’un accès privilégié pour lier le port UDP 53.

local# mkfifo /tmp/fifo
local# sudo nc -l -u -p 53 < /tmp/fifo | nc localhost 6667 > /tmp/fifo

Cela permettra au trafic UDP sur le port 53 de la machine locale d'être transféré au trafic TCP sur le port 6667 de la machine locale. Profitez de votre serveur DNS local :)

Comme vous l'avez probablement deviné, lorsqu'une requête DNS sera effectuée sur la machine locale, par exemple sur le port UDP local 53, elle sera transmise au port TCP local 6667, puis au port TCP du serveur 6667, puis au serveur DNS du serveur. , Port UDP 53 de 192.168.1.1. Pour profiter des services DNS sur votre ordinateur local, insérez la ligne suivante en tant que premier serveur de noms dans votre fichier /etc/resolv.conf:

nameserver 127.0.0.1
John T
la source
28
Cette solution n'est pas sûre. Les flux TCP ne sont pas garantis pour préserver les limites des messages, de sorte qu'un même datagramme UDP peut être fractionné en plusieurs parties, rompant ainsi tout protocole.
Juho Östman
2
Il pourrait également être intéressant d’utiliser le port 1153 au lieu de 6667 (exemple man SSH), qui est utilisé par IRC.
phil pirozhkov
1
@ JuhoÖstman Merci d'avoir signalé ce piège. Etre conscient du problème ... avez-vous trouvé une solution? Des messages assez petits seraient-ils un moyen de le rendre susceptible de fonctionner?
humanitepeace
4
La solution consisterait à ajouter une longueur à chaque paquet avant son envoi dans le flux TCP et à en reconstruire les paquets d'origine. Il serait facile d'écrire un script C pour le faire, mais je ne suis pas sûr qu'il existe une solution facilement disponible. En pratique, le TCP semble généralement préserver les limites des messages, mais des défaillances étranges peuvent survenir à tout moment.
Juho Östman
J'ai fait face à un autre problème avec ceci: le tuyau et le fifo sont tamponnés, les limites du cadre sont donc perdues. Tant de trames UDP peuvent être concaténées dans une trame TCP.
Julio Guerra
26

Cet exemple (je pense que la réponse de John indique la même chose à un endroit différent) explique comment accéder aux services UDP / DNS d'un autre ordinateur via une connexion TCP / SSH.

Nous allons transférer le trafic UDP / 53 local vers TCP, puis le trafic TCP avec le mécanisme de transfert de port de SSH vers l'autre machine, puis TCP vers UDP / 53, à l'autre extrémité.
En règle générale, vous pouvez le faire avec openvpn.
Mais ici, nous le ferons avec des outils plus simples, seulement openssh et netcat.

A la fin de cette page, se trouve un autre commentaire avec une référence à ' socat',
le même accès UDP / DNS est fait avec,

Côté serveur: socat tcp4-listen:5353,reuseaddr,fork UDP:nameserver:53
côté client:socat udp4-listen:53,reuseaddr,fork tcp:localhost:5353

Reportez-vous aux exemples socat pour plus d'informations.

nik
la source
3
Celui-ci me semble beaucoup plus utile que la réponse acceptée. J'avais besoin d'une redirection unidirectionnelle de flux vidéo (TS / UDP) ... ssh orig_strm_src socat udp4-listen:4003,reuseaddr,fork STDOUT| socat STDIN udp-sendto:localhost:4003
nhed
FWIW, sur ma page d’accueil , j’ai écrit un guide plus détaillé décrivant comment configurer socat sur SSH pour le transfert UDP. Il utilise SNMP comme exemple.
Peter V. Mørch
20

SSH (au moins OpenSSH) prend en charge les VPN simples. En utilisant l' option -wou Tunneldans le sshclient, vous pouvez créer un tunpériphérique aux deux extrémités, qui peut être utilisé pour transférer tout type de trafic IP. (Voir aussi Tunnella page de manuel de ssh_config(5).) Notez que cela nécessite OpenSSH (et probablement des privilèges root) aux deux extrémités.

Grawity
la source
Cela nécessite des privilèges root sur la machine distante, même pour le tunneling UDP des ports non privilégiés, et que PermitRootLogin ne soit pas défini sur 'non'. Dommage.
phil pirozhkov
@grawity Merci d'avoir signalé cette option, qui même lorsque, comme le souligne philpirozhkov, le nom d'utilisateur root requis. Je me demande s’il peut y avoir un moyen de le tromper en n’ayant pas besoin de la racine?
humanitepeace
4
@humanityANDpeace: Vous pouvez créer à l'avance les périphériques tun / tap et les attribuer à un utilisateur spécifique, à l'aide de ip tuntap add.
grawity
Bonjour @grawity. J'aime votre solution mais je ne peux pas la faire fonctionner. J'ai précréé le tunpériphérique comme suit: sudo ip tuntap add mode tunmais quand j'utilise jamais l' -woption comme ceci: ssh $Server -w $portje reçois Tunnel device open failed. Could not request tunnel forwarding.Qu'est-ce que je fais de mal?
Lucas Aimaretto
16

Ou vous pouvez simplement utiliser ssf (conçu pour gérer ce cas d'utilisation), avec une simple commande:


Côté client:

#>./ssfc -U 53:192.168.1.1:53 server.foo.com

Cette commande redirige le port local 53 (dns) vers le port 192.168.1.1, via un tunnel sécurisé entre localhost et server.foo.com.


Vous aurez besoin d’un serveur ssf (au lieu de - ou à côté de - votre serveur ssh):

#>./ssfs

Soit dit en passant, les côtés client et serveur de ssf fonctionnent sous Windows / Linux / Mac. Ceci est une application utilisateur, vous n'avez donc pas besoin de tun / tap ou de VPN.

Pour rediriger le port 53, vous aurez besoin de privilèges d’administrateur, quel que soit l’outil utilisé.

Pour plus d'informations, de détails, un cas d'utilisation ou un téléchargement: https://securesocketfunneling.github.io/ssf/

développeurs ssf
la source
S'il vous plaît soyez prudent de répondre avec, "voici mon produit", il s'agit de spam spam. Je suggère de lire et de suivre les directives du centre d'aide .
lourd
7
Tout au plus, c'est un bouchon éhonté. Quoi qu'il en soit, la solution peut correspondre à votre demande. Soit dit en passant, SSF est OpenSource et à but non lucratif.
Les développeurs ssf
11
@heavyd: S'il postait un tas de scripts hacky, ce serait acceptable, mais comme il a créé un outil open-source mature, ce n'est pas le cas? Cela répond parfaitement à la question initiale.
Synthead
Je dois admettre à contrecœur que c'est exactement l'outil que je cherchais, même s'il s'agissait d'un bouchon éhonté.
therealrootuser
9

Je ne pouvais pas nctravailler pour SNMP, car les clients SNMP continuaient de choisir un nouveau port UDP source et que plusieurs d'entre eux pouvaient être actifs simultanément.

Au lieu de cela, j'ai écrit un article décrivant comment le faire socatdans ce blog , en utilisant SNMP comme exemple. Essentiellement, en utilisant deux terminaux, en commençant par un aperçu:

vue d'ensemble

Terminal un:

client$ ssh -L 10000:localhost:10000 server
server$ socat -T10 TCP4-LISTEN:10000,fork UDP4:switch:161

Cela crée le transfert SSH du port TCP 10000 et exécute socat sur le serveur. Notez que l’adresse IP du commutateur est mentionnée dans la ligne de commande socat en tant que «commutateur».

Terminal deux:

client$ sudo socat UDP4-LISTEN:161,fork TCP4:localhost:10000

Cela met en place socat sur le client. Ça devrait le faire.

Peter V. Mørch
la source
cela a fonctionné pour moi :)
Paul Fenney
4

Un VPN est une meilleure solution si vous avez accès à un port UDP.

Si vous avez uniquement accès au port TCP SSH, un tunnel SSH est aussi bon qu'un VPN, du moins pour le ping et le retour arrière de paquets.

Michael
la source