Wireguard Client Router Setup Help

I am attempting to set up an Ubuntu server wireguard VPN client router via a VM under ESXi in my homelab to better understand how this works; eventual deployment would be on my raspberry pi to allow devices connected to said pi to be routed through the VPN; basically a portable router that forces every device connected to it to be routed back to my server (also lives on my homelab) used when I travel for work. For current testing, I have a Ubuntu server VM set up at a family members house so I can have an alternate public IP to verify things work as expected.

Test setup:
Local LAN - 192.168.1.1
WG Server - 10.0.0.1
Virtual LAN for testing within my homelab - 10.0.0.2
Remote LAN 192.168.86.1
WG Server on an Ubuntu Server VM
WG Client on an Ubuntu Server VM

I have a wireguard connection set up, handshakes, public IP shows correct on my WG Client

Current server setup is:

[Interface] 
PrivateKey=<server-private-key> 
Address=<10.0.0.1>/<8> 
SaveConfig=true 
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o <eth0> -j MASQUERADE; 
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o <eth1> -j MASQUERADE; 
ListenPort =51820

Current client setup is:


[Interface] 
PrivateKey = <client-private-key> 
Address = <client-ip-address>/<subnet> 
SaveConfig = true 

[Peer] 
PublicKey = <server-public-key> 
Endpoint = <server-public-ip-address>:51820
AllowedIPs = 0.0.0.0/0

Once I have wireguard set up and working - which I do believe it is, its pretty easy to set up based on the above, I moved onto setup of my secondary interface which will be 10.0.0.2 and will receive DHCP and use the router I set up within the WG Client VM. I set this up via a rather simple guide (can’t link to it apparently, so, just have to assume setting up a router is easy enough).

With this second interface working, I spin up an ubuntu desktop VM on my homelab connected to the same virtual network as the WG Client second interface is connected to, DHCP works as expected, and I am even able to get iffy internet on the ubuntu desktop VM. I can google things, I can watch youtube, but things just don’t quite work right, I can’t download and install chrome for example, it tries, it hangs, it tries some more, but just doesn’t really work. Speed tests do run very near line speed though…

I assume packets are not being routed through to the wireguard interface correctly, or something somewhere is not being translated. I though the "allowwedIP’s being 0.0.0.0/0 would mean all traffic through the WG Client would be forced over the WG interface, but that is proving not to really work. I have tried some random iptables settings as well, but nothing really changes anything. I have seen the fact wireguard works with namespaces, but I am not quite sure how that works or how I would set that up for my needs. I know enough to know enough, but clearly not enough to get this working as intended.

Any ideas, or guides that could be followed for this exact situation? I have been at this for a couple days now and just can’t get my head around it.

Watching with interest, I’m looking to do the same sort of thing as one of our SDWAN vendors (Riverbed) basically EOL’d their Steelconnect range and the new “steel connect” product is basically rip/tear/reimplement with no co-existence between the old/new platform.

AllowedIPs has nothing to do with routing. It’s just additional filtering. You still need to setup routes.

You’ll probably also need to enable NAT / masquerade on the server side if you want the internet to reply to it, and it to forward stuff back to you.

To dumb things down sufficiently…

Lets say I have

  • a point to point tunnel over the internet between host A and host B using Wireguard
  • host A and host B having networks for site A and site B behind them on their LAN side
  • a host route for say network at site A pointing towards site B’s Wireguard IP and
  • a host route for network at site B pointing at site A’s Wireguard IP

… will Wireguard route that traffic over the encrypted tunnel (this would be my expected behaviour)?

I’m looking to test this when I get some free time but if someone can confirm yes it works that way it should be pretty straightforward to set up :smiley:

IPSec tunnel mode needs crypto map definitions and other associated stuff or the traffic won’t be crypto-routed… if Wireguard is more straightforward its a big win…

The documentation for Wireguard is exceedingly simple until it goes off into a tangent on network namespaces and stuff, and I’m not interested in containers, etc. I just want traffic from subnet A to subnet B through a tunnel. And I’m not sure if I’m missing something or if it is as simple as I hope it is :smiley:

Yes. You’ll get an interface in each end, and regular Linux routing works over it. Allowed IP is just an extra filter for incoming traffic if you wanted to prevent people taking random private/endpoint IPs that their private/public key is not associated with. If you trust both ends of the tunnel you could stick 0/0 in there on both sides.


You don’t need to care about network namespaces or containers, ignore all of that if you want… Wireguard just gets you a network interface that encapsulates IP into encrypted UDP efficiently.

1 Like

Based on a response from another forum, it appears as though my server and client interfaces being 10.0.0.1/8 and 10.0.0.2/8 respectively may be an issue. I believe I should be using /24 in order to differentiate them routing wise (sorry, my terminology is likely poor, I’m new to networking and have 0 actual background in it).

Would this possibly make sense as to why things only seemingly sorta work? I’ll be able to test it out in a few hours after work, just trying to better understand.

Oh shoot. I have my client config not really defined, and I have a typo in my iptables portion…

This is a corrected copy paste. Sorry about that!

Current server setup is:

[Interface]
PrivateKey=
Address=10.0.0.1/8
SaveConfig=true
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE;
ListenPort =51820

Current client setup is:
[Interface]
Address = 10.0.0.2/8
SaveConfig = true
ListenPort = xxxxx
PrivateKey = xxxxxxxxxxx

[Peer]
PublicKey = xxxxxxxxxxxxxx
AllowedIPs = 0.0.0.0/0
Endpoint = <server’s IP>
PersistentKeepalive = 30

It’s possible. There’s rules for picking routing table entries based on destination ip and netmask length, and route metric and so on… If you have another 10… route then maybe a /8 is not specific enough for two endpoints to be able to talk to each other.

Try setting one side of Wireguard to 172.16.156.65/30 and the other to 172.16.156.66/30 . (They’re relatively unique IPs on the same subnet I just made up)


You’re missing a server side Peer section with the clients public key ? (that’s what you were saying as well?)

No, sorry. On my phone making really bad edits.

My OP had mistakes in my .conf files I copied over. I didn’t have the client side address specified (10.0.0.2/8) and had a few other typos, all of which are important and may explain my issues. I posted them in the post prior to yours just to add that info. I’ll edit the OP later on a pc as that is easier.

I will edit my addresses to be /24 and retain the 10.0.0.1 and 10.0.0.2, and if that doesn’t help I will try your IP suggestions as well.

The rest of the config files should be fine, I think. The server and client so handshake, so adding the peer to the server worked as expected (there is a simple command to add piers, I don’t know it off hand but it doesn’t go directly into the .conf).

Thanks for confirming! I figured that was the case, and the documentation really needs to be more clear.

i.e., they need to split the containerisation stuff off clearly into its own section, and have a dummies tunnel guide or something imho.

I’ll lab it up and write up a guide when I get some free time I think, will need to document it for work purposes anyway.

So going to be doing some work with this over the next couple of days hopefully. Looking to also include a routing protocol if I can so that bringing up a subnet on one end will add the routing to the other end…

1 Like

That would be absolutely amazing.

I have edited my settings as such, and this didn’t help my issues at all.

Server settings:

[Interface]
Address = 10.66.66.1/24
Address = fd42:42:42::1/64
SaveConfig = true
PostUp = iptables -t nat -A POSTROUTING -o ens33 -j MASQUERADE; ip6tables -t nat -A POSTROUTING -o ens33 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o ens33 -j MASQUERADE; ip6tables -t nat -D POSTROUTING -o ens33 -j MASQUERADE
ListenPort = <port>
PrivateKey = <privatekey>

[Peer]
PublicKey = <pubkey>
AllowedIPs = 10.66.66.2/32, fd42:42:42::2/128
Endpoint = xxxxxxx

Client settings:

[Interface]
Address = 10.66.66.2/24
Address = fd42:42:42::2/64
SaveConfig = true
ListenPort = <port>
PrivateKey = <privatekey>

[Peer]
PublicKey = <pubkey>
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = <IP>:<port>
PersistentKeepalive = 30

my dhcpd.conf for the router I have set up on the wg client is:

option domain-name-servers 8.8.8.8, 8.8.4.4;

default-lease-time 600;
max-lease-time 7200;

ddns-update-style none;
authoritative;
log-facility local7;
subnet 192.168.1.0 netmask 255.255.255.0 {
     range 192.168.1.101 192.168.1.200;
     option subnet-mask 255.255.255.0;
     option routers 192.168.1.1;
}

and my 00-insatller-config.yaml is:

# This is the network config written by 'subiquity'
network:
  ethernets:
    ens160:
      dhcp4: true
    ens192:
       addresses:
       - 192.168.1.1/24
       dhcp4: false
       nameservers:
           addresses:
           - 8.8.8.8
           - 8.8.4.4
  version: 2

with a

sudo iptables -t nat -A POSTROUTING -o ens160 -j MASQUERADE

to nat the router I have created. (should this be 192? The guide I found has this as 160… hopefully thats correct?)

DHCP is working correctly, my ubuntu desktop VM gets 192.168.1.101 as expected, default route is 192.168.1.1, DNS is 8.8.8.8 and 8.8.4.4.

But things just don’t work right still. I can get to the internet, but things are incredibly sluggish and non-responsive, and things just feel broken. I can’t download chrome via firefox for example, it tries, hangs, tries, hangs a lot more. General website loading is incredibly slow and lagy, I am really not sure what is going on. I assume I am not correctly sending traffic from the router through the tunnel… Any ideas?

Looks like my routing may for some reason be wrong? Im thinking when I run wg-quick up wg0 I should be getting the wg0 interface as the default route, no? I am not totally sure, but I have a feeling this route -n result is part of my issue.

Thoughts?

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.21.1    0.0.0.0         UG    100    0        0 ens160
10.66.66.0      0.0.0.0         255.255.255.0   U     0      0        0 wg0
192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 ens192
192.168.21.0    0.0.0.0         255.255.255.0   U     0      0        0 ens160
192.168.21.1    0.0.0.0         255.255.255.255 UH    100    0        0 ens160

In this setup, 192.168.21.1 is my normal LAN side.

yes, your default route is not set to go via 10.66.66.1 as you expect, but is set to use 192.168.21.1 instead.

If you change/override default route to 10.66.66.1 instead, … but then the UDP packets carrying wireguard traffic will not be able to find their way, so you need at least 2 new routes.

You’ll need two new routes:

  1. Add a route for your wireguard endpoint ip, to go via 192.168.21.1, and
  2. Add a default route for everything else to go via 10.66.66.1

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

That makes sense, I will try that later tonight after work. But I guess I am a bit confused as to why that wasn’t automatically configured when I bring up the wg0 interface via wg-quick up?

Maybe somewhere along the lines of my testing I borked something up…

I will give it a try with setting the routes manually, then I will likely spin up a new clean VM and see if maybe there was something along the way I changed incorrectly.

I am a bit confused on how to go about this. Based on the documentation, it seems like wg-quick up should be setting the default route for the wg0 interface:

" It infers all routes from the list of peers’ allowed IPs, and automatically adds them to the system routing table. If one of those routes is the default route (0.0.0.0/0 or ::/0), then it uses ip-rule (8) to handle overriding of the default gateway."

Does that mean this is seemingly not working correctly?

Also, for your 1. adding a route for wireguard endpoint IP to go via 192.168.21.1, that would mean the endpoint IP would be hard set. Since I am “tunneling” to my own house I use a dynamic dns service, how would I add a DNS address as a rule?

@thro maybe you would have some insight as well?

Thanks guys!

So, I’ve got two VMs talking wireguard to each other.

I’ve tested I can route over it by bringing up a loopback IP on both hosts and adding a host route to the other machine for it.

I’ve scripted it a bit using a config file and a script (attached).

There’s some key info in there, but I don’t care these are non-internet connected lab machines.

wireguard.zip (3.2 KB)

Assumes you have done your own key generation, pasting the remote machines public key into the config file and that your local private key is wg-privatekey in the same directory as the script. Edit as appropriate.

Essentially copy the config file and script to each machine, edit the config file as appropriate.

Add routing as appropriate.
There’s a little cruft in there I’m not making use of yet, and this assumes your firewall is either open or permits the port 57090 on both ends.

My next step is to look into adding something like OSPF/RIP/etc. via bird or some other routing daemon.

edit:
Aware there’s a config file for wireguard, but I guess I like to put my own variables in whilst figuring out the command line for it :smiley:

1 Like

I’ll have to take a look later at the config file, hopefully this helps me get to my end goal!

The “config” file I’ve written isn’t a Wireguard format config file, but just a shell script with a bunch of variables in it I use to play with the command line.

I’ve tried to name the variables descriptive things, you could certainly pull those items into a proper Wireguard config file if you like :slight_smile:

I was doing this on a new (to me) l linux distribution (SuSE Openleap, so far I like) and wasn’t sure where it was going to look for the config etc so I just made my own script to test with.

Ah. Ok. I had minor surgery today so I decided I’ll give this a look tomorrow sometime… took it easy today, and decided pulling my hair out with WireGuard wasn’t today’s problem.

I just need to get my routing working (I hope that’s all I need), hopefully something in there would be helpful for me, or point me in the right direction.