How To Set Up a WireGuard VPN Server on Ubuntu Linux

Sorry for the delayed follow up - I didn’t see a notification you’d responded. So I made those changes you mentioned and that’s where I am now and it hasn’t fixed it. I can confirm that from my cell phone I can ping and wg shows the handshake. I still can’t get to anything beyond the VPN server, though. I’d been given advice to remove the iptables postrouting MASQUERADE lines or static routes so I’d think it was a problem with the responses, but I don’t see any requests from the VPN server at or the VPN 10.x range to the firewall,…

UPDATE - Yep, it was as I suspected. I went back in and put the iptables lines back in and it’s working. I did, FWIW, use the lines from another site but they look pretty similar except yours uses %i instead of the wireguard interface name. I’m not sure if that’s contributing to the issue, but that means this is what I used instead:

PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A FORWARD -i wg0  -j ACCEPT; ip6tables -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; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

Actually, I believe the other guide also included installing wireguard-tools, and also a package, something like resolvconf, that may have been the key as well. Sorry I don’t have that definitively, but I am so glad it works. Thanks for the help!

Glad to hear you got it working! (And thank you even more on taking the time to follow-up so we can hopefully make this easier for others to install).

I have two thoughts on why the config might not have worked for you. If you could answer these questions for me so I can decide if I need to make adjustments to the configuration to help others, I would appreciate it:

  1. What Linux distribution (and version) are you running on your Wireguard server?

The %i is what is known as a “template specifier”; more specifically, the variable %i represents the instance identifier. In our case, in the PostUp/PostDown configuration %i represents the WireGuard interface name, wg0. Since this is systemd, if your Linux distribution doesn’t use systemd, I would not expect this to work.

  1. Are you using IPv6 (either internally in your home network or provided by your ISP)?

The easiest way to test if you’re not sure is to use and let me know what you see there. (Visited with the WireGuard connection enabled).

Additionally, running ifconfig and pulling the line with the inet6 addr would also be extremely helpful. I’m especially interested in the Scope that appears in that line (particularly if it says Scope:Site which indicates an IPv6 routed address.

Since I am currently only using IPv4, and I only post material that I have been able to test myself, my configuration only provides for IPv4 in iptables.

The wireguard-tools package should have been pulled in with the rest when you installed wireguard with sudo apt install wireguard. Since it includes both wg and wg-quick, if you didn’t have it, you would have had a heck of a time starting up Wireguard.

Thanks again for the update, and I hope to hear back from you re: the questions above.


Happy to help! I’d actually started making changes to try to get this to work without the iptables NAT on the VPN sever as I want to be able to use firewall and DNS controls on some VPN hosts (like my kids who will also be always-on VPN). Unfortunately, while I got so far as to be able to ping not only the gateway but Internet addresses like, I can’t get DNS to work that way for some reason - no matter what I do.

In any event, I restored a backup so hopefully I can you some answers. Here we go:

  1. I am running Ubuntu 20.04 on a pi 4 for this.

  2. I’ve tried to disable IPv6 everywhere for now because I haven’t felt comfortable setting up all the rules yet. That site you linked seems to verify IPv6 is not enabled.

That’s weird regarding the tools. I’d also flushed the iptables with iptables -F and rebooted, so maybe I didn’t read the message right and it was just something like that. I’m glad it’s working, but I sure do wish I could finish getting this up without NAT’ting the VPN clients to the VPN server interface

HI, I’m about half-way through the tutorial and have all of the keys generated and the wg0.conf created. The one thing I am a bit lost on is the address you are showing for the {Interface] setting in the conf file.

In the WireGuard config file (wg0.conf), Under the heading of [Interface], you have entered . I would assume that you have entered the IP address for your server’s NIC which is ens18, but you mention in the paragraph just before the Prerequisites section of the article this, “forwards it on to the Ubuntu server, which is connected to the router on ens18 with IP address and also listening on port 51910.” That would make me think your server is at . So, I am wondering what address of mine I need to substitute in for that that you have entered at that point. I am stuck in this WireGuard installation until I can settle that issue.

Is an address you assigned to the Wire Guard server application?

That’s correct. My server’s IP address (on ens18) is

You can leave the number as Any line where you see 10.253.4.X/yy you can leave as is in both your server and client config. There’s no need to change either on a simple install.

The reason is that you’re essentially creating a network device with these commands and, as a result, you get to assign the IP addresses you want those interfaces to use.



Thank you, TorqueWrench! You confirmed what I thought after I re-read the tutorial several more times. I’ve installed the official WireGuard Android Client and will be testing it out. I’ll let you know the results as soon as I can get through all of this. Thanks, again!

1 Like

Using a VM lab I followed this article successfully and I have a windows client VM connected to a ubuntu desktop VPN server VM. Eventually my end goal is ubuntu server/desktop running on a Raspberry Pi 4 and windows/mac clients accessing from outside the home network. And a secondary goal is to have a 2nd raspberry PI 4 set up as a site-to-site VPN and as a wireless access point so that any devices connecting to it as the wireless are automatically connected to my home network.

However, back to my simpler step 1, I don’t know what to do next. On my windows client I do see Rx/Tx values greater than 0 and the activated light is green and on my ubuntu desktop I do see Rx/Tx values greater than 0 with wg show but that’s all I can do. What else do I need to make this VPN tunnel useful?

For example, if my ubuntu server is and my windows client is what do I need so that I can access resources on the home network (which is 192.168.7.x) from my client ( through the tunnel? DNS? How do I configure DNS (and where)? If I have a windows machine on my home network at how can I RDP from my remote windows client across the VPN? (again its on and I don’t know conceptually or installed service wise what I’m missing to make this all work) Or in simpler terms, how do I browse my 192.168.7.x home network when I’m remote and only able to connect via the 10.253.4.x VPN?

In a possibly related observation, from inside my home network I also can’t see my ubuntu server by name, I can only SSH/RDP by IP. Maybe this is part of my problem? – what do I need so that my ubuntu machines/VMs can be found via name like my windows machines can?

Thanks for the help!

1 Like

Hi @mark.d.harris,

Brace yourself for my barrage of questions/comments below! :wink:

That’s great news. If you are receiving data then your WireGuard tunnel is working.

Are you saying that you can’t do anything else? I.e. Can you browse a web page? Are you able to ping other devices on your local network? (Note that if you’re trying to ping a Windows machine, by default they don’t respond to pings/ICMP requests).

You should be able to use Windows RDP as usual. Some of your other statements are making me think that you think you might have a DNS issue in which case instead of using your Windows PC’s hostname, you should be able to do connect by putting in that PC’s IP address into Windows RDP instead.

Just to confirm, are you saying that you can’t access any other devices on your local network when connected to WireGuard? Are you able to ping them? If you aren’t able to ping them by hostname, are you able to at least ping them by IP address?

All of this is sounding like you’re “locked inside” the WireGuard server and your connection can’t leave it since 1) you’ve confirmed that you can connect to the WireGuard server and it’s a real connection by receiving data but 2) can’t seem to access outside resources. If that’s the case, did you enable IP forwarding on your WireGuard server?


Thank you so much for your questions!.. as I studied and investigated each one I realized that the VPN tunnel is actually working just fine. The name resolution does not work and that is why I was confused.

It seems strange to me, but yes, from my remote client (which is on the VPN network at I can RDP to or find a resource on my home network like I wouldn’t have thought that would work like that but I guess that comes from the " iptables -A FORWARD part? (is there 101 level info that explains how that iptables work as well as how to set them for wireguard? I blindly followed the setup for wg0.conf but would like to understand it better.)

So, I think the problem I have is that on the remote client, I cannot resolve names of linux or windows hosts. Even in the simpler case, on a home network where there are both linux and windows machines, how can you get name resolution to work (windows machines can find other windows machines just fine but not linux and linux can’t seem to find anything except by IP)? I know its not a VPN question since the tunnel definitely works when I use IP but I’d like to understand how to get name resolution working too.

Thank you!

1 Like

It’s technically because of the iptables -t nat -A POSTROUTING -o ens18 -j MASQUERADE piece, where ens18 is your network device on the local network.

The combination of Network Address Translation (NAT) and MASQUERADE basically allows us to run all of our traffic from the WireGuard tunnel under the “false flag” of our WireGuard server’s primary network device, ens18. As a result, to other devices on the local network, all of the traffic appears to be coming from your WireGuard server on the local network and not from a device in the WireGuard tunnel itself.

Viewed another way, that configuration allows our WireGuard server to act as a sort-of router, allowing traffic to traverse from one network (the WireGuard tunnel) to another (your local home network).

I’ve been meaning to do such an article. In the meantime, here is a good reference on NAT with Linux and iptables. It might be a little advanced, but it will get you started.

Since this isn’t necessarily specific to WireGuard, to keep everything organized and easier to find, would you mind posting this as a separate discussion in the Networking forum? Thanks!


Trying to access my home network over the VPN from an actually remote (non-test) location turned out to be somewhat disappointing. I am able to get an active client and see data transferring in both directions but the only thing that seems to be reasonably working now is seeing the internet from my home network’s IP while remote. That’s good but I do not seem to be able to actually access my home network resources like I thought I could before. (even by IP which I know from my eero phone app). Plus, I put docker on the same PI and am running a test nginx container and am not even able to see that by attempting to browse to the IP of the PI on port 80 (which definitely worked when local)

I’ve also noticed excessively high latency in what is probably DNS resolution of internet resources through the tunnel. It works eventually but a lot of attempts are timing out more often than being successful.

Does any of these symptoms suggest what I might have misconfigured? Also, do you have suggestions for how to work with multiple VPNs? (work requires a VPN client, now I have a home one, etc. - can they be made to work together? if so how does the traffic flow?)

Thanks for any suggestions!

A quick little side tip:
ipv4 forward can be non-persistently enabled via PostUp as well:

PostUp = sysctl -w net.ipv4.ip_forward=1; iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o ens18 -j MASQUERADE

The PostDown is just =0 instead of =1 for that one :slight_smile:

Saves a little time in the install proccess and some room on your instructions :slight_smile:

Also makes it so ipv4 forward is only enabled when wireguard is actually enabled :slight_smile:

1 Like

Now why didn’t I think of that? :thinking:

Thanks for the suggestion, @ok987! I’ll integrate your suggestion into my own config and hopefully update the guides this weekend.

It sounds like you know your stuff, may I ask what brought you to my site?


Having an issue setting up a second peer. I edited wg0.conf and added

PublicKey = {pub key of second peer}
AllowedIPs =

Save the conf file, but when I reboot, the second peer line is gone.

Thanks for the assistance and great article.

That’s most likely because of the SaveConfig = true directive we have set up in the interface. Per the wireguard man page:

SaveConfig — if set to `true’, the configuration is saved from the current state of the interface upon shutdown. Any changes made to the configuration file before the interface is removed will therefore be overwritten.
Source: wg-quick(8) — wireguard-tools — Debian unstable — Debian Manpages

Simplest solution? Make the config changes before bringing WireGuard up, or take wg down temporarily, make your changes, and then either bring wg back up or reboot.

Thanks for the question and let me know if that doesn’t work for you,

That did it! Thank you very much - both peers are connecting and working!

1 Like

I want to set up a wireguard tunnel from my Ubuntu 20.04 laptop to my Ubuntu 20.04 desktop connected to Comcast cable modem and TP-link router. I have no-ip domain names to account for changes in desktop IP address. I would like to use wifi hotspots at hotels, coffee shops, etc to connect to my desktop securely to read and write emails, run searches, etc. I have tried to follow your detailed guide, but cannot ping my laptop from the desktop or vice versa. I will be happy to shave my wg0.conf files (minus the keys), what else do you need to help me?

Hi Ken,

In addition to your WireGuard conf files (minus the keys; also please double-check the keys; the client vs server vs private vs public keys can get easily mixed up):

  1. From behind your network, check your IP address on one of those “What is my IP address?” sites. Compare it to the IP address given by your router. Are they the same? (Trying to rule out that you’re not stuck behind a CGNAT, which is more or less a show-stopper.)

  2. Are you testing from your home network? If so we might be running into a NAT reflection/“hairpinning” issue. Here are some quick troubleshooting steps you can take to figure that out:


Here are my cleaned up server wg0.conf and wg0-laptop.conf. I have double checked that the server and laptop public and private keys on the actual files are correct. I have a spare RPI and could set up an RPI server with the wg0.conf instead of using my desktop. enp37s0 is my desktop wired interface.

Address =
SaveConfig = true
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o enp37s0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o enp37s0 -j MASQUERADE
ListenPort = 51820
PrivateKey = server_private_key

PublicKey = laptop_public_key
AllowedIPs =

Address =
PrivateKey = laptop_private_key

PublicKey = server_public_key
Endpoint =
AllowedIPs - ::0

Would it be possible to create multiple wireguard interfaces that are in turn supporting respective VLAN interfaces?

I’m asking because I want to place different wireguard clients into different VLANs. Imagine you have multiple Peers in your wg0.conf file. There is no way to send them to different networks.

So, what if we had a wg10, wg20 for each VLAN. Naturally, each used a different interface. This way, with the Rasperberry Pi connected to a VLAN switch, the wireguard clients get the VLAN network they should.

Thoughts? I realize I could run multiple Rasberry Pi’s each plugged into different switch Access ports, but that’s silly!