Skip to content

Iodine DNS Tunnel Service

Overview

Iodine is a DNS tunneling tool that allows IPv4 traffic to be tunneled through DNS queries. This is particularly useful for bypassing restrictive firewalls (like captive portals on plane/hotel WiFi) that block regular internet traffic but allow DNS queries on port 53.

Installation Details

  • Software: iodine v0.7.0 (installed from Ubuntu repositories)
  • Server Component: iodined (DNS tunnel server)
  • Client Component: iodine (DNS tunnel client)
  • Service: iodined.service (systemd service)

Configuration

Server Configuration (Optimized for Captive Portals)

  • Domain: i.rbnk.uk (short domain for maximum payload)
  • NS Server: ns-i.rbnk.uk157.180.63.15
  • Tunnel Network: 10.0.0.1/24
  • Server Port: 53 (standard DNS port for captive portal compatibility)
  • DNS Forwarding: Forwards to AdGuard on 127.0.0.1:1053
  • Interface: dns0 (tunnel interface)
  • MTU: 1130 bytes
  • Mode Toggle: Use iodine-mode command to switch between normal and tunnel mode

DNS Records

The following DNS records have been configured in Cloudflare:

  1. A Record: ns-i.rbnk.uk → 157.180.63.15 (DNS-only, no proxy)
  2. NS Record: i.rbnk.uk → ns-i.rbnk.uk (subdomain delegation)

Port Configuration

Normal Mode (Default): - AdGuard DNS: Port 53 (standard DNS for all services) - Iodine: Inactive

Iodine Mode (Emergency Access): - Iodine Server: Port 53 (accepts DNS queries) - AdGuard DNS: Port 1053 on localhost (receives forwarded queries) - Key Benefit: Works through captive portals that only allow DNS on port 53

Service Management

# Enable iodine mode (switches AdGuard to localhost:1053)
sudo iodine-mode enable

# Disable iodine mode (restores normal DNS)
sudo iodine-mode disable

# Check current mode
sudo iodine-mode status

# Toggle between modes
sudo iodine-mode toggle

Manual Service Control

# View logs
sudo journalctl -u iodined -f

# Check ports
sudo ss -tlunp | grep :53

Service File Location

The service file is located at: /etc/systemd/system/iodined.service Password wrapper script: /usr/local/bin/iodined-wrapper.sh

Client Connection

Quick Start (Captive Portal/Plane WiFi)

# macOS/Linux - force DNS mode for captive portals
sudo iodine -f -r -P [password] i.rbnk.uk

# You'll get dns0 with IP 10.0.0.2
# SSH to server:
ssh [email protected]

Android (Samsung Fold)

Use AndIodine from F-Droid: - Server: i.rbnk.uk - Password: [your password] - Leave other settings on auto

Connection Parameters

  • Server: i.rbnk.uk (no need to specify IP)
  • Server Port: 53 (standard DNS - works through captive portals)
  • Tunnel Network: 10.0.0.0/24
  • Server IP on tunnel: 10.0.0.1
  • Client IPs: 10.0.0.2 - 10.0.0.254

Performance Tuning

# Adjust MTU and fragment size for better performance
iodine -f -r -m 1024 -M 200 -P [password] i.rbnk.uk

# Try different encodings/record types
iodine -f -r -T NULL -O base64 -P [password] i.rbnk.uk

Troubleshooting

DNS Propagation

If DNS records don't resolve immediately:

# Check NS delegation
dig +trace i.rbnk.uk NS
dig -t NS foo.i.rbnk.uk @1.1.1.1

# Check A record for NS server
dig A ns-i.rbnk.uk @1.1.1.1

Service Issues

# Check if iodined is listening on port 53
sudo ss -tlunp | grep :53

# Check tunnel interface
ip addr show dns0

# Verify forwarding to AdGuard
dig @127.0.0.1 -p 1053 google.com

Common Issues

  1. "No DNS reply" errors:
  2. DNS records may still be propagating (wait 5-10 minutes)
  3. Some DNS servers filter non-standard queries
  4. Try different upstream DNS (8.8.8.8, 1.1.1.1)

  5. Slow performance:

  6. Normal for DNS tunnels (50-200 kbit/s typical)
  7. Try -T NULL or -T TXT for better throughput
  8. Adjust MTU with -m 1024

  9. Authentication failures:

  10. Password is case-sensitive
  11. Check wrapper script has correct password

Security Considerations

  1. Password Protection: The tunnel is password-protected
  2. Firewall Rules: Only UDP port 5353 is open for iodine
  3. Tunnel Isolation: Traffic is isolated to the 10.0.0.0/24 network
  4. No Routing: By default, no routing between tunnel and main network

Performance Tuning

Server-side Options

  • MTU is set to 1130 (optimal for most networks)
  • Using base32 encoding (default, most compatible)

Client-side Options

# Use NULL type for better performance (if supported)
iodine -T NULL -f -P [password] server tunnel.rbnk.uk

# Use base64 encoding for better throughput
iodine -O base64 -f -P [password] server tunnel.rbnk.uk

# Adjust fragment size
iodine -m 1024 -f -P [password] server tunnel.rbnk.uk

Integration with Infrastructure

Monitoring

The service can be monitored via: - Systemd service status - Network interface statistics - Prometheus node exporter metrics

Backup Considerations

No specific backup required as configuration is minimal. The password should be stored securely in your password manager.

Helper Scripts

  • Setup Script: /srv/dockerdata/_scripts/iodine-setup.sh
  • Quick Access: iodine-setup (symlinked to /usr/local/bin)
  • Documentation: /srv/dockerdata/_scripts/IODINE_GUIDE.md

Use Cases

  1. Emergency Access: Bypass restrictive firewalls in emergencies
  2. Testing: Verify DNS-based exfiltration detection systems
  3. Research: Understand DNS tunneling techniques
  4. Backup Connectivity: Alternative access method when primary routes fail

Important Notes

  • DNS tunneling is slow (50-200 kbit/s) but sufficient for SSH/terminal access
  • Optimized for captive portals that only allow DNS on port 53
  • Short domain (i.rbnk.uk) maximizes payload for better performance
  • The -r flag forces DNS mode (no raw UDP) for captive portal compatibility
  • This is configured as a defensive security tool for legitimate emergency access
  • DNS Resolution: Keep AdGuard on port 53 by default to maintain normal DNS for all services
  • Mode Switching: Use iodine-mode script to safely toggle between normal and tunnel modes