UDP traffic through SSH tunnel

08
2013-08
  • heavyd

    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?

  • Answers
  • Chris

    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 with TCP port-forward:

    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 upper 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 it now, 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
    
  • grawity

    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.

  • nik

    This example (I think John's answer points the the same thing at a different place), describes how to access another machine's UDP/DNS services over an TCP/SSH connection.

    We will forward local UDP/53 traffic to TCP, then TCP traffic with the port-forwarding mechanism of SSH to the other machine, then TCP to UDP/53 on the other end.
    Typically, you can do it with openvpn.
    But here, we'll do it with simpler tools, only openssh and netcat.

    At the end of that page, is another comment with a reference to 'socat',
    The same UDP/DNS access is made with,

    Server side: socat tcp4-listen:5353,reuseaddr,fork UDP:nameserver:53
    Client side: socat udp4-listen:53,reuseaddr,fork tcp:localhost:5353

    Refer socat examples for more.

  • slhck

    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.

  • Teddy

    I'm sorry to give a non-answer, but you really don't want to do that. What about ICMP? SCTP? What you want is a real encrypted connection, either using real IPsec or some special VPN thing.


  • Related Question

    windows - GUI to tunnel VNC over SSH
  • mrduclaw

    I tend to log into a lot of remote sites, and typically the setup we have is: the gateway is running OpenWRT with an SSH server, there are client machines behind the NAT running UltraVNC. While I have no problems tunneling my VNC connections through that SSH server running on the gateway, lately I've been needing to let other people have access to those machines too.

    I would like a GUI program that would let me set up, in advance, connections to machines and just click to connect to them.

    That is, the software would take care of creating the SSH tunnel and opening the VNC viewer. The goal is that I could give this software to someone else and they'd have a list of machine names they could click on and start using VNC though (they'd be prompted for authentication credentials, but that should be about it).

    Does a software like this exist, or am I going to need to throw together some C# foo?

    Thanks!

    Update:

    With regard to the PuTTY solution:

    This is the way I currently do it. The problem is that my users sometimes need to VNC into multiple machines at once, creating standard profiles like that messes up this solution (e.g., what local port to use without having the user know what to connect to in the VNCViewer software).

    For instance, if I save sessions that are of the form (using the ssh cli-style commands):

    ssh -l username hostname.com -L 5900:remoteHost_number_1:5900
    ssh -l username hostname.com -L 5900:remoteHost_number_2:5900
    ssh -l username hostname.com -L 5900:remoteHost_number_3:5900
    

    When the user connects in VNC, all they need to know is to connect to localhost. The problem arises when they want to connect to both remoteHost_number_1 and remoteHost_number_2 at the same time. Then my user will need to know what port their local machine is listening on, and that's what I'm trying to avoid. For the trivial case of three, this is a non-issue, but when the number of systems is large it becomes a problem. This problem can be further exacerbated when there's hostname1.com, hostname2.com, etc each with a similar number of systems behind the NAT.

    I'd also like to have as few steps in this process as possible as my users aren't typically the most technical bunch.

    Thanks again!


  • Related Answers
  • Journeyman Geek

    putty will do the trick

  • Joril

    For completeness, there is also ssvnc.