[GH-ISSUE #5851] Masquerade not applied for traffic to local VIP (same-host Keepalived/VRRP) #12151

Open
opened 2026-08-05 01:32:32 -04:00 by saavagebueno · 0 comments
Owner

Originally created by @Alvis-pixel on GitHub (Apr 11, 2026).
Original GitHub issue: https://github.com/netbirdio/netbird/issues/5851

When a routing peer also hosts a Keepalived VIP (e.g., 192.168.100.200 on eth0), VPN traffic destined for that VIP never leaves the host — it's delivered locally. The built-in masquerade feature doesn't apply because the traffic never traverses an outgoing interface.

Setup:

  • NetBird v0.68.1 self-hosted
  • Routing peer on host with Keepalived VIP on eth0
  • Masquerade enabled in dashboard (Networks → Routing Peers)
  • Reverse proxy (Traefik) listening on the VIP

Expected: VPN client traffic (100.64.x.x) to the VIP is masqueraded to the host's LAN IP before reaching the reverse proxy.

Actual: Traffic arrives at the reverse proxy with the original CGNAT source IP (100.64.x.x). The reverse proxy sets X-Forwarded-For: 100.64.x.x, causing backend apps with "disable auth for local addresses" to
require authentication.

Workaround: Manual iptables rule without interface restriction:
iptables -t nat -A POSTROUTING -s 100.64.0.0/10 -j MASQUERADE

The default masquerade rules (if any are created) likely use -o which doesn't match locally-delivered traffic.

Originally created by @Alvis-pixel on GitHub (Apr 11, 2026). Original GitHub issue: https://github.com/netbirdio/netbird/issues/5851 When a routing peer also hosts a Keepalived VIP (e.g., 192.168.100.200 on eth0), VPN traffic destined for that VIP never leaves the host — it's delivered locally. The built-in masquerade feature doesn't apply because the traffic never traverses an outgoing interface. Setup: - NetBird v0.68.1 self-hosted - Routing peer on host with Keepalived VIP on eth0 - Masquerade enabled in dashboard (Networks → Routing Peers) - Reverse proxy (Traefik) listening on the VIP Expected: VPN client traffic (100.64.x.x) to the VIP is masqueraded to the host's LAN IP before reaching the reverse proxy. Actual: Traffic arrives at the reverse proxy with the original CGNAT source IP (100.64.x.x). The reverse proxy sets X-Forwarded-For: 100.64.x.x, causing backend apps with "disable auth for local addresses" to require authentication. Workaround: Manual iptables rule without interface restriction: iptables -t nat -A POSTROUTING -s 100.64.0.0/10 -j MASQUERADE The default masquerade rules (if any are created) likely use -o <interface> which doesn't match locally-delivered traffic.
saavagebueno added the triage-needed label 2026-08-05 01:32:32 -04:00
Sign in to join this conversation.
No Label triage-needed
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: DYNR/netbird#12151