OpenWrt client to linux hosted wireguard

I have reviewed the threads which are similar already

I have also gone through the docs https://openwrt.org/docs/guide-user/services/vpn/wireguard/start

What I want to do I have a cottage and want to install some IoT devices there. Those devices need to be able to see my home network (MQTT broker) to report status and get commands.

What I have working I have a wireguard server setup. Multiple client devices can connect to this wireguard and access my home network (including the MQTT broker).

I've also installed wireguard on the cottage OpenWRT router. I can see from the wireguard server that a connection is being made. Looking at the status of the wireguard "client" on the cottage OpenWRT router it looks like it agrees, and that the wg0 device is connected.

What I'm stuck on I can't seem to get traffic from a device connecting to the cottage OpenWRT router to flow over the wireguard connection.

I think there are two key 'config' files - but I'm happy to share more to help investigate this

/etc/config/network

config interface 'wg0'
        option proto 'wireguard'
        option private_key 'SECRET='

config wireguard_wg0 'wgserver'
        option public_key 'SECRET='
        option preshared_key 'SECRET='
        option endpoint_host 'mydomain.com'
        option endpoint_port '51820'
        option route_allowed_ips '1'
        option persistent_keepalive '25'
        list allowed_ips '192.168.0.0/22'

This seems to be the key thing to get wireguard to setup and to connect.

/etc/config/firewall

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

This is simply my moving the 'wg0' device into the lan zone.

Looking at the admin web interface routes https://openwrt.lan/cgi-bin/luci/admin/status/routes

Active IPv4 Routes
Network Target          Gateway           Metric  Table   Protocol
wan     0.0.0.0/0       192.168.10.1       0       main
wg0     192.168.0.0/22     -               0       main
lan     192.168.9.0/24     -               0       main
wan     192.168.10.0/24    -               0       main
wan     26.246.8.195    192.168.10.1       0       main

It may help to know that my hardware setup.

I'm using a KuWifi LTE router. That's configured to be 192.168.10.1
My OpenWRT router uplink port is plugged into the back of the KuWifi. The OpenWRT router is 192.168.9.1.

My home network is running on 192.168.1.1 and 192.168.2.1 - the MQTT server lives at 192.168.1.88

It feels like I'm really close -- but I can't seem to get it quite right.

Put the wg0 network into its own zone (and remove it form the lan zone). This can mirror the lan zone, but turn on masquerading. and enable forwarding from lan > wg and wg > lan.

Your /22 for the wireguard tunnel network is overlapping the home LAN. The wireguard tunnel network only needs one IP at each end, so a /24 is fine.

I would suggest
Wireguard tunnel 192.168.0.0/24
Cottage:
Wireguard tunnel 192.168.0.9 / 24
Allowed IPs from home 192.168.1.0/24 and 192.168.0.1/32
Route allowed IPs should install this route: 192.168.1.0/24 via 192.168.0.1

Home:
Wireguard tunnel 192.168.0.1/24
Allowed IPs from cottage 192.168.9.0/24 and 192.168.0.9/32
This should also install the route to the cottage 192.168.9.0/24 via 192.168.0.9

With symmetric routing like this, you can leave the wireguard tunnel in the LAN zone and do not use masquerade on it.

Note that the WAN networks don't matter other than that on one end you need to allow and or forward the encrypted packets through the WAN.

Hmm. that was intentional - but I have to admit that based on the documentation it wasn't clear to me how I should be configuring things.

Your answer seems to also imply that you're suggesting that I have wireguard in both directions - I don't need that to make what I'm trying to setup work. I'll certainly re-read what you've said here and experiment to see if I can gain a better understanding.

My "home" wireguard is actually in a container. Specifically the one from linuxserver.io https://fleet.linuxserver.io/image?name=linuxserver/wireguard this is working fine and I don't want to mess with it.

My cottage setup will have wireguard, but only configured as a client.

The linuxserver.io container sets up on network 10.13.13.x. Each peer (client) gets an address (10.13.13.2/32 for example).

This doc: https://openwrt.org/docs/guide-user/services/vpn/wireguard/client left me scratching my head a little - since it calls out WG_ADDR to bet setup. I didn't really understand what this was meant to be. Based on your example - I think you're suggesting it could be 192.168.0.9 -- but as I should translate that to the linuxserver.io setup - maybe I call it 10.13.13.2? (I'm really unsure about this in case that isn't obvious)

Both your answer @mk24 and @psherman seems like they are in the same space - you're giving me routing advice.

I do agree that 192.168.0.0/22 overlaps my home network - that's exactly what I was trying to specify - with the list allowed_ips '192.168.0.0/22' -- but clearly I mis-understood what that field was for. I was trying to say: these are the IPs that you should route over the wireguard.

Again if we look at https://openwrt.org/docs/guide-user/services/vpn/wireguard/client - it seems to imply this is the list of IPs to route over the interface? Thus my confusion.

uci add_list network.wgserver.allowed_ips="0.0.0.0/0"

If you look at my config for the interface - I don't specify an IP at all.

config interface 'wg0'
        option proto 'wireguard'
        option private_key 'SECRET='

Maybe this is my key problem. The device has no IP, so it's sort of hard to route data to it.

So it can be a bit confusing... I'll try to help clear up some of that...

@mk24 made a good catch with the subnet overlap. As a general rule, subnets should never overlap or there will be ambiguity and thus routing breaks (in the basic case of 2 identical subnets, you cannot route between them because it is not clear which network is the destination). So that needs to be fixed first. Your LANs on each side should have different subnets, and the wireguard interface should be a 3rd subnet (this one will be sort-of common between the two routers).

Allowed IPs is the other major part here...

To define "allowed IPs" -- these are the IP addresses that are allowed through the tunnel. Some have called it a simplistic firewall, and there is truth to that. How it works in practice needs to be viewed from the lens of a 'server' or 'client' model because of the nature of what you are sending through the tunnel.

Let's first take the example of a road-warrior or commercial VPN client type setup... on the client side of the system, you want to send all addresses through the tunnel -- in other words, you'll set the allowed IPs (on the client side) to 0.0.0.0/0. This represents the entire IPv4 address space, so all traffic will go through the tunnel.

If you are creating a site-to-site configuration, or just trying to access 'local' resources when you are away from that network, you set the client's allowed IPs to a range that is associated with the network you are trying to reach (so if the network of interest is 10.20.30.0/24, the allowed IPs would be exactly that). This means that only destination IPs in the 10.20.30.0/24 network will go through the tunnel.

On the 'server' side, things are a bit different. Here, the allowed IPs are effectively the IP address that the 'client' holds on the WG network. So if you have a wireguard subnet of 172.16.30.0/24, you might have a 'client' that occupies 172.16.30.4/32 (/32 being designator here as it is a network for a single host). This IP address is used in the allowed IPs field for the specific client in question. On the 'client' side, the IP will appear as the WG interface address. What this does is declares that all traffic that is destined for 172.16.30.4 will be allowed through the tunnel to a specific peer, and that is why the peer holds the same IP as its interface address.

I entirely missed that earlier (I was multi-tasking... in that I was not doing any task well... sorry about that!). I honestly have never tried WG without an interface address, so I'm not sure if it will work or not. But best practice is that you always specify this. So, for example:

  • WG 'server' interface address: 172.16.30.1/24
  • WG 'client' address: 172.16.30.4/32
    • this would be specified in the server > peer config > allowed IPs
    • it is also the same as the interface address on the client side, although it is acceptable to use a larger subnet (such as /24) on the 'client' side (this subnet should not exceed the size of the 'server' subnet.

BTW, WireGaurd does not truly distinguish between server and client. They are all just peers. However, from a practical perspective, the 'server' is the one that is listening for an inbound connection, and this will often have peers that have /32 addresses in the allowed IPs. The 'client' side will initiate the connection to the 'server', and the allowed IPs are usually much broader in their definition (maybe one or more /24 networks. maybe even the entire IPv4 address space).

Does this help?

1 Like

Your comments certainly help - but I'm still 'stuck'. I'm moving slowly - but I find that taking small steps and experimenting often leads me to a fuller understanding.

Here's where I'm at now.

/etc/config/network

config interface 'wg0'
	option proto 'wireguard'
	option private_key 'SECRET='
	list addresses '192.168.8.0/24'

config wireguard_wg0 'wgserver'
	option public_key 'SECRET='
	option preshared_key 'SECRET='
	option endpoint_host 'mydomain.com'
	option endpoint_port '51820'
	option route_allowed_ips '1'
	option persistent_keepalive '25'
	list allowed_ips '192.168.0.0/22'

I also moved the wg0 from the 'lan' to the 'wan' - this aligns with I believe the doc https://openwrt.org/docs/guide-user/services/vpn/wireguard/client

If I go look at https://openwrt.lan/cgi-bin/luci/admin/status/routes

Active IPv4 Routes
Network	Target	    Gateway	     Metric	Table	Protocol
wan	0.0.0.0/0	    192.168.10.1	0	main	
wg0	192.168.0.0/22	      -	        0	main	
wg0	192.168.8.0/24	      -	        0	main	
lan	192.168.9.0/24	      -	        0	main	
wan	192.168.10.0/24	      -	        0	main	
wan	24.246.8.196   	192.168.10.1	0	main

The IP 24.246.8.196 is my home system (IP of mydomain.com). I'm thinking this route exists because of the wireguard connection -- and I can see on the other side - that wireguard is connected. This is also reported by OpenWRT that the connection is active.

As configured now - I can connect my laptop to the OpenWRT wireless. It can see the internet just fine (google.com etc). However when I try to ping 192.168.0.1 - it fails.

It feels like I've followed the doc fairly directly. The wireguard tunnel is getting setup and is connected- but I've missed something about getting the actual routing of traffic from this OpenWRT to my home network to happen.

Again - small steps because I'm trying to figure out why this isn't just working like it's documented.

I guess I need to read up more on configuring routes to solve this.

Minor edit..
I can ping 192.168.8.0 - but attempts to ping 192.168.0.1 fail

This is not right, it should be 192.168.8.X/24 where X is not 0 or 255. The first and last IPs in a subnet cannot be assigned to devices.
The two ends of the Wireguard tunnel should hold different and legal 192.168.8 IPs. I like to number them based on the second to the last number of the LAN, but you can't do that with the lan being 192.168.0.0.

Your ping to 192.168.0.1 will originate from 192.168.8.X For this ping to be returned, the other router / wireguard server needs to allow the IP in and route the reply ping back through the tunnel. So on the other end the 192.168.8.X/32, or the whole 192.168.8.0/24 range need to be allowed_ips.

Yes that is the hole punch route in case you were to route the whole Internet via VPN, the encrypted packets would still go to the regular WAN as they must to actually reach the server. I don't know exactly when it is created though, it shouldn't be considered evidence that the tunnel is up. That could be readily proven by setting up legal 192.168.8.0/24 IPs on both ends, making that an allowed range, and having the wireguard tunnel in a zone that allows input. Then you can issue a ping directly to the other end of the tunnel. When pinging your end of the tunnel the response time will be very short, when you ping to the other site you will see it delayed by going through the Internet.

1 Like

*1 to everything @mk24 said.

In addition, I don’t think you should be using a /22 for your wireguard network. In general it is not a problem, but iirc, this causes an overlap with one of the networks on one of the routers. Sticking to a /24 makes things visually simple to understand and avoids accidental overlaps.

I've applied the suggested changes - but it's still not happy.

config interface 'wg0'
	option proto 'wireguard'
	option private_key 'SECRET='
	list addresses '192.168.8.1/24'

config wireguard_wg0 'wgserver'
	option public_key 'SECRET='
	option preshared_key 'SECRET='
	option endpoint_host 'mydomain.com'
	option endpoint_port '51820'
	option route_allowed_ips '1'
	option persistent_keepalive '25'
	list allowed_ips '192.168.0.0/24'

I can see on the 'server' side of this - that I'm getting a wireguard connection from my LTE IP address.

On my server - let me shell into the wireguard container

$ docker run --rm -it --network=container:wireguard ubuntu bash
root@edb19232ab89:/#

Of course the base ubuntu container doesn't have ssh -- so let's do some installs

apt update
apt install openssh-client iputils-ping

and.. it's at this point that I realize that while my wireguard tunnel appears connected - it's not allowing any traffic to flow (or at least ping is failing). If I connect my phone to the same wireguard server.. I can ping the phone..

:person_facepalming: oh..

This got me looking at the peer config in my wireguard. You'll recall that I'm using the linuxserver.io wireguard.

$ cat peer_cottage.conf 
[Interface]
Address = 10.13.13.6
PrivateKey = SECRET=
ListenPort = 51820
DNS = 8.8.8.8

[Peer]
PublicKey = SECRET=
PresharedKey = secret=
Endpoint = mydomain.com:51820
AllowedIPs = 0.0.0.0/0, ::/0

it didn't occur to me (until now) that the peer configuration for the wireguard address had to MATCH the server version - I mean.. they are internal IPs.. but yeah..

This appears to be a working configuration for me

config interface 'wg0'
	option proto 'wireguard'
	option private_key 'SECRET='
	list addresses '10.13.13.6/32'

config wireguard_wg0 'wgserver'
	option public_key 'SECRET='
	option preshared_key 'SECRET='
	option endpoint_host 'mydomain.com'
	option endpoint_port '51820'
	option route_allowed_ips '1'
	option persistent_keepalive '25'
	list allowed_ips '192.168.0.0/24'

My docker trick to connect and ping the from the server to the client isn't working.. but this may be a firewall in the way.. but it should work. I'll dig a bit deeper.

Flagging my own post as the 'solution' - but many thanks to @psherman and @mk24 for comments and advice. I still have a few mysteries to sort out - but the basic function is working like it should.

Key was the make sure both of the wireguards (server/client) were using the same IP.

IE: the peer configuration for [Interface] should match the OpenWRT config interface 'wg0'

I've written this up as a blog post: https://lowtek.ca/roo/2022/openwrt-as-a-wireguard-client/

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