Iodine
Iodine is a DNS tunneling tool that encapsulates IP traffic within DNS queries and responses, allowing you to tunnel network traffic through restrictive firewalls and captive portals that only permit DNS traffic. It establishes a PPP tunnel interface (dns0) over DNS, enabling full network access when direct connections are blocked.
Installation
섹션 제목: “Installation”Linux (Debian/Ubuntu)
섹션 제목: “Linux (Debian/Ubuntu)”sudo apt update
sudo apt install iodine
macOS
섹션 제목: “macOS”brew install iodine
Compile from Source
섹션 제목: “Compile from Source”git clone https://github.com/yarrick/iodine.git
cd iodine
make
sudo make install
Verify installation:
iodine --version
iodined --version
Infrastructure Setup
섹션 제목: “Infrastructure Setup”Domain Requirements
섹션 제목: “Domain Requirements”- Delegated subdomain: Use a domain you control (e.g.,
tunnel.example.com) - DNS nameserver: The delegated domain must point to your iodined server
DNS Configuration
섹션 제목: “DNS Configuration”Create NS record delegation at your domain registrar:
tunnel.example.com NS ns1.tunnel.example.com
ns1.tunnel.example.com A <your-server-ip>
This routes all DNS queries for *.tunnel.example.com to your iodined server listening on port 53.
Verification:
nslookup test.tunnel.example.com
# Should resolve to your server IP
Server Setup
섹션 제목: “Server Setup”Basic iodined Server
섹션 제목: “Basic iodined Server”Start the DNS tunneling server:
sudo iodined -f -c -P "SecurePassword123" 10.0.0.1 tunnel.example.com
Server Options Reference
섹션 제목: “Server Options Reference”| Option | Description |
|---|---|
-f | Run in foreground (don’t daemonize) |
-c | Disable IP check of incoming packets (enables NAT clients) |
-P password | Set tunnel authentication password |
-n auto|IP | Listen address (auto or specific IP, default: 0.0.0.0) |
-l 0.0.0.0 | Explicitly bind to all interfaces |
-p 53 | Listen port (default 53, requires root) |
-u username | Drop privileges to user after bind |
-t /var/empty | Chroot to directory |
-d device | Use specific TUN device |
-m mtu | Set tunnel MTU (default 1024) |
-M | Use lazy mode for faster transfers |
-w downstream | Fragment size downstream (default 3333) |
Production Setup
섹션 제목: “Production Setup”sudo iodined -u iodine -t /var/empty \
-c -P "ComplexPassword!" \
-n auto \
-m 1024 \
10.0.0.1 tunnel.example.com
Verify server is running:
sudo netstat -tulnp | grep 53
ps aux | grep iodined
Client Setup
섹션 제목: “Client Setup”Basic Connection
섹션 제목: “Basic Connection”sudo iodine -f -P "SecurePassword123" tunnel.example.com
Client Options Reference
섹션 제목: “Client Options Reference”| Option | Description |
|---|---|
-f | Run in foreground |
-P password | Authentication password (must match server) |
-r | Force specific DNS resolver IP |
-R | Bind to specific DNS port on client |
-T record_type | DNS record type: NULL (default), TXT, SRV, MX, CNAME, A |
-m mtu | Set tunnel MTU (should match server) |
-M | Enable lazy mode (faster transfers) |
-I interval | Ping interval in seconds (default 4) |
-L lazy_mode | Set lazy mode strength (0-3) |
-O encoding | Set encoding: base32 (default), base64, base128, raw |
-W window_size | Set window size for flow control |
Force Custom DNS Resolver
섹션 제목: “Force Custom DNS Resolver”sudo iodine -f -r 8.8.8.8 -P "password" tunnel.example.com
Specify Record Type
섹션 제목: “Specify Record Type”sudo iodine -f -T TXT -P "password" tunnel.example.com
DNS Record Types
섹션 제목: “DNS Record Types”Bandwidth Comparison
섹션 제목: “Bandwidth Comparison”| Type | Bandwidth | Notes |
|---|---|---|
| NULL | 200-300 KB/s | Best (most nameservers allow) |
| TXT | 150-200 KB/s | Good fallback when NULL blocked |
| A | 50-80 KB/s | Limited, some networks block |
| CNAME | 50-80 KB/s | Can trigger warnings, avoid |
| MX | 100-150 KB/s | Reasonable fallback |
| SRV | 100-150 KB/s | Possible but uncommon |
Selection Strategy
섹션 제목: “Selection Strategy”- Try NULL first (fastest, widely supported)
- Fall back to TXT if NULL blocked
- Use A records as last resort (slowest)
# Try NULL (default)
sudo iodine -f tunnel.example.com
# Fall back to TXT
sudo iodine -f -T TXT tunnel.example.com
# Try A record
sudo iodine -f -T A tunnel.example.com
Tunnel Interface
섹션 제목: “Tunnel Interface”Interface Configuration
섹션 제목: “Interface Configuration”Once connected, you’ll see:
ifconfig dns0
# Shows: 10.0.0.x/255.255.255.0 (tun interface)
Verify Connectivity
섹션 제목: “Verify Connectivity”# Test tunnel is up
ping 10.0.0.1
# Test external connectivity
traceroute 8.8.8.8
Routing Through Tunnel
섹션 제목: “Routing Through Tunnel”Configure which traffic flows through the tunnel:
# Route all traffic through tunnel
sudo route add default gw 10.0.0.1
# Route specific subnet
sudo route add 192.168.1.0/24 gw 10.0.0.1
# Route to specific host
sudo route add 10.20.30.40 gw 10.0.0.1
SOCKS Proxy Over Tunnel
섹션 제목: “SOCKS Proxy Over Tunnel”Create a SOCKS proxy via SSH tunneling:
# Terminal 1: Establish iodine tunnel
sudo iodine -f -P "password" tunnel.example.com
# Terminal 2: SSH SOCKS proxy (once tunnel is up)
ssh -D 1080 user@10.0.0.1
# Terminal 3: Use SOCKS proxy
curl --socks5 127.0.0.1:1080 https://example.com
DNS Configuration on Tunnel
섹션 제목: “DNS Configuration on Tunnel”Set DNS for tunnel traffic:
# Temporary (single session)
echo "nameserver 10.0.0.1" | sudo tee -a /etc/resolv.conf
# Or use client option
sudo iodine -f -P "password" tunnel.example.com
# DNS automatically configured
Performance Tuning
섹션 제목: “Performance Tuning”MTU Optimization
섹션 제목: “MTU Optimization”Start conservative, then increase:
# Server (smaller MTU = more reliable)
sudo iodined -m 1024 10.0.0.1 tunnel.example.com
# Client (must match or be smaller than server)
sudo iodine -m 1024 tunnel.example.com
# Increase for faster speeds (if stable)
sudo iodined -m 2048 10.0.0.1 tunnel.example.com
sudo iodine -m 2048 tunnel.example.com
Fragment Size Control
섹션 제목: “Fragment Size Control”# Server: reduce downstream fragment size for stability
sudo iodined -w 2000 10.0.0.1 tunnel.example.com
Lazy Mode (Faster Transfers)
섹션 제목: “Lazy Mode (Faster Transfers)”Reduces ping overhead, increases speed:
# Server
sudo iodined -M 10.0.0.1 tunnel.example.com
# Client
sudo iodine -M tunnel.example.com
Encoding Selection
섹션 제목: “Encoding Selection”Choose encoding to optimize for network conditions:
# base32 (default, most compatible)
sudo iodine -O base32 tunnel.example.com
# base64 (faster, may be filtered)
sudo iodine -O base64 tunnel.example.com
# base128 (fastest, least compatible)
sudo iodine -O base128 tunnel.example.com
Captive Portal Bypass
섹션 제목: “Captive Portal Bypass”Typical Workflow
섹션 제목: “Typical Workflow”# 1. Connect to WiFi (will show captive portal)
# Don't authenticate if you want pure DNS tunnel
# 2. Start iodine tunnel
sudo iodine -f -P "password" tunnel.example.com
# 3. Once connected, traffic routes through DNS tunnel
# You have full network access regardless of captive portal
# 4. Verify connectivity
ping 8.8.8.8
curl https://example.com
Handling Aggressive Filtering
섹션 제목: “Handling Aggressive Filtering”Some networks block DNS on non-standard ports or filter record types:
# Try different DNS resolvers
sudo iodine -r 1.1.1.1 tunnel.example.com
sudo iodine -r 8.8.8.8 tunnel.example.com
# Try different record types
sudo iodine -T TXT tunnel.example.com
sudo iodine -T A tunnel.example.com
# Combine strategies
sudo iodine -r 1.1.1.1 -T TXT tunnel.example.com
Routing Configuration
섹션 제목: “Routing Configuration”Split Tunneling (Selective Routes)
섹션 제목: “Split Tunneling (Selective Routes)”Route only specific traffic through tunnel:
# Assume tunnel is up: 10.0.0.1
# Route corporate network through tunnel
sudo route add 10.20.0.0/16 gw 10.0.0.1
# Route specific server
sudo route add 10.30.40.50 gw 10.0.0.1
# All other traffic uses normal route (local ISP)
Full Tunnel (All Traffic)
섹션 제목: “Full Tunnel (All Traffic)”Route all traffic through tunnel (careful with latency):
# Save default route first
ip route show > /tmp/routes.bak
# Replace default route
sudo route del default
sudo route add default gw 10.0.0.1
# Restore later
sudo route del default
cat /tmp/routes.bak | while read line; do sudo route add $line; done
View Current Routes
섹션 제목: “View Current Routes”route -n
ip route show
netstat -r
Troubleshooting
섹션 제목: “Troubleshooting”Connection Fails
섹션 제목: “Connection Fails”# 1. Verify DNS resolution
nslookup test.tunnel.example.com
dig @ns1.example.com test.tunnel.example.com
# 2. Check server is listening
sudo netstat -tulnp | grep 53
sudo ss -tulnp | grep 53
# 3. Check firewall
sudo iptables -L -n | grep 53
sudo firewall-cmd --list-all
# 4. Enable firewall port
sudo ufw allow 53/udp
sudo firewall-cmd --permanent --add-port=53/udp
Slow Tunnel
섹션 제목: “Slow Tunnel”# 1. Test with lazy mode
sudo iodine -M -f tunnel.example.com
# 2. Increase MTU
sudo iodine -m 2048 tunnel.example.com
# 3. Try different encoding
sudo iodine -O base64 tunnel.example.com
# 4. Check latency
ping -c 5 10.0.0.1
Password Authentication Issues
섹션 제목: “Password Authentication Issues”# Verify server password
sudo ps aux | grep iodined
# Look for -P flag
# Ensure exact match on client
sudo iodine -P "ExactSamePassword" tunnel.example.com
# Check for special characters
# Use quotes to preserve spaces/special chars
TUN/TAP Device Errors
섹션 제목: “TUN/TAP Device Errors”# Check device exists
ls -la /dev/net/tun
# Create if missing
sudo mkdir -p /dev/net
sudo mknod /dev/net/tun c 10 200
sudo chmod 600 /dev/net/tun
No DNS Resolution in Tunnel
섹션 제목: “No DNS Resolution in Tunnel”# Manually set DNS
echo "nameserver 10.0.0.1" | sudo tee /etc/resolv.conf
# Or use resolvconf
echo "nameserver 10.0.0.1" | sudo resolvconf -a tun0
# Verify
cat /etc/resolv.conf
Best Practices
섹션 제목: “Best Practices”Security
섹션 제목: “Security”- Use strong passwords: At least 16 characters, mix of complexity
- Restrict server access: Firewall port 53 to authorized IPs only
- Run as unprivileged user: Use
-u iodine -t /var/empty - Use HTTPS tunneling: Encrypt data within the tunnel
- Rotate credentials: Change password regularly in production
Stability
섹션 제목: “Stability”- Start conservative: Begin with default MTU (1024), increase carefully
- Monitor packet loss: Check
pingoutput for drops - Use lazy mode judiciously: Faster but less reliable on poor connections
- Match MTU on client and server: Prevents fragmentation
- Test in staging: Verify before production deployment
Operational
섹션 제목: “Operational”- Monitor DNS logs: Track tunnel usage at the DNS level
- Set up alerts: Monitor connection drops and errors
- Document configuration: Keep record of MTU, encoding, record type settings
- Have fallbacks: Prepare alternative tunneling methods (dnscat2, dns2tcp)
- Test regularly: Verify tunnel works from different networks
Related Tools
섹션 제목: “Related Tools”| Tool | Purpose | Comparison |
|---|---|---|
| dnscat2 | DNS tunneling with C&C capabilities | Full shell over DNS, more features, complex setup |
| dns2tcp | TCP tunneling over DNS | Lighter weight, simpler than iodine, slower |
| Chisel | HTTP/HTTPS reverse proxy tunneling | Modern, SSH-like syntax, easier setup, not DNS-based |
| NSTX | DNS tunneling via SSH | Older, less maintained, similar to iodine |
| DNSExfil | DNS exfiltration only | One-way data extraction, not bidirectional |
When to Use Iodine
섹션 제목: “When to Use Iodine”- Firewall bypass: When only DNS port 53 is open
- Captive portal evasion: Hotel/airport WiFi restrictions
- Low-bandwidth pivoting: Need minimal bandwidth for command execution
- Reliable covert channel: More stable than ICMP or other methods
When to Use Alternatives
섹션 제목: “When to Use Alternatives”- Full shell needed: Use dnscat2 (more features)
- Modern infrastructure: Use Chisel (simpler, faster)
- Quick lightweight tunnel: Use dns2tcp (minimal overhead)