Home » Questions » Computers [ Ask a new question ]

UDP traffic through SSH tunnel

UDP traffic through SSH tunnel

The title pretty much sums it up. I would like to send UDP traffic through a SSH tunnel. Specifically, I need to be able to send UDP packets through the tunnel and have the server be able to send them back to me on the other side. I know how to do it for TCP connections. Is this it possible with UDP?

Asked by: Guest | Views: 235
Total answers/comments: 4
Guest [Entry]

"This small guide tells you how to send UDP traffic via SSH using tools that come standard (ssh,nc,mkfifo) with most UNIX-like operating systems.

Performing UDP tunneling through an SSH connection
Step by step
Open a TCP forward port with your SSH connection

On your local machine (local), connect to the distant machine (server) by SSH, with the additional -L option so that SSH will do TCP port-forwarding:

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

This will allow TCP connections on the port number 6667 of your local machine to be forwarded to the port number 6667 on server.foo.com through the secure channel.

Setup the TCP to UDP forward on the server

On the server, we open a listener on the TCP port 6667 which will forward data to UDP port 53 of a specified IP. If you want to do DNS forwarding like me, you can take the first nameserver's IP you will find in /etc/resolv.conf.

But first, we need to create a fifo. The fifo is necessary to have two-way communications between the two channels. A simple shell pipe would only communicate left process' standard output to right process' standard input.

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

This will allow TCP traffic on server's port 6667 to be forwarded to UDP traffic on 192.168.1.1's port 53, and responses to come back.

Setup the UDP to TCP forward on your machine

Now, we need to do the opposite of what was done above on the local machine. You need priviledged access to bind the UDP port 53.

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

This will allow UDP traffic on local machine's port 53 to be forwarded to TCP traffic on local machine's port 6667. Enjoy your local DNS server :)

As you've probably guessed, when a DNS query will be performed on the local machine, e.g. on local UDP port 53, it will be forwarded to local TCP port 6667, then to server's TCP port 6667, then to server's DNS server, UDP port 53 of 192.168.1.1. To enjoy DNS services on your local machine, put the following line as first nameserver in your /etc/resolv.conf:

nameserver 127.0.0.1"
Guest [Entry]

SSH (at least OpenSSH) has support for simple VPNs. Using the -w or Tunnel option in the ssh client, you can create a tun device at both ends, which can be used to forward any kind of IP traffic. (See also Tunnel in the manual page of ssh_config(5).) Note that this requires OpenSSH (and probably root privileges) at both ends.
Guest [Entry]

"A VPN is a better solution if you have access to an UDP port.

If you only have access to the TCP SSH port, then an SSH tunnel is as good as a VPN, at least for ping and packet backtracking."
Guest [Entry]

"on ssh server:

sudo ip tuntap add dev tun7 mode tun user SSHUSER
sudo ip addr add 192.168.7.1/30 dev tun7
sudo iptables -t nat -A PREROUTING -p udp -i eth0 --dport PUBLIC_PORT -j DNAT --to-destination 192.168.7.2:LOCAL_PORT
sudo iptables -t filter -A FORWARD -i eth0 -p udp -d 192.168.7.2 --dport LOCAL_PORT -j ACCEPT
sudo iptables -t filter -A FORWARD -i tun7 -o eth0 -j ACCEPT
sudo iptables -t nat -A POSTROUTING -o tun7 -j MASQUERADE
# set ""PermitTunnel point-to-point"" for user SSHUSER in /etc/ssh/sshd_config
sudo sshd -t && sudo systemctl restart sshd

replace eth0 with the interface connected to the internet

on ssh client running udp server:

sudo ip tuntap add dev tun8 mode tun user LOCALUSER
sudo ip addr add 192.168.7.2/30 dev tun8
ssh -v -w 8:7 SSHUSER@REMOTEHOST

you might also need sudo ip link set tun7 up on the remote host and sudo ip link set tun8 up on the local host.

inspired by comment UDP traffic through SSH tunnel"