#2769·wg-easy

[Bug]: Per-Client Firewall (WG_CLIENTS chain) doesn't account for a client's routed subnets, blocking legitimate return traffic from site-to-site peers

Author: hannes-hanischCreated Aug 25, 2026Updated Sep 2, 2026

Describe the bug

When a client has additional routed subnets configured via "Server Allowed IPs" (site-to-site setup, e.g. a router/gateway peer routing a LAN behind it), the Per-Client Firewall feature (WG_CLIENTS chain) only matches traffic based on the client's own tunnel IP as source — it does not account for traffic originating from the subnets routed through that client. This causes legitimate return traffic from devices behind the site-to-site peer to be dropped.

Steps to reproduce:

Create two clients: Client A ("Admin"), tunnel IP 10.8.0.2, Firewall Allowed IPs: 0.0.0.0/0 Client B ("Gateway"), tunnel IP 10.8.0.3, Server Allowed IPs additionally includes 192.168.1.0/24 (a LAN routed through this peer), Firewall Allowed IPs: 10.8.0.0/24 (to allow other peers to reach it) Enable "Per-Client Firewall" in Interface settings From Client A, initiate an HTTP request to a device in 192.168.1.0/24 (routed via Client B)

Expected behavior:

The request should succeed — Client B's config explicitly routes 192.168.1.0/24, and Client A has 0.0.0.0/0 Firewall Allowed IPs, so traffic in both directions should be permitted.

Actual behavior:

The initial request out (Client A → 192.168.1.x) works. But the return traffic (source 192.168.1.x, i.e. the LAN device behind Client B, destined for Client A at 10.8.0.2) is dropped, because the WG_CLIENTS chain rule for Client B only matches -s 10.8.0.3, not the routed subnet 192.168.1.0/24. This return traffic falls through to the final catch-all DROP rule.

Confirmed via:

iptables -L WG_CLIENTS -n -v --line-numbers

showing packet counters incrementing on the final DROP rule (not on either client's ACCEPT rule) for traffic matching this pattern.

Suggested fix:

When generating the WG_CLIENTS ACCEPT rule for a client, the source match should include not just the client's own tunnel IP, but also any additional subnets present in that client's "Server Allowed IPs" (i.e. the same IP set already used for routing/anti-spoofing), e.g.:

iptables -A WG_CLIENTS -s 10.8.0.3/32 -j ACCEPT iptables -A WG_CLIENTS -s 192.168.1.0/24 -j ACCEPT

instead of only:

iptables -A WG_CLIENTS -s 10.8.0.3/32 -j ACCEPT

Environment:

wg-easy version: 15 (image ghcr.io/wg-easy/wg-easy:15) Deployment: Docker Compose, custom bridge network (not host networking)