Imagine you are in a situation where you are using ISP which do censorship based on DNS. We might use free DNS service but quite often ISP will hijack the traffic and redirect them to their DNS. Another approach is using tool which transfer DNS traffic on top of encrypted channel, for example dnscrypt. However in this article we won’t use this approach. I will give insight about another approach, doing it by ourselves.

We will have three entities involved:


SERVER is an endpoint of SSH tunnel. NAMESERVER is DNS server, which we will contact. It can be a internal DNS server on SERVER’s network, or it can be SERVER itself. LOCAL is our local machine.

The idea is simple:

  • creating a SSH tunnel between LOCAL and SERVER
  • setup TCP to UDP forward on SERVER
  • setup UDP to TCP forward on LOCAL

Create SSH Tunnel

On LOCAL, connect to SERVER by SSH. We need additional -L option so that SSH will do TCP port forwarding.

This will allow TCP connection to port 13510 of local machine to be forwarded to the port number 13511 on SERVER. Of course, replace LOCAL and SERVER as we need.

Setup TCP to UDP Forward on SERVER

On the server we open listener on port 13511 which will forward data to UDP port 53 of specified IP, or NAMESERVER to be precise. There are two approach, whether you want to use netcat or socat.


We need to create a fifo. The fifo is necessary to have two-way communication between two channels. A pipe won’t do because it only transfer data from STDOUT of left process to STDIN of right process.

This will have bidirectional communication, from SERVER:13511 to NAMESERVER:53 and vice-versa


Socat is bidirectional by nature, so we don’t need to create a fifo.

see socat cheatsheet for more info on socat capability.

Setup UDP to TCP Forward on LOCAL

On LOCAL we need a privilege access to bind on port 53. Other than that, it’s only bit opposite of what we have done on SERVER.


This will have bidirectional communication, from LOCAL:53 to LOCAL:13510 and vice-versa


Again, socat is bidirectional by nature.

see socat cheatsheet for more info on socat capability.


As mentioned, our traffic now flow like this LOCAL:53 – LOCAL:13510 – SSH TUNNEL – SERVER:13511 – NAMESERVER:53 for request. To test DNS service on local machine, use host


Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">