Wireguard Full Tunnel without masquerading

Hello everyone, my current network is setup as follows:


Site A: Router with Wireguard peer 10.0.100.1.
Site B: Router running OpenWRT 24.10.0. Wireguard peer IP of 10.0.100.7. Devices connected to the LAN ports are on the 10.1.21.x/24 subnet. Uplink WAN is via WiFi.

Currently, all Wireguard VPN LAN packets are reaching their destinations correctly. For example, devices behind the site A router can reach devices behind site B via the WG VPN. Devices behind the site B router can reach devices behind site A. Other WG clients (ex. 10.0.100.2) can reach devices behind site A and B routers.

My current setup on site B allows VPN LAN traffic only and drops WAN traffic by design.

Now, instead of dropping site B's WAN traffic, I'd like to forward it to site A's router via Wireguard, and forward it to site A's WAN port. This would be a full tunnel setup.

I've read this guide, but it requires masquerading to be on: https://openwrt.org/docs/guide-user/services/vpn/wireguard/all-traffic-through-wireguard

I'd like to forward all of site B's traffic to site A WITHOUT masquerading because I'd like to use the site A router's firewall to filter packets by the IP address of site B's devices and keep logs. With masquerading, all IP addresses will be from the site B router, not the devices themselves.

When I follow the guide above to enable full tunnel VPN forwarding from site B to site A without masquerading, site B's OpenWRT router cannot connect to site A's WG client at all. Packets are sent via the WG vpn interface, but none are received.

Here is site B router's config attempting full tunnel, but doesn't connect to site A's client:

cat /etc/config/network

config interface 'loopback'
	option device 'lo'
	option proto 'static'
	option ipaddr '127.0.0.1'
	option netmask '255.0.0.0'

config globals 'globals'
	option ula_prefix 'xxxx:xxxx:xxxx::/48'
	option packet_steering '1'

config device
	option name 'br-lan'
	option type 'bridge'
	list ports 'lan1'
	list ports 'lan2'
	list ports 'lan3'
	list ports 'wan' (using wan port as lan due to lack of ports)
	option ipv6 '0'

config device
	option name 'lan1'
	option macaddr 'xx:xx:xx:xx:xx:36'

config device
	option name 'lan2'
	option macaddr 'xx:xx:xx:xx:xx:36'

config device
	option name 'lan3'
	option macaddr 'xx:xx:xx:xx:xx:36'

config interface 'lan'
	option device 'br-lan'
	option proto 'static'
	option ip6assign '60'
	option gateway '127.0.0.1'
	option defaultroute '0'
	list ipaddr '10.1.21.1/24'

config device
	option name 'wan'
	option macaddr 'xx:xx:xx:xx:xx:37'

config interface 'wwan'
	option proto 'dhcp'

config interface 'vpn'
	option proto 'wireguard'
	option private_key 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx='
	option nohostroute '1'
	list addresses '10.0.100.7/16'

config wireguard_vpn 'wgserver'
	option public_key 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx='
	option preshared_key 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx='
	option endpoint_host 'xxxx.xxxx.xxxx'
	option endpoint_port '12345'
	option persistent_keepalive '25'
	option route_allowed_ips '1'
	option description 'xxxx'
	list allowed_ips '10.0.0.0/16'
	list allowed_ips '0.0.0.0/0' <--- fails to establish WG VPN connection with this. Without, WG VPN is fine.

config route
	option interface 'vpn'
	option target '10.0.0.0/16'
	option gateway '10.0.100.7'
cat /etc/config/firewall

config defaults
	option input 'DROP'
	option output 'DROP'
	option forward 'DROP'
	option synflood_protect '1'
	option drop_invalid '1'

config zone 'lan'
	option name 'lan'
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'ACCEPT'
	list network 'lan'

config zone 'wan'
	option name 'wan'
	option input 'REJECT'
	option output 'ACCEPT'
	option forward 'REJECT'
	option masq '1'
	option mtu_fix '1'
	list network 'wwan'

config rule
	option name 'Allow-DHCP-Renew'
	option src 'wan'
	option proto 'udp'
	option dest_port '68'
	option target 'ACCEPT'
	option family 'ipv4'

config rule
	option name 'Allow-Ping'
	option src 'wan'
	option proto 'icmp'
	option icmp_type 'echo-request'
	option family 'ipv4'
	option target 'ACCEPT'

config rule
	option name 'Allow-IGMP'
	option src 'wan'
	option proto 'igmp'
	option family 'ipv4'
	option target 'ACCEPT'

config rule
	option name 'Allow-MLD'
	option src 'wan'
	option proto 'icmp'
	option src_ip 'fe80::/10'
	list icmp_type '130/0'
	list icmp_type '131/0'
	list icmp_type '132/0'
	list icmp_type '143/0'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-IPSec-ESP'
	option src 'wan'
	option dest 'lan'
	option proto 'esp'
	option target 'ACCEPT'

config rule
	option name 'Allow-ISAKMP'
	option src 'wan'
	option dest 'lan'
	option dest_port '500'
	option proto 'udp'
	option target 'ACCEPT'

config zone
	option name 'vpn'
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'REJECT'
	list network 'vpn'

config forwarding
	option src 'vpn'
	option dest 'lan'

config forwarding
	option src 'lan'
	option dest 'vpn'

Some questions and comments:

  • Why is masquerading necessary in the full tunnel example above?
  • I believe with list allowed_ips '0.0.0.0/0', the router is trying to route all packets, including site A's peer address option endpoint_host 'xxxx.xxxx.xxxx' during the initial WG handshake, via the WG VPN. The WG VPN isn't established yet, so the packet never reaches site A's router, and the VPN connection is never established.
  • If I add list allowed_ips '1.1.1.1/32' instead of list allowed_ips '0.0.0.0/0', I can ping 1.1.1.1 from site B via site A. How can I do this will all IPs from site B? There must be a way to forward '0.0.0.0/0'` from site B to site A without masquerading.

Thank you for your time and help.

Remove this.

When all traffic is routed through the tunnel, there must be an explicit route for the remote peer via the wan interface to prevent the tunnel from collapsing.
That option does not allow the creation of such a route.

1 Like

It is not.
Site to Site traffic is under normal circumstances plain Layer-3 routing.
I also fail to see where (except on wan) you have set option masq '1'...

allowed_ips specify destination addresses which are allowed to be processed by the wireguard interface. Routing of packets to that interface is done with ip route or handled by UCI.
Like, you can have allowed_ips '0.0.0.0/0' but adding only specific routes to your local routing table. Like i.e. if you use a dynamic routing daemon for OSPF or BGP.

Nice catch @pavelgl . What does nohostroute, do?

It prevents the creation of an explicit route for the remote peer, which is needed when all traffic is routed over wireguard.

https://www.wireguard.com/netns/#routing-all-your-traffic

1 Like

But this option is OpenWrt specific or not?
I most of the time handle my routes with bird2 only.

@_bernd, the option to disable the host route looks OpenWRT specific, at least I have never seen it elsewhere.
All clients I know make a host route

For the OP, Masquerading is not enabled but side A has to allow traffic from side B's subnet 10.1.21.0/24 so add that as Allowed IPs to site A and enable Route Allowed IPs if that is not yet done.

You have very large subnet masks, I have no overview of all involved subnets but that can get you into trouble:

The following can be removed a route via the tunnel is automatically established:

For a more tailored advice it helps if we see the current configs of both sides, Remember to redact keys, passwords, MAC addresses and any public IP addresses you may have::

ubus call system board
cat /etc/config/network
cat /etc/config/firewall
ip route show
wg show
1 Like

Thanks for chiming in everyone. I've made the following changes, but unfortunately site B WG still cannot connect to site A WG.

Removed option nohostroute '1'.

The Wireguard interface now looks like this:

config interface 'vpn'
	option proto 'wireguard'
	option private_key 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx='
	list addresses '10.0.100.7/32'

config wireguard_vpn 'wgserver'
	option public_key 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx='
	option preshared_key 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx='
	option endpoint_host 'xxxx.xxxx.xxxx' <---DDNS to site A WG
	option endpoint_port '12345'
	option persistent_keepalive '25'
	option description 'xxxx'
	list allowed_ips '0.0.0.0/0' <--- fails to establish WG VPN connection with this. If '10.0.0.0/16', packets to 10.0.0.0/16 are successfully routed to site A.

I've removed this route, as it's redundant.

With the setup above, I get the following:

Protocol: WireGuard VPN
Uptime: 15h 35m 8s
RX: 0 B (0 Pkts.)
TX: 1.56 MB (10352 Pkts.)
IPv4: 10.0.100.7/32

With list allowed_ips '10.0.0.0/16' only (without 0.0.0.0/0) for site B, its WG establishes a connection to site A's WG:

Protocol: WireGuard VPN
Uptime: 9h 30m 13s
RX: 2.39 GB (2017278 Pkts.)
TX: 176.59 MB (1768489 Pkts.)
IPv4: 10.0.100.7/32

As mentioned above, if I add list allowed_ips '1.1.1.1/32' and list allowed_ips '10.0.0.0/16' instead of list allowed_ips '0.0.0.0/0' , I can ping 1.1.1.1 from site B via site A. How can I do this will all IPs from site B? Hope that makes sense, and please let me know if you need more info from my side.

See inline comment

Site A must also have as Allowed IPs for the peer of Site B: 10.1.2.0/24 (subnet of side B) and have Route Allowed IPs enabled

Please post output of both Site A and Site B of (redact keys, MAC, Public IP etc):

ubus call system board
cat /etc/config/network
cat /etc/config/firewall
ip route show
wg show