WireGuard Basics¶
What is WireGuard?¶
WireGuard is a modern VPN protocol that Tailscale uses as its underlying transport. It's known for being fast, secure, and simple.
WireGuard vs Tailscale¶
┌──────────────────────────────────────────────────────────────────────────────┐
│ WireGuard vs Tailscale │
│ │
│ WireGuard (protocol) Tailscale (product) │
│ ───────────────────────────────────────────────────────────────── │
│ • Encryption & tunneling • Uses WireGuard for tunnels │
│ • Manual key exchange • Automatic key exchange │
│ • Manual IP assignment • Automatic IP assignment │
│ • Manual peer configuration • Automatic peer discovery │
│ • No NAT traversal • Built-in NAT traversal │
│ • No access controls • ACL-based access control │
│ • No DNS management • MagicDNS included │
│ │
│ WireGuard = Engine Tailscale = Complete Car │
│ │
└──────────────────────────────────────────────────────────────────────────────┘
WireGuard Cryptography¶
Cipher Suite¶
WireGuard uses modern, well-audited cryptographic primitives:
| Component | Algorithm | Purpose |
|---|---|---|
| Key exchange | Curve25519 | Elliptic curve Diffie-Hellman |
| Encryption | ChaCha20-Poly1305 | Authenticated encryption |
| Hashing | BLAKE2s | Fast cryptographic hash |
| Key derivation | HKDF | Deriving session keys |
Key Pair¶
Each WireGuard interface has a key pair:
# Generate WireGuard keys (for reference - Tailscale does this automatically)
wg genkey | tee privatekey | wg pubkey > publickey
Tailscale manages keys automatically:
# View Tailscale's WireGuard interface
sudo wg show tailscale0
# Example output:
# interface: tailscale0
# public key: ABC123...
# private key: (hidden)
# listening port: 41641
#
# peer: DEF456...
# endpoint: 203.0.113.1:41641
# allowed ips: 100.100.100.2/32
# latest handshake: 42 seconds ago
# transfer: 1.23 MiB received, 456.78 KiB sent
WireGuard Interface¶
Tailscale creates a virtual network interface:
# View the interface
ip addr show tailscale0
# Example output:
# tailscale0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1280
# inet 100.100.100.1/32 scope global tailscale0
Interface Properties¶
┌──────────────────────────────────────────────────────────────────────────────┐
│ tailscale0 Interface │
│ │
│ Property Value Notes │
│ ───────────────────────────────────────────────────────────────── │
│ Type WireGuard Virtual tunnel interface │
│ IP Address 100.x.x.x/32 Tailscale-assigned │
│ MTU 1280 Allows for encapsulation │
│ Flags POINTOPOINT Point-to-point tunnel │
│ Protocol UDP WireGuard uses UDP │
│ Port 41641 (typical) Can vary │
│ │
└──────────────────────────────────────────────────────────────────────────────┘
WireGuard Concepts¶
Peers¶
In WireGuard, each device you can connect to is a "peer":
Allowed IPs¶
Each peer has "allowed IPs" - the IP ranges that can be routed through that peer:
┌──────────────────────────────────────────────────────────────────────────────┐
│ Allowed IPs Example │
│ │
│ Peer: server.tailnet.ts.net │
│ ───────────────────────────────────────────────────────────────── │
│ Allowed IPs: │
│ • 100.100.100.2/32 → Server's Tailscale IP │
│ • 192.168.10.0/24 → Subnet router for home network │
│ │
│ Traffic to these IPs goes through this peer's WireGuard tunnel │
│ │
└──────────────────────────────────────────────────────────────────────────────┘
Endpoints¶
The endpoint is the public IP:port where a peer can be reached:
Endpoints can change as devices move networks - Tailscale handles this automatically.
Handshakes¶
WireGuard performs periodic handshakes to: - Verify peer is still reachable - Rotate session keys - Update endpoint if changed
# Check handshake status
sudo wg show tailscale0 latest-handshakes
# Handshakes occur every 2 minutes when active
# Stale handshake (>5 min) may indicate connection issues
WireGuard Performance¶
Why WireGuard is Fast¶
- Minimal code: ~4,000 lines vs 100,000+ for OpenVPN
- Kernel implementation: Runs in kernel space
- Modern crypto: ChaCha20 is very fast
- UDP-based: Lower overhead than TCP
Performance Comparison¶
| VPN Protocol | Typical Overhead | CPU Usage |
|---|---|---|
| WireGuard | ~3% | Very low |
| OpenVPN (UDP) | ~15-20% | Moderate |
| OpenVPN (TCP) | ~20-30% | Higher |
| IPsec | ~10-15% | Moderate |
Benchmarking¶
# Test throughput through Tailscale
iperf3 -s # On server
# On client
iperf3 -c 100.100.100.2
# Compare with direct connection
iperf3 -c server-local-ip
Raw WireGuard vs Tailscale¶
Manual WireGuard Setup¶
What you'd need to do manually:
# 1. Generate keys on each device
wg genkey | tee /etc/wireguard/private.key | wg pubkey > /etc/wireguard/public.key
# 2. Create config on each device
cat > /etc/wireguard/wg0.conf << 'EOF'
[Interface]
PrivateKey = <your-private-key>
Address = 10.0.0.1/24
ListenPort = 51820
[Peer]
PublicKey = <peer-public-key>
AllowedIPs = 10.0.0.2/32
Endpoint = peer.example.com:51820
PersistentKeepalive = 25
EOF
# 3. Exchange public keys between all devices
# 4. Configure firewall rules
# 5. Set up DNS manually
# 6. Handle key rotation manually
# 7. Configure each new peer on all existing devices
Tailscale Setup¶
# 1. Install and authenticate (that's it)
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
Debugging WireGuard Layer¶
View WireGuard Status¶
# Full WireGuard status
sudo wg show tailscale0
# Just peers
sudo wg show tailscale0 peers
# Transfer statistics
sudo wg show tailscale0 transfer
# Latest handshakes
sudo wg show tailscale0 latest-handshakes
Common Issues¶
| Symptom | WireGuard Cause | Tailscale Fix |
|---|---|---|
| No handshake | Endpoint unreachable | Check tailscale netcheck |
| Stale handshake | NAT timeout | Tailscale keepalive handles this |
| No transfer | Allowed IPs wrong | Tailscale manages automatically |
| High latency | Using DERP relay | Check tailscale status for relay |
Packet Capture¶
# Capture WireGuard traffic (encrypted)
sudo tcpdump -i eth0 udp port 41641
# Capture decrypted traffic on tunnel
sudo tcpdump -i tailscale0
Security Considerations¶
WireGuard Security Properties¶
- Forward secrecy: Compromised key doesn't expose past traffic
- Replay protection: Built-in via nonce
- DoS resistance: Minimal state before authentication
- Stealth: Silent to unauthenticated packets
Key Storage¶
# Tailscale stores keys securely
ls -la /var/lib/tailscale/
# Never share these files:
# - tailscaled.state (contains private keys)