WireGuard server on secondary router

Hi everyone,

I'm trying to setup a WireGuard tunnel with OpenWrt, but I just can't get routing working.

I mostly followed https://openwrt.org/docs/guide-user/services/vpn/wireguard/server, but my setup is a little different: The OpenWrt device (some old TP-Link router) isn't the main router, but a dump Wifi AP and supposed future WireGuard "server". The WAN port is consequently not being used. My main router is a AVM Fritz!Box. I therefore already configured a static route for the private VPN network and a port forwarding rule for 51820/udp on the Fritz!Box targeting the OpenWrt device, adapting https://openwrt.org/docs/guide-user/services/vpn/wireguard/extras#split_gateway.

My ultimate goal is allowing three common use cases:

  1. WireGuard clients should be able to route all their traffic through the VPN,
  2. WireGuard clients should be able to connect to other devices in my LAN, and
  3. WireGuard clients should be able to connect their LAN with the server's LAN (i.e. a site-to-site config following https://openwrt.org/docs/guide-user/services/vpn/wireguard/site-to-site).

Use cases (1) and (2) correspond to "Client 2" below, use case (3) corresponds to "Client 1". For now I just want to get (1) and (2) working (i.e. I'm connecting "Client 2").

Since the original setup from the wiki didn't work, I created a separate firewall zone with masquerading, but still no luck. Here's the config I came up with:

Local network: 10.69.42.0/24
IP address of AVM Fritz!Box (main router): 10.69.42.1
IP address of OpenWrt device ("WireGuard server"): 10.69.42.2
WireGuard network: 10.162.83.0/24

# /etc/config/network (snippet)
config interface 'lan'
        option proto 'static'
        option ipaddr '10.69.42.2'
        option netmask '255.255.255.0'
        option gateway '10.69.42.1'
        option ip6assign '64'
        list dns '10.69.42.1'
        option device 'br-lan'

config interface 'wg0'
        option proto 'wireguard'
        option private_key '…'
        option listen_port '51820'
        list addresses '10.162.83.1/24'
        list addresses 'fdd7:9be5:32c9:fe63::1/64'

config wireguard_wg0
        option description 'Client 1'
        option public_key '…'
        option preshared_key '…'
        option persistent_keepalive '25'
        list allowed_ips '10.162.83.2/32'
        list allowed_ips 'fdd7:9be5:32c9:fe63::2/128'
        list allowed_ips '10.136.162.0/24'
        option route_allowed_ips '1'

config wireguard_wg0
        option description 'Client 2'
        option public_key '…'
        option preshared_key '…'
        option persistent_keepalive '25'
        list allowed_ips '10.162.83.3/32'
        list allowed_ips 'fdd7:9be5:32c9:fe63::3/128'
# /etc/config/firewall (snippet)
config zone 'lan'
        option name 'lan'
        list network 'lan'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'ACCEPT'

config zone 'wg'
        option name 'wg'
        list network 'wg0'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'REJECT'
        option masq '1'
        option mtu_fix '1'

config forwarding
        option src 'wg'
        option dest 'lan'

The WireGuard handshake works (i.e. clients can connect to the WireGuard "server"; wg show on the client indicates a successful handshake and the client's kernel dyndb log shows that it receives keep alive packages from the "server"), but I can't route any traffic through the tunnel (I can't even ping 10.162.83.1 from the client).

Any hints what is missing?

Set to ACCEPT

Thanks for the fast response! Unfortunately the change made no difference: the WireGuard handshake still succeeds, but I still can't route any traffic through the tunnel.

For completeness, here's my client's WireGuard config:

[Interface]
Address = 10.162.83.3/24,fdd7:9be5:32c9:fe63::3/64
PrivateKey = …
ListenPort = 51820

[Peer]
PublicKey = …
PresharedKey = …
Endpoint = …:51820
AllowedIPs = 0.0.0.0/0,::/0

And some correction: I can indeed ping both 10.162.83.1 (i.e. the WireGuard server's address in the VPN network) and 10.69.42.2 (i.e. the WireGuard server's address in the LAN network) from the WireGuard client - with both your suggested change and without (no idea why it didn't work before). But I still can't ping any other device in the WireGuard server's LAN network (e.g. the main router 10.69.42.1) or connect to any outside servers (e.g. Google) from the WireGuard client.

Maybe your static route on the Fritzbox is not working?

As a test can you enable option masq on the lan interface?

BTW
You do not need option masq on the wg interface.

For client 2 did you enable route allowed IPs?
(It should work without as your address is /24)

There are two ways to do this:

  1. Wireguard users will be in the existing lan. This means that everything in lan will reach the Internet via Wireguard.
  2. Make a new separate network in the OpenWrt router for wireguard users.

Case 2 is simpler and the only real downside is that the wireguard users will need to know the IP addresses of machines in the LAN to reach them: automatic discovery of printers etc will not work. The setup for this is the same as a guest network on a main router, only instead of guest->wan routing you have guest->vpn.

Oh, that's the one :+1:

By switching masquerading from the wg zone to lan it started working.Thinking about it this kinda makes sense: just as for LAN <> WAN traffic masquerading must be enabled on the destination zone, not on the source zone. For WireGuard the LAN zone is the destination. It just feels weird to enable masquerading on the LAN zone, but yeah, this way it works.

Thank you very much @egc! :heart:


Another issue showed up: For some reason I can't connect to SSH via the WireGuard tunnel. I can ping 10.69.42.2 (i.e. the WireGuard server), I can even open LuCi in my browser, but attempting to connect via SSH just hangs indefinitely. I didn't limit the interface in the Dropbear config though (I didn't change Dropbear's config at all, i.e. interface is still "unspecified" in LuCi).

I checked the router's syslog and it shows a connection, but nothing else:

Sat Jul 29 20:23:52 2023 authpriv.info dropbear[2398]: Child connection from 10.162.83.3:43666

Running ssh -v indicates that ssh is waiting for server's key, but nothing is sent:

…
debug1: Connecting to 10.69.42.2 [10.69.42.2] port 22.
debug1: Connection established.
…
debug1: Local version string SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.7
debug1: Remote protocol version 2.0, remote software version dropbear
debug1: no match: dropbear
debug1: Authenticating to 10.69.42.2:22 as 'root'
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: algorithm: curve25519-sha256
debug1: kex: host key algorithm: rsa-sha2-256
debug1: kex: server->client cipher: chacha20-poly1305@openssh.com MAC: <implicit> compression: none
debug1: kex: client->server cipher: chacha20-poly1305@openssh.com MAC: <implicit> compression: none
debug1: expecting SSH2_MSG_KEX_ECDH_REPLY

Any idea what might be the problem?


About my other client with the site-to-site config: Since I'm currently in the LAN with the WireGuard server I unfortunately can't setup and test the site-to-site config. Thus I'm marking this thread as solved for now. If I experience any issues with https://openwrt.org/docs/guide-user/services/vpn/wireguard/site-to-site I'll open another thread and reference it here.

Thanks again!


Thank you for the explanation @mk24! :+1: Makes sense. Since I'm connecting separate networks and don't need things like autodiscovery of printers there's no need to have the WireGuard users in the same network, thus I'll go with the simpler setup with separate networks and masquerading.


For completeness and for others with the same issue, here's the full working config:

Local network: 10.69.42.0/24
IP address of AVM Fritz!Box (main router): 10.69.42.1
IP address of OpenWrt device ("WireGuard server"): 10.69.42.2
WireGuard network: 10.162.83.0/24

 /etc/config/network (snippet)
config interface 'lan'
        option proto 'static'
        option ipaddr '10.69.42.2'
        option netmask '255.255.255.0'
        option gateway '10.69.42.1'
        option ip6assign '64'
        list dns '10.69.42.1'
        option device 'br-lan'

config interface 'wg0'
        option proto 'wireguard'
        option private_key '…'
        option listen_port '51820'
        list addresses '10.162.83.1/24'
        list addresses 'fdd7:9be5:32c9:fe63::1/64'

config wireguard_wg0
        option description 'Client 1'
        option public_key '…'
        option preshared_key '…'
        option persistent_keepalive '25'
        list allowed_ips '10.162.83.2/32'
        list allowed_ips 'fdd7:9be5:32c9:fe63::2/128'
        list allowed_ips '10.136.162.0/24'
        option route_allowed_ips '1'

config wireguard_wg0
        option description 'Client 2'
        option public_key '…'
        option preshared_key '…'
        option persistent_keepalive '25'
        list allowed_ips '10.162.83.3/32'
        list allowed_ips 'fdd7:9be5:32c9:fe63::3/128'
# /etc/config/firewall (snippet)
config zone 'lan'
        option name 'lan'
        list network 'lan'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'ACCEPT'
        option masq '1'
        option mtu_fix '1'

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

config forwarding
        option src 'wg'
        option dest 'lan'
# WireGuard client config
[Interface]
Address = 10.162.83.3/32,fdd7:9be5:32c9:fe63::3/128
PrivateKey = …

[Peer]
PublicKey = …
PresharedKey = …
Endpoint = …:51820
AllowedIPs = 0.0.0.0/0,::/0

Hi again,

I'm now in the LAN with the previously remote network and created the site-to-site-config. I had to add a forwarding rule for lanwg as well to enable the site-to-site config (i.e. wglan). The wglan forwarding apparently only allows devices in the remote 10.136.162.0/24 network to connect (in terms of "initiating a new connection") with devices in the local 10.69.42.0/24 network, but not the other way round. To also allow devices in the local 10.69.42.0/24 network to connect to devices in the remote 10.136.162.0/24 network, one also needs lanwg forwarding on both endpoints.

One issue arised: Originally I planned using another Fritz!Box with WireGuard support on the remote 10.136.162.0/24 network as VPN server, but failed to do so. I suspect that the issue is with AVM not choosing to create a separate network (10.162.83.0/24 in my case) for the VPN, but to dump the devices into the same network as local devices (10.136.162.0/24 in my case) - basically as suggested by @mk24. It seems like the Fritz!Box then fails to add routes for the remote network (10.69.42.0/24 in my case). So before wasting my time with AVM I decided using another OpenWrt router instead. It's simpler this way... One basically just copies the config over and replaces all occurrences of 10.69.42. by 10.136.162. and updates the WireGuard keys accordingly. :see_no_evil:

The SSH server issue somehow disappeared. Since I was using a mobile network to test the VPN the issue might have been related to this, but who knows... Even though I didn't change anything I can now connect to the SSH server even when connected via WireGuard, that's what matters.

For completeness and for others, here's the full working config. For the site-to-site config one just has to replicate the exact same setup on the other site as well (with IP addresses switched, new preshared keys for plain clients and the public/private keys of the sites switched). Note that I've also renamed the wg zone to vpn.

Local network: 10.69.42.0/24
IP address of AVM Fritz!Box (main router): 10.69.42.1
IP address of OpenWrt device ("WireGuard server"): 10.69.42.2
WireGuard network: 10.162.83.0/24
Remote network of Client 1: 10.136.162.0/24

# /etc/config/network (snippet)
config interface 'lan'
        option proto 'static'
        option ipaddr '10.69.42.2'
        option netmask '255.255.255.0'
        option gateway '10.69.42.1'
        option ip6assign '64'
        list dns '10.69.42.1'
        option device 'br-lan'

config interface 'wg0'
        option proto 'wireguard'
        option private_key '…'
        option listen_port '51820'
        list addresses '10.162.83.1/24'
        list addresses 'fdd7:9be5:32c9:fe63::1/64'

config wireguard_wg0
        option description 'Client 1'
        option public_key '…'
        option preshared_key '…'
        option persistent_keepalive '25'
        list allowed_ips '10.162.83.2/32'
        list allowed_ips 'fdd7:9be5:32c9:fe63::2/128'
        list allowed_ips '10.136.162.0/24'
        option route_allowed_ips '1'

config wireguard_wg0
        option description 'Client 2'
        option public_key '…'
        option preshared_key '…'
        option persistent_keepalive '25'
        list allowed_ips '10.162.83.3/32'
        list allowed_ips 'fdd7:9be5:32c9:fe63::3/128'
# /etc/config/firewall (snippet)
config zone 'lan'
        option name 'lan'
        list network 'lan'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'ACCEPT'
        option masq '1'
        option mtu_fix '1'

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

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

config forwarding
        option src 'lan'
        option dest 'vpn'
# WireGuard client config ("Client 2")
[Interface]
PrivateKey = …
Address = 10.162.83.3/32,fdd7:9be5:32c9:fe63::3/128
DNS = 10.69.42.1

[Peer]
PublicKey = …
PresharedKey = …
Endpoint = …:51820
AllowedIPs = 0.0.0.0/0,::/0

Marking this post as solution. Thanks everyone for your help! :heart:

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.