|
| 1 | +--- |
| 2 | +title: "AllowedIPs in WireGuard Explained: Quick Reference and How It Really Works" |
| 3 | +description: "Complete guide to understanding WireGuard's AllowedIPs parameter - how it controls routing and filtering, common configurations, and troubleshooting tips to avoid routing mistakes." |
| 4 | +publishDate: 2026-01-22 |
| 5 | +author: "Defguard Team" |
| 6 | +tags: ["wireguard", "vpn", "networking", "routing", "troubleshooting", "security"] |
| 7 | +draft: true |
| 8 | +--- |
| 9 | +## Overview |
| 10 | + |
| 11 | +Keep this reference handy when designing WireGuard network topologies. For complex routing scenarios, test in a lab before production deployment. |
| 12 | + |
| 13 | +--- |
| 14 | + |
| 15 | +## What AllowedIPs Actually Does |
| 16 | + |
| 17 | +AllowedIPs serves **two functions simultaneously**: |
| 18 | + |
| 19 | +1. **Routing (outbound):** Which destination IPs should be sent through this peer |
| 20 | +2. **Filtering (inbound):** Which source IPs are accepted from this peer |
| 21 | + |
| 22 | +Think of it as: "This peer is allowed to send/receive traffic for these IP ranges." |
| 23 | + |
| 24 | +--- |
| 25 | + |
| 26 | +## The Mental Model |
| 27 | + |
| 28 | +``` |
| 29 | +┌─────────────────────────────────────────────────────────────────┐ |
| 30 | +│ YOUR DEVICE │ |
| 31 | +│ │ |
| 32 | +│ Application wants to reach 10.0.0.50 │ |
| 33 | +│ │ │ |
| 34 | +│ ▼ │ |
| 35 | +│ ┌─────────────────────────────────────────────────────────┐ │ |
| 36 | +│ │ Routing Decision: Which peer has 10.0.0.50 in │ │ |
| 37 | +│ │ AllowedIPs? │ │ |
| 38 | +│ └─────────────────────────────────────────────────────────┘ │ |
| 39 | +│ │ │ |
| 40 | +│ ▼ │ |
| 41 | +│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ |
| 42 | +│ │ Peer A │ │ Peer B │ │ Peer C │ │ |
| 43 | +│ │ 10.0.0.0/24 │◄───│ 10.1.0.0/24 │ │ 10.2.0.0/24 │ │ |
| 44 | +│ │ ✓ MATCH │ │ No match │ │ No match │ │ |
| 45 | +│ └─────────────┘ └─────────────┘ └─────────────┘ │ |
| 46 | +│ │ │ |
| 47 | +│ ▼ │ |
| 48 | +│ Packet encrypted and sent to Peer A's endpoint │ |
| 49 | +└─────────────────────────────────────────────────────────────────┘ |
| 50 | +``` |
| 51 | + |
| 52 | +--- |
| 53 | + |
| 54 | +## Common Configurations |
| 55 | + |
| 56 | +### Full Tunnel (All Traffic Through VPN) |
| 57 | + |
| 58 | +```ini |
| 59 | +[Peer] |
| 60 | +PublicKey = <server_public_key> |
| 61 | +Endpoint = vpn.example.com:51820 |
| 62 | +AllowedIPs = 0.0.0.0/0, ::/0 # All IPv4 and IPv6 traffic |
| 63 | +``` |
| 64 | + |
| 65 | +**Use case:** All internet traffic through VPN (privacy, compliance, security) |
| 66 | + |
| 67 | +**Warning:** This routes EVERYTHING through VPN, including DNS. Ensure VPN server can reach the internet. |
| 68 | + |
| 69 | +--- |
| 70 | + |
| 71 | +### Split Tunnel (Only Corporate Resources) |
| 72 | + |
| 73 | +```ini |
| 74 | +[Peer] |
| 75 | +PublicKey = <server_public_key> |
| 76 | +Endpoint = vpn.example.com:51820 |
| 77 | +AllowedIPs = 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 |
| 78 | +``` |
| 79 | + |
| 80 | +**Use case:** Access internal resources while using local internet for everything else |
| 81 | + |
| 82 | +**Advantage:** Reduces VPN server load, faster internet access |
| 83 | + |
| 84 | +--- |
| 85 | + |
| 86 | +### Single Host Access |
| 87 | + |
| 88 | +```ini |
| 89 | +[Peer] |
| 90 | +PublicKey = <server_public_key> |
| 91 | +Endpoint = vpn.example.com:51820 |
| 92 | +AllowedIPs = 10.0.0.50/32 # Only this one IP |
| 93 | +``` |
| 94 | + |
| 95 | +**Use case:** Restrict access to a single server |
| 96 | + |
| 97 | +--- |
| 98 | + |
| 99 | +### Multiple Non-Contiguous Ranges |
| 100 | + |
| 101 | +```ini |
| 102 | +[Peer] |
| 103 | +PublicKey = <server_public_key> |
| 104 | +Endpoint = vpn.example.com:51820 |
| 105 | +AllowedIPs = 10.0.0.0/24, 10.5.0.0/24, 172.16.50.0/24 |
| 106 | +``` |
| 107 | + |
| 108 | +**Use case:** Access multiple separate subnets |
| 109 | + |
| 110 | +--- |
| 111 | + |
| 112 | +## Server-Side vs Client-Side |
| 113 | + |
| 114 | +### Server Config (Gateway) |
| 115 | + |
| 116 | +```ini |
| 117 | +# Server accepts traffic FROM THIS CLIENT only when source IP matches these ranges |
| 118 | +[Peer] |
| 119 | +PublicKey = <client_public_key> |
| 120 | +AllowedIPs = 10.0.0.10/32, 10.0.0.0/24 # Client's IP + networks it can access |
| 121 | +``` |
| 122 | + |
| 123 | +### Client Config |
| 124 | + |
| 125 | +```ini |
| 126 | +# Client routes THESE DESTINATIONS through server |
| 127 | +[Peer] |
| 128 | +PublicKey = <server_public_key> |
| 129 | +AllowedIPs = 10.0.0.0/24 # All of internal network |
| 130 | +``` |
| 131 | + |
| 132 | +**Key insight:** Server and client AllowedIPs serve different purposes: |
| 133 | +- Server: "What IPs can this client claim as source?" |
| 134 | +- Client: "What destinations should go through VPN?" |
| 135 | + |
| 136 | +--- |
| 137 | + |
| 138 | +## Common Mistakes |
| 139 | + |
| 140 | +### Mistake 1: Overlapping AllowedIPs |
| 141 | + |
| 142 | +```ini |
| 143 | +# BAD: Two peers with overlapping ranges |
| 144 | +[Peer] |
| 145 | +PublicKey = <peer_a> |
| 146 | +AllowedIPs = 10.0.0.0/16 # 10.0.x.x |
| 147 | + |
| 148 | +[Peer] |
| 149 | +PublicKey = <peer_b> |
| 150 | +AllowedIPs = 10.0.1.0/24 # Also 10.0.x.x - OVERLAP! |
| 151 | +``` |
| 152 | + |
| 153 | +**Result:** Traffic to 10.0.1.x could go to either peer (undefined behavior) |
| 154 | + |
| 155 | +**Fix:** Use non-overlapping, most-specific routes |
| 156 | + |
| 157 | +--- |
| 158 | + |
| 159 | +### Mistake 2: Incorrect Source IP Ranges |
| 160 | + |
| 161 | +```ini |
| 162 | +# BAD: Server config doesn't match client's actual tunnel IP |
| 163 | +[Peer] |
| 164 | +PublicKey = <client> |
| 165 | +AllowedIPs = 10.0.0.0/24 # Client uses 10.1.0.5, but this allows 10.0.x.x sources only |
| 166 | +``` |
| 167 | + |
| 168 | +**Result:** Client can't communicate because its source IP (10.1.0.5) doesn't match allowed ranges |
| 169 | + |
| 170 | +**Fix:** Include client's actual tunnel IP in server's AllowedIPs: `AllowedIPs = 10.1.0.5/32, 10.0.0.0/24` |
| 171 | + |
| 172 | +--- |
| 173 | + |
| 174 | +### Mistake 3: Full Tunnel Breaking Local Access |
| 175 | + |
| 176 | +```ini |
| 177 | +# Client config |
| 178 | +[Peer] |
| 179 | +AllowedIPs = 0.0.0.0/0 # All traffic through VPN |
| 180 | +``` |
| 181 | + |
| 182 | +**Problem:** Local network (printer, NAS) unreachable |
| 183 | + |
| 184 | +**Fixes:** |
| 185 | +1. **Exclude local subnet (recommended):** |
| 186 | + ```ini |
| 187 | + AllowedIPs = 0.0.0.0/0, !192.168.1.0/24 # All except local network |
| 188 | + ``` |
| 189 | + *Note: Not all WireGuard implementations support exclusion syntax* |
| 190 | + |
| 191 | +2. **Use CIDR math workaround:** |
| 192 | + ```ini |
| 193 | + AllowedIPs = 0.0.0.0/1, 128.0.0.0/1 # Covers all IPv4 except 0.0.0.0/0 exactly |
| 194 | + ``` |
| 195 | + |
| 196 | +3. **OS-specific routing:** Configure local routes to bypass VPN interface |
| 197 | + |
| 198 | +--- |
| 199 | + |
| 200 | +### Mistake 4: DNS Leaks in Split Tunnel |
| 201 | + |
| 202 | +```ini |
| 203 | +# Client config - split tunnel |
| 204 | +[Peer] |
| 205 | +AllowedIPs = 10.0.0.0/8 |
| 206 | +DNS = 10.0.0.1 # Corporate DNS |
| 207 | +``` |
| 208 | + |
| 209 | +**Problem:** DNS queries might still go to ISP DNS |
| 210 | + |
| 211 | +**Fix:** Ensure DNS server IP is in AllowedIPs, or use full tunnel for DNS: |
| 212 | +```ini |
| 213 | +AllowedIPs = 10.0.0.0/8, 10.0.0.1/32 |
| 214 | +``` |
| 215 | + |
| 216 | +--- |
| 217 | + |
| 218 | +## Quick Subnet Reference |
| 219 | + |
| 220 | +| CIDR | Addresses | Use Case | |
| 221 | +|------|-----------|----------| |
| 222 | +| /32 | 1 | Single host | |
| 223 | +| /24 | 256 | Small subnet | |
| 224 | +| /16 | 65,536 | Large network | |
| 225 | +| /8 | 16.7M | Entire class A | |
| 226 | +| /0 | All | Full tunnel | |
| 227 | + |
| 228 | +--- |
| 229 | + |
| 230 | +## Defguard and AllowedIPs |
| 231 | + |
| 232 | +When using Defguard: |
| 233 | + |
| 234 | +1. **Location configuration** defines which networks that VPN location provides access to |
| 235 | +2. **User/device assignment** determines which locations a user can connect to |
| 236 | +3. **AllowedIPs is auto-generated** based on location settings |
| 237 | + |
| 238 | +**Verify in [docs.defguard.net](https://docs.defguard.net):** How to configure location network ranges and per-user access |
| 239 | + |
| 240 | +**Advantage:** No manual AllowedIPs management, reduces routing conflicts |
| 241 | + |
| 242 | +--- |
| 243 | + |
| 244 | +## Debugging AllowedIPs Issues |
| 245 | + |
| 246 | +### Check Current Routes |
| 247 | + |
| 248 | +```bash |
| 249 | +# Linux - show routing table |
| 250 | +ip route show table all | grep wg0 |
| 251 | + |
| 252 | +# macOS |
| 253 | +netstat -rn | grep utun |
| 254 | +``` |
| 255 | + |
| 256 | +### Verify Peer Configuration |
| 257 | + |
| 258 | +```bash |
| 259 | +# Show all peers and their AllowedIPs |
| 260 | +wg show wg0 allowed-ips |
| 261 | +``` |
| 262 | + |
| 263 | +### Test Routing Decision |
| 264 | + |
| 265 | +```bash |
| 266 | +# Which interface would this IP use? |
| 267 | +ip route get 10.0.0.50 |
| 268 | +``` |
| 269 | + |
| 270 | +--- |
| 271 | + |
| 272 | +## One-Liner Summary |
| 273 | + |
| 274 | +> **AllowedIPs = "Send traffic FOR these IPs through this peer, and ACCEPT traffic FROM these IPs from this peer."** |
0 commit comments