WireGuard on a Router: NAT Mistakes That Break LAN Access (and Fixes)

Was this helpful?

You set up WireGuard on your router because you want “the whole house VPN” or remote access to your LAN. It handshakes instantly. Your phone gets a tunnel IP.
You feel smart for five minutes. Then you can’t reach your printer, your NAS, or anything on the LAN—unless you turn the VPN off. That’s not a WireGuard problem.
That’s you (or your router) doing NAT in the wrong place.

The worst part: it often “sort of works.” DNS resolves. Some sites load. But LAN traffic dies silently, or only works one way, or breaks only for one subnet.
NAT mistakes are like glitter: once they’re in your routing table and firewall, they show up everywhere.

The mental model: routing first, NAT last

WireGuard is boring in the best way. It’s a point-to-point interface that encrypts packets and puts them on a virtual NIC.
Everything else—who can reach what, how packets return, whether LAN devices see real client IPs—is decided by the same old
routing table and the same old firewall rules you’ve been fighting since 2003.

Three truths that explain 90% of “VPN breaks LAN”

  • AllowedIPs is routing. On a peer, AllowedIPs is a policy route selector and an anti-spoof filter. It is not “an ACL.” Treat it like a route map.
  • NAT hides mistakes until it doesn’t. Masquerading the tunnel can make return traffic “work” without adding routes, but it breaks LAN visibility, inbound policies, and sometimes even connectivity.
  • Return paths matter more than forward paths. Most failures are asymmetric routing: packet goes in, reply goes out the wrong interface.

When you run WireGuard on a router, you are combining two roles: VPN endpoint and traffic director.
If you do NAT on the wrong leg (or for the wrong subnets), you can end up with a tunnel that functions perfectly while the network behaves like it’s haunted.

What “LAN access” really means

People say “I can’t access my LAN,” but they mean one of several distinct things:

  • Can’t reach LAN IPs: Ping to 192.168.1.10 fails from a remote client over the tunnel.
  • Can reach LAN IPs but services fail: SMB works intermittently, mDNS/Bonjour doesn’t, printer discovery is dead.
  • LAN devices can’t reach the VPN client: You can connect to NAS, but NAS can’t call back to your laptop (common with backups, monitoring agents, or reverse connections).
  • Everything goes through the VPN and LAN dies: Full tunnel catches RFC1918 traffic and routes it into the tunnel, blackholing local networks.

The fixes are different. If you jump straight to “add masquerade,” you’re choosing the quick dopamine hit over correctness.
Sometimes NAT is required (especially for “road warrior” clients), but you want to understand what you’re paying with: observability, identity, and policy.

Paraphrased idea from John Allspaw: Reliability comes from understanding how systems fail, not from pretending they won’t.
That applies to WireGuard NAT too.

Joke #1: NAT is like a witness protection program for packets. Great for privacy, terrible when you’re trying to interview the witness.

Facts and context: why this keeps happening

A few short, concrete facts help explain why router-based WireGuard + NAT turns into a recurring incident pattern:

  1. NAT wasn’t part of the original Internet design. It spread because IPv4 ran out and because it made “one public IP” deployments cheap.
  2. Linux IP forwarding defaults to off. Router behavior is opt-in; VPN tutorials that skip this create “handshake but no traffic” confusion.
  3. WireGuard’s config is intentionally minimal. No built-in “server mode,” no pushing routes, no magical NAT toggles; you glue it together with OS routing and firewall.
  4. AllowedIPs doubles as a route and a filter. This design prevents spoofing but surprises people expecting OpenVPN-style push routes.
  5. Consumer routers often ship with aggressive helper NAT. Some firmware adds masquerade rules broadly; it can accidentally NAT LAN-to-LAN or tunnel-to-LAN traffic.
  6. Split-tunnel is the default, full-tunnel is the footgun. The moment you route 0.0.0.0/0 through the tunnel, you’re now in the business of exceptions and policy routing.
  7. MTU issues became louder with VPN-over-ISP CGNAT. Path MTU discovery can be unreliable; blackholed ICMP makes “works for small pings” a classic symptom.
  8. Double NAT is normal now. Home users are often behind ISP NAT plus their own router NAT; VPNs add a third translation layer if you’re careless.
  9. NAT breaks end-to-end identity. It complicates logging, ACLs, and sometimes application protocols that embed IPs.

Fast diagnosis playbook

When LAN access breaks, don’t “try random firewall stuff.” Do this in order. The goal is to identify the bottleneck layer:
WireGuard crypto/handshake, routing, NAT, or filtering.

First: prove the tunnel is alive (control plane)

  • Check handshake time and transfer counters on the router.
  • Confirm the client has a route for the LAN (split tunnel) or at least a default route (full tunnel).

Second: prove basic forwarding works (data plane)

  • From the client, ping the router’s LAN IP and tunnel IP.
  • From the router, ping a LAN host using the tunnel source IP (or use tcpdump to see packets enter and leave).

Third: validate return paths (this is where it usually breaks)

  • On the LAN host (or LAN gateway), verify it has a route back to the WireGuard client subnet.
  • If it doesn’t, decide: add routes (correct) or do selective NAT (acceptable compromise).

Fourth: check firewall policy and NAT scope

  • Confirm forwarding rules allow wg0 → br-lan and br-lan → wg0.
  • Confirm NAT is applied only where needed (usually wg0 → wan for full tunnel, not wg0 → lan unless you’re intentionally hiding clients).

Fifth: MTU and DNS (the “everything is flaky” bucket)

  • If small packets work but large connections stall, test MTU.
  • If “LAN access” is actually “names don’t resolve,” inspect DNS and split DNS.

Practical tasks: commands, outputs, decisions

These are the tasks I actually run during incidents. Each includes: command, realistic output, what it means, and what decision you make next.
Examples assume a Linux-based router (Debian/OpenWrt-like userland). Translate to your platform as needed, but keep the logic.

Task 1: Check WireGuard handshake and counters

cr0x@server:~$ sudo wg show
interface: wg0
  public key: oR7...routerpub...
  listening port: 51820

peer: k9T...clientpub...
  endpoint: 198.51.100.23:53312
  allowed ips: 10.6.0.2/32
  latest handshake: 42 seconds ago
  transfer: 18.34 MiB received, 22.91 MiB sent
  persistent keepalive: every 25 seconds

What it means: Handshake is fresh, counters move. Crypto and UDP path are fine.

Decision: Stop blaming “WireGuard not working.” Move to routing/forwarding/NAT.

Task 2: Confirm the router has the expected tunnel address

cr0x@server:~$ ip -brief address show dev wg0
wg0             UP             10.6.0.1/24

What it means: Interface is up and addressed. If it’s DOWN or missing an IP, fix the interface config before anything else.

Decision: If address is wrong (e.g., /32 instead of /24 when you expect a subnet), fix and restart the interface.

Task 3: Verify IP forwarding is enabled

cr0x@server:~$ sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 0

What it means: The router is acting like a host. Packets won’t forward between wg0 and LAN/WAN.

Decision: Enable forwarding and persist it.

Task 4: Enable forwarding (temporary + persistent)

cr0x@server:~$ sudo sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1

What it means: Forwarding is on now; re-test traffic immediately.

Decision: If this fixes it, persist in /etc/sysctl.conf or distro equivalent and audit why it was off.

Task 5: Check routes on the router (main table)

cr0x@server:~$ ip route show
default via 203.0.113.1 dev wan0
10.6.0.0/24 dev wg0 proto kernel scope link src 10.6.0.1
192.168.50.0/24 dev br-lan proto kernel scope link src 192.168.50.1

What it means: Router knows both networks. Good. If the LAN subnet is missing, your LAN bridge isn’t configured. If wg0 route is missing, WireGuard didn’t apply the address.

Decision: If routes look correct, focus on firewall and NAT scope.

Task 6: Check policy routing rules (full tunnel setups often add these)

cr0x@server:~$ ip rule show
0:      from all lookup local
1000:   from 10.6.0.0/24 lookup 100
32766:  from all lookup main
32767:  from all lookup default

What it means: Traffic sourced from the WireGuard subnet uses table 100. This is common when forcing VPN clients out WAN or another uplink.

Decision: If LAN access breaks only for VPN clients, table 100 might be missing a route to 192.168.50.0/24 (or it’s sending it out WAN). Inspect table 100 next.

Task 7: Inspect the alternate routing table

cr0x@server:~$ ip route show table 100
default via 203.0.113.1 dev wan0

What it means: For VPN-sourced traffic, everything—including the LAN subnet—follows default route out wan0. That blackholes or hairpins LAN access.

Decision: Add an explicit route to the LAN in table 100, or fix your policy rule so LAN destinations use main.

Task 8: Add LAN route to policy table (example fix)

cr0x@server:~$ sudo ip route add 192.168.50.0/24 dev br-lan table 100

What it means: Now VPN client traffic destined for the LAN stays local.

Decision: Retest. If this fixes it, persist the route via your router’s network config system.

Task 9: Confirm the client is actually routing LAN via the tunnel

cr0x@server:~$ ip route get 192.168.50.10
192.168.50.10 via 10.6.0.1 dev wg0 src 10.6.0.2 uid 1000
    cache

What it means: The client will send LAN traffic to wg0. If it says dev wlan0 or your normal interface, your client AllowedIPs/split-tunnel is wrong.

Decision: Fix client config (AllowedIPs should include the LAN subnets you want reachable) before changing router NAT.

Task 10: Watch packets enter wg0 and leave toward LAN

cr0x@server:~$ sudo tcpdump -ni wg0 icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on wg0, link-type RAW (Raw IP), snapshot length 262144 bytes
12:01:10.112233 IP 10.6.0.2 > 192.168.50.10: ICMP echo request, id 4421, seq 1, length 64

What it means: The router is receiving the ping from the tunnel.

Decision: If you see it on wg0 but not on LAN, your forwarding/firewall is blocking. If you see it on LAN but no reply, it’s a return path issue.

Task 11: Confirm it leaves via the LAN interface

cr0x@server:~$ sudo tcpdump -ni br-lan icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on br-lan, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:01:10.112987 IP 10.6.0.2 > 192.168.50.10: ICMP echo request, id 4421, seq 1, length 64

What it means: Forwarding is working at least one direction: wg0 → LAN.

Decision: If no echo reply comes back to wg0, the LAN host doesn’t know how to return to 10.6.0.0/24 (or a firewall blocks it). Decide between adding routes or doing NAT.

Task 12: Check NAT rules (iptables legacy example)

cr0x@server:~$ sudo iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-A POSTROUTING -o wan0 -j MASQUERADE
-A POSTROUTING -o br-lan -j MASQUERADE

What it means: That second rule is suspicious: masquerading to br-lan means packets sent into the LAN will be source-NATed to the router’s LAN IP. Your LAN hosts will never see the real VPN client IP.

Decision: If your goal is “VPN clients are first-class LAN members,” delete that rule. If your goal is “access LAN without changing LAN routes,” then keep it—but understand the cost and scope it narrowly.

Task 13: Remove overly broad masquerade (dangerous if you rely on it)

cr0x@server:~$ sudo iptables -t nat -D POSTROUTING -o br-lan -j MASQUERADE

What it means: VPN-to-LAN traffic will now preserve source IPs (10.6.0.x). Return routing must be correct.

Decision: If things break after this, you’ve proven you were relying on NAT to paper over missing routes. Fix routing properly.

Task 14: Add a proper LAN route on the LAN gateway (example)

cr0x@server:~$ sudo ip route add 10.6.0.0/24 via 192.168.50.1

What it means: LAN devices using that gateway can now return traffic to the WireGuard subnet through the router.

Decision: If you can’t add routes on every LAN device, add it on the default gateway (or use DHCP option 121/classless static routes) so clients learn it automatically.

Task 15: Inspect nftables ruleset (modern routers often use nft)

cr0x@server:~$ sudo nft list ruleset
table inet filter {
  chain forward {
    type filter hook forward priority filter; policy drop;
    iifname "wg0" oifname "br-lan" accept
    iifname "br-lan" oifname "wg0" ct state established,related accept
  }
}
table ip nat {
  chain postrouting {
    type nat hook postrouting priority srcnat; policy accept;
    oifname "wan0" masquerade
  }
}

What it means: Forward chain allows wg0 → LAN, but LAN → wg0 only allows established/related. That blocks LAN-initiated connections to VPN clients (and breaks some protocols that don’t look “established” the way you expect).

Decision: Decide whether you want LAN → VPN initiation. If yes, add an explicit accept for iif br-lan oif wg0 with appropriate restrictions.

Task 16: Test MTU if you see “works for ping, fails for apps”

cr0x@server:~$ ping -M do -s 1420 192.168.50.10 -c 2
PING 192.168.50.10 (192.168.50.10) 1420(1448) bytes of data.
ping: local error: message too long, mtu=1420
ping: local error: message too long, mtu=1420

--- 192.168.50.10 ping statistics ---
2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1026ms

What it means: Your path can’t handle that size with DF set. You need a lower tunnel MTU or MSS clamping.

Decision: Drop WireGuard MTU (e.g., 1280–1380 depending on WAN) and retest with incremental sizes.

Joke #2: The packet was too big for the tunnel, like a storage engineer trying to fit “just one more dataset” on a full pool.

Common mistakes: symptoms → root cause → fix

This section is opinionated because it needs to be. These are the mistakes that keep showing up in ticket queues and home-lab writeups.
Each one includes the symptom you’ll see, the actual root cause, and a fix that doesn’t create the next incident.

1) “Handshake works, but I can’t ping any LAN hosts”

Symptom: wg show shows recent handshake; traffic counters increase; LAN IPs don’t respond.

Root cause: Missing return route from LAN back to the WireGuard client subnet (10.6.0.0/24, 10.0.0.0/24, etc.).

Fix: Add a route on the LAN gateway pointing the WireGuard subnet to the router’s LAN IP. If that’s impossible, do selective NAT for wg0 → LAN, scoped to the LAN subnet only.

2) “LAN access works, but LAN devices see everything coming from the router”

Symptom: NAS logs show source IP = 192.168.50.1 for all VPN clients; per-client ACLs fail.

Root cause: Masquerade applied on wg0 → LAN (POSTROUTING on br-lan). You turned remote clients into “the router.”

Fix: Remove NAT for LAN-bound traffic; add proper routing. If you must NAT, restrict it to a small set of legacy devices and document it.

3) “I turned on full tunnel, now local network access is broken on the client”

Symptom: Client can’t reach 192.168.0.1 on the local Wi‑Fi after enabling AllowedIPs = 0.0.0.0/0.

Root cause: Full tunnel hijacks all IPv4 routes, including RFC1918. Client tries to reach local gateway through the tunnel.

Fix: Use split tunnel (only route what you need), or add explicit “local LAN bypass” routes on the client. On some clients this is “exclude private IPs,” on others you add manual routes.

4) “Some services work, but SMB/RDP is flaky or hangs”

Symptom: Ping works, small HTTP works, but large transfers stall or remote desktop freezes.

Root cause: MTU/PMTUD blackhole. The tunnel overhead pushes packets above path MTU; ICMP fragmentation-needed is blocked by someone’s firewall.

Fix: Lower WireGuard MTU (start around 1380, go down to 1280 if needed) or clamp TCP MSS on the router for wg0 flows.

5) “Only one VLAN works over VPN; other VLANs are dead”

Symptom: Can reach 192.168.50.0/24 but not 192.168.60.0/24.

Root cause: AllowedIPs on the client or server peer doesn’t include all LAN prefixes, or firewall rules only allow one interface/zone.

Fix: Add the missing VLAN subnets to AllowedIPs on the client and ensure router firewall forwards wg0 to the VLAN interfaces.

6) “VPN clients can reach LAN, but LAN can’t reach VPN clients”

Symptom: Remote client can SSH into NAS, but NAS can’t connect back to the client for a reverse callback.

Root cause: Firewall forward policy only permits established flows from LAN to wg0, or NAT hides the client and breaks inbound initiation.

Fix: Permit LAN → wg0 where required, or keep it blocked intentionally and accept that the VPN is client-initiated only. Don’t accidentally block and then wonder why backups can’t push.

7) “DNS works for Internet, but internal names don’t resolve”

Symptom: nas.lan fails but 1.1.1.1 works fine.

Root cause: Client uses public DNS over the tunnel; no split DNS; search domains missing. People call it “LAN access,” but it’s name resolution.

Fix: Push/use internal DNS for the LAN domain when on VPN. If you run full tunnel, use the router’s resolver; if split, configure per-domain DNS if your client supports it.

8) “It worked yesterday, now it doesn’t, and nothing changed (allegedly)”

Symptom: Sudden failure after ISP or router reboot; handshakes still happen.

Root cause: Dynamic WAN IP changed and peer endpoint isn’t updated, or NAT state/conntrack got reset and reveals asymmetric routing that NAT had been masking.

Fix: Ensure keepalive for road-warrior clients, consider dynamic endpoint update strategies, and fix routing so you’re not dependent on stale conntrack state.

Three corporate mini-stories from the NAT trenches

Mini-story 1: The incident caused by a wrong assumption

A mid-sized company rolled out WireGuard on a branch router so on-call engineers could access internal tools during an office move.
The person who built it assumed “VPN clients should look like they’re on the LAN.” Reasonable goal, wrong implementation.

They enabled a broad masquerade rule for anything coming from wg0 and going to the LAN bridge. It “fixed” reachability immediately.
Engineers could hit Jira, Grafana, and the file server. Everyone celebrated and moved on.

Two weeks later, security asked why the file server logs showed the router as the source for every VPN session.
Then operations noticed rate limiting was triggering against the router’s LAN IP, not the actual client IPs.
A couple of internal ACLs that were supposed to be “admins only” became “any VPN user” because the ACL was keyed on source IP and the router was on the allowlist.

The incident wasn’t “WireGuard insecurity.” It was identity collapse caused by NAT.
The fix was boring: remove wg0→LAN NAT, add a route for the VPN subnet on the LAN gateway, and update firewall policy to explicitly permit the intended flows.
After that, logs and ACLs started making sense again, which is a weird kind of joy.

Mini-story 2: The optimization that backfired

Another org wanted faster remote access for developers working from home. Someone had read that “NAT is expensive” and tried to optimize away conntrack.
They implemented policy routing so VPN client traffic used a special table and bypassed some firewall chains, expecting lower latency.

In isolation, the change looked clean. The tunnel stayed up. Throughput benchmarks to the Internet improved a bit.
Then an entirely different thing broke: access to internal Git over the LAN VLAN became intermittent, but only for certain developers.

The culprit was the policy table missing a specific route for one of the internal subnets.
Traffic from 10.6.0.0/24 to 192.168.70.0/24 followed the policy default route out the WAN interface.
Replies never came back, because those packets never should have left the building in the first place.

The “optimization” created a parallel routing universe that drifted from reality. The fix was also boring: replicate required LAN routes into the policy table,
add a regression test that validated reachability to every internal prefix, and stop treating policy routing like a performance tweak you can do on a Friday afternoon.

Mini-story 3: The boring but correct practice that saved the day

A third team ran a fleet of small routers for remote sites, all managed the same way. Their WireGuard config template never included wg0→LAN masquerade.
Instead, every site gateway carried a static route for the VPN client subnet back to the router, and DHCP distributed classless routes where needed.

It was unglamorous. It required keeping an inventory of which subnets existed and making sure templates didn’t diverge.
But it meant packets preserved source identity end to end. Logging was accurate. Firewall policy was meaningful.

During a messy ISP outage at one site, they had to temporarily shift VPN egress to a backup uplink.
Because their design didn’t rely on NAT tricks for LAN access, the change was mostly about default routes and failover.
Internal access kept working while the uplink flapped. The on-call got to sleep.

The lesson: correctness scales. “Quick fixes” scale too, just in the opposite direction.

Patterns that actually work (and why)

Pattern A: Route it properly (preferred)

If your goal is real LAN membership—clients have stable tunnel IPs, you want per-client logging and ACLs—do routing, not NAT.
That means:

  • WireGuard clients live in a dedicated subnet (e.g., 10.6.0.0/24).
  • The router knows both LAN and VPN subnets (it does by default if configured).
  • The LAN gateway has a route back to the WireGuard subnet via the router.
  • Firewall permits the flows you want; denies the rest.

This is the only approach that makes identity, monitoring, and debugging sane. If you operate networks for a living, choose this unless you have a strong reason not to.

Pattern B: Selective NAT for legacy LANs (acceptable compromise)

Sometimes you cannot add routes to the LAN gateway. Maybe it’s an ISP-provided brick, maybe it’s a managed network you don’t control,
maybe the LAN is a zoo of static devices and you can’t touch them.

In that case, NAT can be a pragmatic tool—but scope it tightly:

  • NAT only from the WireGuard subnet to specific LAN prefixes.
  • Do not masquerade all wg0 traffic in all directions.
  • Keep a list of devices/subnets that rely on this so you can unwind it later.

The goal is to avoid the “all VPN clients become the router” syndrome, and to avoid unintended LAN-to-LAN NAT.

Pattern C: Full tunnel on a router (powerful, but you’re signing up for work)

Full tunnel is when clients route 0.0.0.0/0 (and sometimes ::/0) into wg0. On a router, this usually means you want remote clients to use your home/office egress
(for trust, geo, content filtering, or because the hotel Wi‑Fi is cursed).

Full tunnel almost always needs NAT on the WAN egress, because you’re sending private tunnel addresses out to the Internet. But that NAT belongs on wg0→WAN, not wg0→LAN.
Also, full tunnel introduces these recurring requirements:

  • LAN exceptions: ensure internal prefixes still route locally (especially if using policy routing tables).
  • DNS strategy: internal DNS for internal names; decide whether to resolve via router or split DNS.
  • MTU tuning: more hops, more encapsulation, more chance of PMTUD problems.

Where people go wrong: confusing “make it reachable” with “make it correct”

NAT is seductive because it can make packets come back without touching the LAN. But when you NAT the tunnel to the LAN, you’re rewriting the story your packets tell.
Everything downstream—logs, ACLs, rate limits, application audit trails—now sees “the router did it.”

If you’re doing this at home and you don’t care, fine. If you’re doing this at work and you care about attribution, don’t.

Checklists / step-by-step plan

Step-by-step: restore LAN access without cargo-cult NAT

  1. Confirm handshake and counters: wg show must show a recent handshake and non-zero transfer. If not, fix endpoints/keys/UDP reachability.
  2. Check router forwarding: enable net.ipv4.ip_forward=1. If IPv6 is involved, also enable IPv6 forwarding intentionally.
  3. Confirm client routing intent: client AllowedIPs must include the LAN subnets you want reachable (split tunnel) or 0.0.0.0/0 (full tunnel).
  4. Confirm router routes: router must have connected routes for LAN and wg0. If using policy routing, confirm those tables include LAN routes too.
  5. Prove packet flow with tcpdump: see ICMP/TCP packets on wg0 and br-lan. If it doesn’t traverse, it’s firewall/forwarding.
  6. Fix return path properly: add a route for the WireGuard subnet on the LAN gateway pointing at the router. Prefer doing this once on the gateway, not on every host.
  7. Only then consider NAT: if you truly can’t fix routing, add a scoped NAT rule from wg0 subnet to LAN subnet, not a broad masquerade.
  8. Lock down firewall policy: allow only required protocols from wg0 to LAN; consider blocking lateral movement by default.
  9. Validate MTU: test large packets and tune MTU/MSS if needed.
  10. Document it: include which subnets exist, why NAT exists (if it does), and what “working” means (tests you can run).

Decision checklist: should you NAT VPN-to-LAN?

  • Do you control the LAN gateway? If yes, route it. If no, NAT might be your only option.
  • Do you need per-client attribution on LAN systems? If yes, do not NAT wg0→LAN.
  • Do you expect LAN-initiated connections to VPN clients? If yes, routing is far easier than NAT + port forwards + sadness.
  • Is this temporary? If you must NAT, treat it as technical debt with an exit plan.

Regression tests (run after every change)

Make these tests muscle memory. They catch most breakages:

  • From VPN client: ping router LAN IP, ping one LAN host, connect to one TCP service (SSH/HTTPS/SMB).
  • From router: ping LAN host, ping VPN client tunnel IP.
  • From a LAN host: ping VPN client tunnel IP (if you want LAN→VPN), or confirm it’s blocked (if you don’t).
  • Check logs: confirm LAN service sees VPN client source IP (if routing design) or sees router (if NAT design, intentionally).

FAQ

1) Why does WireGuard “connect” but LAN traffic doesn’t move?

The handshake only proves cryptographic session establishment. Data traffic still needs IP forwarding, correct routes, and firewall permission.
Most often the forward path works but the return route from LAN to VPN subnet is missing.

2) Is AllowedIPs a firewall rule?

Not really. It behaves like a routing selector (what destinations go to that peer) and a source filter (what source addresses are accepted from that peer).
Treat it like routing policy, then use the real firewall for access control.

3) Should I masquerade WireGuard traffic?

Masquerade is usually correct for wg0→WAN when doing full tunnel egress. Masquerading wg0→LAN is usually a workaround for missing routes.
Use routing if you can; use scoped NAT only when you must.

4) My LAN is 192.168.1.0/24 and the remote network is also 192.168.1.0/24. What now?

Overlapping subnets are a routing dead-end. You need to renumber one side, or NAT one side into a non-overlapping range, or use application-level proxies.
If this is a site-to-site VPN, plan a renumbering project and stop pretending it won’t happen.

5) Why can I reach IPs but not hostnames?

That’s DNS, not routing. Your client may be using public DNS or lacks the LAN search domain.
Configure the VPN client to use your internal DNS (or run a resolver on the router) and ensure internal zones are reachable.

6) How do I allow VPN clients to access only one LAN host (like a NAS) and nothing else?

Route correctly (no NAT), then enforce with firewall rules: allow wg0 to the NAS IP/ports, deny wg0 to the rest of the LAN.
Doing this with NAT makes auditing harder and can create accidental access via the router’s own privileges.

7) Why does traffic fail only for large downloads or file copies?

MTU/PMTUD issues. The path can’t carry large encapsulated packets, and ICMP “fragmentation needed” may be blocked.
Lower WireGuard MTU or clamp TCP MSS at the router for traffic traversing wg0.

8) What’s the cleanest way to avoid adding routes on every LAN device?

Add a route on the LAN default gateway to the WireGuard subnet via the router. If your LAN has multiple gateways/VLANs, put the route in the L3 core.
For endpoints, DHCP classless static routes can help, but the gateway route is the simplest.

9) Do I need to allow br-lan → wg0 forwarding?

Only if you want LAN-initiated connections to VPN clients. Many setups intentionally block this for security.
But be explicit: if you block it, document that VPN is client-initiated only so nobody wastes a weekend debugging “broken callbacks.”

Next steps you should do today

If your current setup “works” only because you masquerade wg0 into the LAN, you’re one change away from a weird outage or a logging mystery.
Fix it like you mean it.

  1. Audit NAT scope: ensure masquerade exists for wg0→WAN if needed, and remove wg0→LAN masquerade unless it’s an explicit, documented compromise.
  2. Make return routing correct: add the WireGuard subnet route on the LAN gateway and verify with a LAN-side ping to a VPN client IP.
  3. Validate with packet captures: tcpdump on wg0 and LAN to prove where the packet stops.
  4. Decide your security posture: is LAN allowed to initiate to VPN clients? If yes, permit it carefully; if no, block it loudly and intentionally.
  5. Write a one-page runbook: include your subnets, where NAT exists, and three regression tests. Future you will be less angry.

Do those things, and WireGuard becomes what it’s supposed to be: a simple encrypted interface, not a recurring exercise in interpretive NAT.

← Previous
Email: “554 spam detected” — clean up reputation without wasting weeks
Next →
Windows Phone: How a Good OS Lost to Ecosystems

Leave a comment