unsubbed.co

iodine

For networking & VPN, iodine is a self-hosted solution that provides iPv4 over DNS tunnel solution, enabling you to start up a socks5 proxy listener.

A deep look at the ISC-licensed tool that tunnels your internet traffic through DNS queries. No marketing fluff — just what you actually get when you run this.

TL;DR

  • What it is: A free (ISC license) command-line tool that tunnels IPv4 traffic through DNS servers — useful when internet is firewalled but DNS queries still get through [README].
  • Who it’s for: Sysadmins, developers, and security researchers who need network access from restrictive environments (conference captive portals, corporate firewalls, hotel Wi-Fi). Not a tool for non-technical users [README][3].
  • Cost savings: Commercial VPNs run $4–15/month. iodine is free software — your only cost is the VPS running the server side (~$5/month) and a domain you control. Data not available on iodine-specific SaaS alternatives because none exist.
  • Key strength: Genuinely solves a problem nothing else does: getting IPv4 connectivity out of networks where port 53 (DNS) is the only thing that works [README][3].
  • Key weakness: Slow (up to ~1 Mbit/s downstream, significantly less upstream), setup requires domain ownership and DNS delegation, and the project has been in maintenance mode since its last release in April 2023 [website].

What is iodine

iodine is a piece of software — the name has nothing to do with the periodic table — that lets you tunnel IPv4 data through DNS server infrastructure [README]. The trick works because many firewalled networks (hotels, airports, conference halls, some corporate environments) block all outbound traffic except DNS queries. DNS has to work for almost any network to function at all, and iodine exploits that.

The mechanism is not simple UDP-53 port reuse. Instead, data gets sliced into small chunks and sent as legitimate-looking DNS queries, which travel through the recursive resolver chain until they reach a server you control running the iodined daemon. Responses travel back the same way. From the operating system’s perspective, you end up with a virtual network interface (dns0) carrying real IP traffic [3].

The project lives at https://github.com/yarrick/iodine and has accumulated 7,747 GitHub stars over roughly 15 years of existence. It’s authored under the ISC license, which is functionally equivalent to MIT — do what you want, keep the copyright notice. The latest release, version 0.8.0, shipped on April 17, 2023. Before that, v0.7.0 was the stable version for several years. The pace of development is slow; this is mature, stable software rather than an actively growing product [website].

iodine runs on Linux, macOS, FreeBSD, NetBSD, OpenBSD, and Windows. It requires a TUN/TAP device, which all of those platforms support either natively or via drivers [README].


Why people choose it

The use case is specific enough that “why people choose it” really means “why people need it”: there is no substitute when DNS is the only thing getting through.

The security research community has written about iodine extensively as both a tunneling technique and a detection/defense topic [3]. The weberblog.net walkthrough — one of the most thorough practical write-ups available — demonstrates a full setup between a delegated subdomain and a VPS, including the client-side negotiation sequence that auto-detects optimal DNS query types and fragment sizes [3]. What comes through clearly is that the setup, while not trivial, produces a working tunnel in under 20 minutes for anyone comfortable with the Linux command line.

Three things distinguish iodine from other DNS tunnel implementations, according to its own documentation:

Higher performance. iodine uses the NULL DNS record type for downstream traffic, which means the data doesn’t need base64 or other encoding — each DNS reply can carry over a kilobyte of compressed payload. This is why iodine’s benchmarks are usually better than alternatives like dns2tcp [README].

Cross-platform portability. The tunnels work regardless of whether server and client have different byte ordering or operating systems [README].

Simpler multi-user setup. Up to 16 users can share one iodined server instance simultaneously, and the server handles IP assignment for tunnel interfaces automatically [README].

The security properties are intentionally limited: iodine uses challenge-response login secured by an MD5 hash. That means authentication exists, but the tunnel traffic itself is not encrypted by iodine. If you need confidentiality, you layer something like WireGuard or SSH inside the tunnel [README]. The MD5 approach is 2005-era security — functional for keeping randos out of your tunnel, not meaningful confidentiality in a threat model with active adversaries.


Features

Based on the README and the technical write-up at weberblog.net:

Core tunneling:

  • Tunnels IPv4 over DNS using NULL, CNAME, MX, TXT, or A record types — auto-detects the best available type [3]
  • Raw UDP mode: if iodine detects that direct UDP to port 53 of the server is possible, it switches to raw mode, bypassing DNS entirely and getting better performance [README][3]
  • Up to 1 Mbit/s downstream; upstream is substantially lower due to DNS query size limits [website]
  • Automatic maximum fragment size probing — iodine tests and finds the optimal downstream packet size for your network path [3]
  • MTU of ~1130 bytes on the tunnel interface (vs. 1500 on Ethernet) [3]

Multi-user and server:

  • Up to 16 simultaneous clients per server [README]
  • Server handles tunnel IP assignment automatically [README]
  • -c flag to disable IP checking (useful for clients behind NAT) [README]
  • DNS forwarding mode: if your server already runs a DNS daemon, iodined can forward non-tunnel queries to it (with caveats — zone transfers won’t work) [README]

Security:

  • Password-based authentication with MD5 challenge-response [README]
  • Source IP filtering — drops packets not coming from the authenticated client IP [README]
  • No built-in encryption — tunnel your traffic over SSH or WireGuard if you need it [README]

Platform support:

  • Linux (with optional SELinux and systemd integration if headers are present)
  • macOS, FreeBSD, NetBSD, OpenBSD
  • Windows (32-bit and 64-bit binaries available) [website]
  • Android (separate build) [website]

Diagnostics:

  • The project offers an online checker at https://code.kryo.se/iodine/check-it/ to verify your DNS setup before deploying [3][website]
  • The weberblog post includes the full client negotiation output, which shows exactly what’s happening during connection setup [3]

What it doesn’t do:

  • IPv6 tunneling (IPv4 only)
  • Encryption (intentionally out of scope)
  • GUI of any kind
  • Automatic certificate/TLS management

Pricing: SaaS vs self-hosted math

There is no SaaS version of iodine. The tool is pure open source, and there’s no hosted offering.

What you need to run it:

  • A domain you control (or a subdomain you can delegate) — already costs you something if you have a domain, ~$10-15/year if you don’t
  • A VPS with a public IP for the server side: $3-6/month on Hetzner or Contabo
  • The iodine software itself: free (ISC license)

What you’d pay for commercial alternatives that solve the “restricted network” problem:

  • NordVPN, ExpressVPN, Mullvad: $4-12/month, work via OpenVPN or WireGuard — which means they only help when those protocols get through
  • Cloudflare WARP: free for personal use, but also relies on WireGuard and port 2408/UDP, which may still be blocked
  • Commercial “DNS VPN” or tunnel services: pricing data not available for this category; few established players exist

The iodine self-hosted approach saves you the monthly VPN subscription only if you actually need DNS tunneling specifically. If a regular VPN gets through your network, iodine is overkill — use WireGuard. iodine’s value is in the niche case where literally nothing else works.

Realistic all-in cost: $3-6/month (VPS) + ~$1/month amortized (domain) = $4-7/month for infrastructure you control, with no data caps and no log policy questions.


Deployment reality check

This is not a point-and-click tool. The setup requires several moving parts working correctly [README][3]:

Server prerequisites:

  • A domain or subdomain you can create NS records for
  • An A record pointing the NS hostname to your server’s public IP (CNAMEs don’t work here — DNS spec requires NS targets to be A records)
  • A VPS with root access running Linux (other platforms work but Linux is the common case)
  • UDP port 53 accessible on the server (or a different port with -p)

The DNS delegation step is the friction point. You add two lines to your zone file or registrar DNS panel: an NS record delegating t1.yourdomain.com to your server’s name, and an A record giving that name an IP [README]. This is a standard DNS operation, but it’s not something most non-technical users will have done before. You also have to wait for DNS propagation before testing, which adds friction during setup.

What the weberblog.net walkthrough shows [3]:

  • Server command: sudo iodined -f -c -P passphrase 192.168.99.1 t1.yourdomain.com
  • This opens a dns0 interface with a /27 tunnel network
  • Client command: sudo iodine -f -P passphrase -r [dns-server-ip] t1.yourdomain.com
  • The client negotiates query type, fragment size, and encoding automatically
  • Full connection output is verbose — you can see exactly what’s happening

Time estimate: A technical user who has set up NS delegations before: 30-45 minutes including propagation wait. Someone doing DNS delegation for the first time: 2-3 hours including debugging. The project’s check-it tool at https://code.kryo.se/iodine/check-it/ helps validate the DNS setup before you bother with the daemon [3][website].

What can go wrong:

  • DNS propagation delays mean changes take time to take effect — patience required
  • Some recursive resolvers strip or modify NULL records, forcing iodine to fall back to less efficient record types
  • Corporate DNS infrastructure may block or inspect tunneled queries — detection and blocking is documented [3]
  • Protocol version must match exactly between server and client — running different iodine versions on each end will fail with a version mismatch error [README]
  • The project’s mailing list and IRC channel (#iodine on IRCnet) are the support options — no issue tracker with active maintainer responses [website]

Pros and Cons

Pros

  • Solves a unique problem. If DNS is the only thing getting out of your network, nothing else gives you what iodine gives you. This is its entire value proposition and it delivers [README][3].
  • ISC license. Maximally permissive. Use it however you want without a lawyer [website].
  • Cross-platform. Linux, macOS, BSDs, Windows, Android — same tool everywhere [README][website].
  • NULL record optimization. Using NULL-type DNS responses for downstream traffic is smarter than competitors that base64-encode everything — meaningfully better throughput [README].
  • Multi-client support. Up to 16 simultaneous users on one server, with automatic IP assignment — usable as a shared emergency escape hatch [README].
  • Mature and stable. It has been working for 15+ years. The codebase is small (~100KB source tarball), auditable, and the core functionality doesn’t change [website].
  • Online DNS checker. The check-it tool at https://code.kryo.se/iodine/check-it/ saves significant debugging time [3][website].

Cons

  • Slow by design. DNS is not a transport protocol. Bandwidth caps around 1 Mbit/s downstream and less upstream — streaming video is not happening, though SSH sessions and web browsing work [README][website].
  • High latency. Each packet traverses the DNS resolver chain. Expect 20-50ms of added latency on a good path — the weberblog ping output showed ~20-26ms round-trip just for the tunnel overhead [3]. Interactive use is tolerable; bulk transfer is painful.
  • No encryption. MD5 for auth, nothing for confidentiality. You must layer SSH or WireGuard inside if you need secure traffic [README].
  • Requires domain ownership and DNS delegation. This isn’t optional — you can’t use iodine without a domain you control and the ability to create NS records [README]. Eliminates casual use.
  • Slow development. One release in 2023 after a multi-year gap. The project is maintained but not actively developed. Security vulnerabilities would be slow to patch [website].
  • MD5-based auth. MD5 is not broken for HMAC use cases but it’s not modern either. No option for stronger authentication without patching the source [README].
  • Detection and blocking is documented. The weberblog post ends with exactly how to block iodine tunnels using Infoblox, Palo Alto, and Fortinet [3]. If you’re in a network where the admin is security-conscious, iodine may not work.
  • No logging or monitoring UI. You get terminal output. That’s it.

Who should use this / who shouldn’t

Use iodine if:

  • You regularly find yourself on networks where VPN protocols are blocked (conference halls, some hotels, university networks, corporate environments that block non-DNS traffic)
  • You’re a sysadmin or security researcher who needs a reliable escape valve for restricted environments
  • You want to understand DNS tunneling as a technique — the iodine codebase and setup process are educational
  • You need a shared tunnel endpoint for a small team (up to 16 users) and can manage the DNS setup

Don’t use iodine if:

  • A regular WireGuard or OpenVPN server gets through your network — just use those, the performance is incomparable
  • You want a VPN for privacy or security — iodine has no encryption and MD5 auth
  • You’re not comfortable with DNS zone management and command-line Linux — the setup will frustrate you
  • You need reliable throughput for anything beyond text-based traffic — 1 Mbit/s maximum means forget video calls

Skip it entirely (pick Cloudflare WARP or a commercial VPN) if:

  • Your goal is general privacy, not bypassing a specific DNS-only firewall
  • You want a mobile-friendly setup with a UI
  • You’re not willing to maintain server infrastructure

Skip it (pick Chisel or similar) if:

  • HTTP/HTTPS is allowed but not other protocols — Chisel tunnels TCP/UDP over WebSocket and is faster and easier to set up in HTTP-allowed environments

Alternatives worth considering

  • dns2tcp — another DNS tunneling tool, uses TCP encapsulation, generally slower than iodine’s NULL-record approach
  • hans — IP over ICMP instead of DNS; useful when ICMP is allowed but DNS is not; similar niche
  • Chisel — TCP/UDP tunneling over HTTP/WebSocket; faster and simpler when HTTP works; not useful for DNS-only scenarios
  • WireGuard — the right answer when port 51820/UDP gets through; categorically better performance than any DNS tunnel; requires a VPS
  • SSH with dynamic port forwarding — creates a SOCKS proxy through any SSH connection; works when port 22 gets out; simpler than iodine when SSH is available
  • Cloudflare WARP — free, uses WireGuard on port 2408/UDP; good for general restricted networks but won’t work in DNS-only environments
  • ngrok / Cloudflare Tunnel — for exposing local services to the internet, not the same use case but often conflated with tunneling tools

For the specific case iodine addresses — DNS-only network access — there is no credible SaaS substitute. The closest is a dedicated DNS VPN service, but this market is thin and the offerings are not established products.


Bottom line

iodine is a solved problem wrapped in a 100KB tarball. It does one thing — tunnel IPv4 over DNS — and does it better than anything else available. The ISC license, multi-platform support, and NULL-record optimization put it ahead of alternatives in its specific niche. But that niche is genuinely narrow: if you can get WireGuard out, iodine is the wrong tool. If you need encryption or simplicity, iodine is the wrong tool. If you’re a non-technical founder looking to escape a SaaS bill, iodine is definitely the wrong tool.

Where it belongs is in the toolkit of every sysadmin and developer who works across different network environments: conference networks, client offices, restrictive corporate setups. The setup cost is real (domain, DNS delegation, Linux comfort) but it’s one-time work, and once it’s running, you have a reliable egress path from almost any network on the planet. That’s a specific but genuinely useful thing to have.


Sources

  1. weberblog.net“iodine | Weberblog.net” — tag index page for iodine-related posts. https://weberblog.net/tag/iodine/
  2. weberblog.net“DNS Tunneling: iodine” — detailed setup walkthrough including server/client commands, tunnel interface output, and detection/blocking guidance. https://weberblog.net/dns-tunneling-iodine/
  3. psimyn.com“iodine(8) - Linux man page” — tagged reference linking to the iodine man page. https://psimyn.com/tags/dns/

Primary sources: