In the Super User question UDP traffic through SSH tunnel, it describes how to tunnel DNS trough a SSH tunnel:

First, on the client side, do this:

ssh -N -L 6667:localhost:6667 user@server

Then, on the server side do this:

mkfifo /tmp/fifo
nc -k -l 6667 < /tmp/fifo | nc -u ip_of_dns_server 53 > /tmp/fifo

Finally, back on the client side do this:

mkfifo /tmp/fifo
nc -k -l -u 53 < /tmp/fifo | nc 127.0.0.1 6667 > /tmp/fifo

After that I can do a DNS query as expected, but only for a single request:

client# host m6.fr 127.0.0.1

How can I keep the connection alive for more requests?

TL;DR: don’t use Netcat, use Socat for experiments. It handles anything better.

The reason it’s not working isn’t about the named pipes (even if it’s an ugly method with other problems lurking around) but a limitation of netcat.

Once Netcat receives an UDP connection, it binds to it. So it’s not listening anymore to the port 53, it’s connected to the port that sent the initial packet, exactly as it'd do with TCP. Each time you’re doing a DNS request, the tool will change port and Netcat will never get the request. So only the first request will work.

When you set up your example, try this command before the first query:

netstat -aunp|grep -w 53
udp        0      0 0.0.0.0:53              0.0.0.0:*                           12316/nc.openbsd 

Do the (only working) query and try again netstat:

# netstat -aunp|grep -w 53
udp        0      0 127.0.0.1:53            127.0.0.1:44335         ESTABLISHED 12316/nc.openbsd

As you can see netcat just changed mode: From listening to looping over a connection. Because it’s UDP, Netcat won’t know automatically the “established connection” isn’t there anymore.

I have a proof of concept (that makes it work and shows the problem is related to this UDP mode) but it requires socat in addition to netcat on the client. The goal is to have all requests reach netcat using the same UDP source port. Nothing changes on the server side, but I insert socat at the start of the chain (so the last command) to force the source port of the UDP request to Netcat.

First, on the client side, do this:

ssh -N -L 6667:localhost:6667 user@server

Then, on the server side do this:

mkfifo /tmp/fifo
nc -k -l 6667 < /tmp/fifo | nc -u ip_of_dns_server 53 > /tmp/fifo

Finally, back on the client side do this:

mkfifo /tmp/fifo
nc -k -l -u 5555 < /tmp/fifo | nc 127.0.0.1 6667 > /tmp/fifo

socat udp4-listen:53,reuseaddr,fork udp:127.0.0.1:5555,sourceport=55550,reuseaddr

Now I can make multiple queries.

Before 1st query:

# netstat -aunp|egrep -w '53|5555'
udp        0      0 0.0.0.0:5555            0.0.0.0:*                           12715/nc.openbsd    
udp        0      0 0.0.0.0:53              0.0.0.0:*                           12717/socat         

After 1st:

udp        0      0 127.0.0.1:55550         127.0.0.1:5555          ESTABLISHED 12736/socat         
udp        0      0 127.0.0.1:5555          127.0.0.1:55550         ESTABLISHED 12715/nc.openbsd    
udp        0      0 0.0.0.0:53              0.0.0.0:*                           12717/socat         

After 2nd query:

udp        0      0 127.0.0.1:55550         127.0.0.1:5555          ESTABLISHED 12750/socat         
udp        0      0 127.0.0.1:5555          127.0.0.1:55550         ESTABLISHED 12715/nc.openbsd    
udp        0      0 0.0.0.0:53              0.0.0.0:*                           12717/socat         
udp        0      0 127.0.0.1:53            127.0.0.1:53255         ESTABLISHED 12750/socat         

Socat would suffer the same problem but with the fork option, it listens again, and it appears it detects the previous lost “connection”; I think that causes a delay.

You can get the old behaviour (works once) if you just remove the ,sourceport=55550,reuseaddr part in the socat command.

  • using UDP-RECVFROM instead of UDP-LISTEN should improve socat behaviour (it won't become established) – A.B Sep 14 '16 at 0:17

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.