Set Up Your Own WireGuard VPN Server on Ubuntu

This tutorial is going to show you how to set up your own WireGuard VPN server on Ubuntu. WireGuard is made specifically for the Linux kernel. It runs inside the Linux kernel and allows you to create fast, modern, and secure VPN tunnel.

Features of WireGuard VPN

  • Lightweight and super fast speed, blowing OpenVPN out of the water.
  • Cross-platform. WireGuard can run on Linux, BSD, macOS, Windows, Android, iOS, and OpenWRT.
  • User authentication is done by exchanging public keys, similar to SSH keys.
  • It assigns static tunnel IP addresses to VPN clients. Some folks may not like it, but it can be useful in some cases.
  • Mobile devices can switch between Wi-Fi and mobile network seamlessly without dropping any connectivity.
  • It aims to replace OpenVPN and IPSec in most use cases.

Prerequisites

This tutorial assumes that the VPN server and VPN client are both running Ubuntu operating system.

Step 1: Install WireGuard on Ubuntu Server and Desktop

Log into your Ubuntu server, then run the following commands to install WireGuard.

Ubuntu 20.04

Ubuntu 20.04 ships with Linux kernel 5.4, which has a built-in wireguard module.

sudo apt update
sudo apt install wireguard wireguard-tools

Ubuntu 18.04

Ubuntu 18.04 ships with Linux kernel 4.15, so users needs to install the hardware-enablement kernel first (HWE), which will install kernel 5.4 on your system.

sudo apt update
sudo apt install linux-generic-hwe-18.04-edge

Restart your Ubuntu 18.04 server and install WireGuard.

sudo shutdown -r now
sudo apt install wireguard wireguard-tools wireguard-dkms

Then use the same commands to install WireGuard on your local Ubuntu computer (the VPN client). Note that you also need to install the openresolv package on the client to configure DNS server.

sudo apt install openresolv

Step 2: Generate Public/Private Keypair

Server

Run the following command on the Ubuntu server to create a public/private key pair, which will be saved under /etc/wireguard/ directory.

wg genkey | sudo tee /etc/wireguard/server_private.key | wg pubkey | sudo tee /etc/wireguard/server_public.key

wireguard VPN server generate public private key

Client

Run the following command to create a public/private key pair on the local Ubuntu computer (the VPN client).

wg genkey | sudo tee /etc/wireguard/client_private.key | wg pubkey | sudo tee /etc/wireguard/client_public.key

Step 3: Create WireGuard Configuration File

Server

Use a command-line text editor like Nano to create a WireGuard configuration file on the Ubuntu server. wg0 will be the network interface name.

sudo nano /etc/wireguard/wg0.conf

Copy the following text and paste it to your configuration file. You need to use your own server private key and client public key.

[Interface]
Address = 10.10.10.1/24
SaveConfig = true
PrivateKey = UIFH+XXjJ0g0uAZJ6vPqsbb/o68SYVQdmYJpy/FlGFA=
ListenPort = 51820

[Peer]
PublicKey = 75VNV7HqFh+3QIT5OHZkcjWfbjx8tc6Ck62gZJT/KRA=
AllowedIPs = 10.10.10.2/32

ubuntu wireguard VPN server configuration file

Where:

  • Address: Specify the private IP address of the VPN server. Here I’m using the 10.10.10.0/24 network range, so it won’t conflict with your home network range. (Most home routers use 192.168.0.0/24 or 192.168.1.0/24). 10.10.10.1 is the private IP address for the VPN server.
  • SaveConfig: the configuration should be saved on shutdown using the current status of the interface.
  • PrivateKey: The private key of VPN server, which can be found in the /etc/wireguard/server_private.key file on the server.
  • ListenPort: WireGuard VPN server will be listening on UDP port 51820, which is the default.
  • PublicKey: The public key of VPN client, which can be found in the /etc/wireguard/client_public.key file on the client computer.
  • AllowedIPs: IP addresses the VPN client is allowed to use. In this example, the client can only use the 10.10.10.2 IP address inside the VPN tunnel.

Save and close the file. (To save a file in Nano text editor, press Ctrl+O, then press Enter to confirm. Press Ctrl+X to exit.)

Change the file permission mode so that only root user can read the files.

sudo chmod 600 /etc/wireguard/ -R

Client

Use a command-line text editor like Nano to create a WireGuard configuration file on your local Ubuntu computer. wg-client0 will be the network interface name.

sudo nano /etc/wireguard/wg-client0.conf

Copy the following text and paste it to your configuration file. You need to use your own client private key and server public key.

[Interface]
Address = 10.10.10.2/24
DNS = 10.10.10.1
PrivateKey = cOFA+x5UvHF+a3xJ6enLatG+DoE3I5PhMgKrMKkUyXI=

[Peer]
PublicKey = RaoAdsIEIwgV9DHNSubxWVG+nZ1GP/c3OU6A/efBJ0I=
AllowedIPs = 0.0.0.0/0
Endpoint = 12.34.56.78:51820
PersistentKeepalive = 25

Where:

  • Address: Specify the private IP address of the VPN client.
  • DNS: specify 10.10.10.1 (VPN server) as the DNS server. It will be configured via the resolvconf command.
  • PrivateKey: The client’s private key, which can be found in the /etc/wireguard/client_private.key file on the client computer.
  • PublicKey: The server’s public key, which can be found in the /etc/wireguard/server_public.key file on the server.
  • AllowedIPs: 0.0.0.0/0 represents the whole Internet, which means all traffic to the Internet should be routed via the VPN.
  • Endpoint: The public IP address and port number of VPN server. Replace 12.34.56.78 with your server’s real public IP address.
  • PersistentKeepalive: Send an authenticated empty packet to the peer every 25 seconds to keep the connection alive. If PersistentKeepalive isn’t enabled, the VPN server might not be able to ping the VPN client.

Save and close the file.

Change the file mode so that only root user can read the files.

sudo chmod 600 /etc/wireguard/ -R

Step 4: Enable IP Forwarding on the Server

In order for the VPN server to route packets between VPN clients and the Internet, we need to enable IP forwarding. Edit sysctl.conf file.

sudo nano /etc/sysctl.conf

Add the following line at the end of this file.

net.ipv4.ip_forward = 1

Save and close the file. Then apply the changes with the below command. The -p option will load sysctl settings from /etc/sysctl.conf file. This command will preserve our changes across system reboots.

sudo sysctl -p

Step 5: Configure IP Masquerading on the Server

We need to set up IP masquerading in the server firewall, so that the server becomes a virtual router for VPN clients. I will use UFW, which is a front end to the iptables firewall. Install UFW on Ubuntu with:

sudo apt install ufw

First, you need to allow SSH traffic.

sudo ufw allow 22/tcp

Next, find the name of your server’s main network interface.

ip addr

As you can see, it’s named ens3 on my Ubuntu server.

ubuntu wireguard firewall

To configure IP masquerading, we have to add iptables command in a UFW configuration file.

sudo nano /etc/ufw/before.rules

By default, there are some rules for the filter table. Add the following lines at the end of this file. Replace ens3 with your own network interface name.

# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o ens3 -j MASQUERADE

# End each table with the 'COMMIT' line or these rules won't be processed
COMMIT

In Nano text editor, you can go to the end of the file by pressing Ctrl+W, then pressing Ctrl+V.

UFW NAT table POSTROUTING MASQUERADE

The above lines will append (-A) a rule to the end of of POSTROUTING chain of nat table. It will link your virtual private network with the Internet. And also hide your network from the outside world. So the Internet can only see your VPN server’s IP, but can’t see your VPN client’s IP, just like your home router hides your private home network.

By default, UFW forbids packet forwarding. We can allow forwarding for our private network. Find the ufw-before-forward chain in this file and add the following 3 lines, which will accept packet forwarding if the source IP or destination IP is in the 10.10.10.0/24 range.

# allow forwarding for trusted network
-A ufw-before-forward -s 10.10.10.0/24 -j ACCEPT
-A ufw-before-forward -d 10.10.10.0/24 -j ACCEPT

ufw allow packet fowarding

Save and close the file. Then enable UFW.

sudo ufw enable

If you have enabled UFW before, then you can use systemctl to restart UFW.

sudo systemctl restart ufw

Now if you list the rules in the POSTROUTING chain of the NAT table by using the following command:

sudo iptables -t nat -L POSTROUTING

You can see the Masquerade rule.

wireguard-IP-Masquerading-ufw-ubuntu

Step 6: Install a DNS Resolver on the Server

Since we specify the VPN server as the DNS server for client, we need to run a DNS resolver on the VPN server. We can install the bind9 DNS server.

sudo apt install bind9

Once it’s installed, BIND will automatically start. You can check its status with:

systemctl status bind9

Sample output:

 named.service - BIND Domain Name Server
     Loaded: loaded (/lib/systemd/system/named.service; enabled; vendor preset: enabled)
     Active: active (running) since Sun 2020-05-17 08:11:26 UTC; 37s ago
       Docs: man:named(8)
   Main PID: 13820 (named)
      Tasks: 5 (limit: 1074)
     Memory: 14.3M
     CGroup: /system.slice/named.service
             └─13820 /usr/sbin/named -f -u bind

If it’s not running, start it with:

sudo systemctl start bind9

Edit the BIND DNS server’s configuration file.

sudo nano /etc/bind/named.conf.options

Add the following line to allow VPN clients to send recursive DNS queries.

allow-recursion { 127.0.0.1; 10.10.10.0/24; };

wireguard BIND DNS resolver

Save and close the file. Restart BIND9 for the changes to take effect.

sudo systemctl restart bind9

Then you need to run the following command to allow VPN clients to connect to port 53.

sudo ufw insert 1 allow in from 10.10.10.0/24

Step 7: Open WireGuard Port in Firewall

Run the following command to open UDP port 51820 on the server.

sudo ufw allow 51820/udp

Step 8: Start WireGuard

server

Run the following command on the server to start WireGuard.

sudo wg-quick up /etc/wireguard/wg0.conf

To stop it, run

sudo wg-quick down /etc/wireguard/wg0.conf

You can also use systemd service to start WireGuard.

sudo systemctl start wg-quick@wg0.service

Enable auto-start at system boot time.

sudo systemctl enable wg-quick@wg0.service

Check its status with the following command. Its status should be active (exited).

systemctl status wg-quick@wg0.service

Now WireGuard server is ready to accept client connections.

Client

Start WireGuard.

sudo systemctl start wg-quick@wg-client0.service

Enable auto-start at system boot time.

sudo systemctl enable wg-quick@wg-client0.service

Check its status:

systemctl status wg-quick@wg-client0.service

Now go to this website: http://icanhazip.com/ to check your public IP address. If everything went well, it should display your VPN server’s public IP address instead of your client computer’s public IP address.

Policy Routing

By default, all traffic on the VPN client will be routed through the VPN server. Sometimes you may want to route only a specific type of traffic, based on the transport layer protocol and the destination port. This is known as policy routing.

Policy routing is configured on the client computer, and we need to stop the VPN connection first.

sudo systemctl stop wg-quick@wg-client0.service

Then edit the client configuration file.

sudo nano /etc/wireguard/wg-client0.conf

For example, if you add the following 3 lines in the [interface] section, then WireGuard will create a routing table named “1234” and add the ip rule into the routing table. In this example, traffic will be routed through VPN server only when TCP is used as the transport layer protocol and the destination port is 25, i.e, when the client computer sends emails.

Table = 1234
PostUp = ip rule add ipproto tcp dport 25 table 1234
PreDown = ip rule delete ipproto tcp dport 25 table 1234

wireguard-vpn-policy-routing-ubuntu

Note: The client should be running Ubuntu 20.04 or up in order to configure policy routing. The ip utility on Ubuntu 18.04 doesn’t support the ipproto and dport argument.

Save and close the file. Then start the WireGuard client.

sudo systemctl start wg-quick@wg-client0.service

VPN Kill Switch

By default, your computer can access the Internet via the normal gateway when the VPN connection is disrupted. You may want to enable the kill switch feature, which prevents the flow of unencrypted packets through non-WireGuard interfaces.

Stop the WireGuard client process.

sudo systemctl stop wg-quick@wg-client0.service

Edit the client configuration file.

sudo nano /etc/wireguard/wg-client0.conf

Add the following two lines in the [interface] section.

PostUp = iptables -I OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
PreDown = iptables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT

Like this:

[Interface]
Address = 10.10.10.2/24
DNS = 10.10.10.1
PrivateKey = cOFA+x5UvHF+a3xJ6enLatG+DoE3I5PhMgKrMKkUyXI=
PostUp = iptables -I OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
PreDown = iptables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT

[Peer]
PublicKey = RaoAdsIEIwgV9DHNSubxWVG+nZ1GP/c3OU6A/efBJ0I=
AllowedIPs = 0.0.0.0/0
Endpoint = 12.34.56.78:51820
PersistentKeepalive = 25

Save and close the file. Then start the WireGuard client.

sudo systemctl start wg-quick@wg-client0.service

Wrapping Up

That’s it! I hope this tutorial helped you install and configure WireGuard on Ubuntu. As always, if you found this post useful, then subscribe to our free newsletter to get more tips and tricks 🙂

Rate this tutorial
[Total: 8 Average: 5]

39 Responses to “Set Up Your Own WireGuard VPN Server on Ubuntu

  • What if the server uses a dynamic public IP? I would like to build this in my home server but don’t have a static public IP from my isp.

    • You need a domain name and a dynamic DNS service (such as no-ip.com) to translate the domain name into an IP address. Then in the client configuration file, use your domain name instead of an IP address.

      Endpoint = example.com:51820

      You also need to configure port forwarding (UDP 51820) in your router.

  • Ken Wright
    5 months ago

    I’m having a problem with the WireGuard client. When I try to restart it after setting up the VPN Kill Switch, I get an error message. Systemctl status wg-quick@wg-client0.service tells me there’s a bad integer value for option “–mark”. Is there something I’ve missed?

    • Comment out the PostUp and PreDown lines in the client configuration file. Then stop the WireGuard client process.

      sudo systemctl stop wg-quick@wg-client0.service

      Edit the client configuration file.

      sudo nano /etc/wireguard/wg-client0.conf

      Uncomment the PostUp and PreDown lines. Save and close the file. Then start the WireGuard client.

      sudo systemctl start wg-quick@wg-client0.service
  • Ken Wright
    5 months ago

    Umm, which PostUp and PreDown lines? There are two each. Here’s the file:

    PostUp = iptables -I OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
    PreDown = iptables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
    PostUp = ip rule add ipproto tcp dport 25 table 1234
    PreDown = ip rule delete ipproto tcp dport 25 table 1234

    Am I trying to do too much?

    • Yes, I don’t think policy routing and VPN kill switch should be used together. With policy routing, there is traffic that will need to use the usual Internet connection. However, VPN kill switch is meant to stop the flow of the normal Internet traffic.

      • Ken Wright
        5 months ago

        Okay, I deleted the Policy Routing lines and restarted Wireguard Client unsuccessfully. Here’s the output:

        ● wg-quick@wg-client0.service - WireGuard via wg-quick(8) for wg/client0
             Loaded: loaded (/lib/systemd/system/wg-quick@.service; enabled; vendor preset: enabled)
             Active: failed (Result: exit-code) since Fri 2020-05-22 13:33:05 EDT; 3min 46s ago
               Docs: man:wg-quick(8)
                     man:wg(8)
                     https://www.wireguard.com/
                     https://www.wireguard.com/quickstart/
                     https://git.zx2c4.com/wireguard-tools/about/src/man/wg-quick.8
                     https://git.zx2c4.com/wireguard-tools/about/src/man/wg.8
            Process: 24409 ExecStart=/usr/bin/wg-quick up wg-client0 (code=exited, status=2)
           Main PID: 24409 (code=exited, status=2)
        
        May 22 13:33:05 Inspiron-3542 wg-quick[24455]: [#] resolvconf -a wg-client0 -m 0 -x
        May 22 13:33:05 Inspiron-3542 wg-quick[24409]: [#] ip -4 route add 0.0.0.0/0 dev wg-client0 table 1234
        May 22 13:33:05 Inspiron-3542 wg-quick[24409]: [#] iptables -I OUTPUT ! -o wg-client0 -m mark ! --mark $(wg show wg-client0 fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
        May 22 13:33:05 Inspiron-3542 wg-quick[24527]: iptables v1.8.4 (legacy): mark: bad integer value for option "--mark", or out of range.
        May 22 13:33:05 Inspiron-3542 wg-quick[24527]: Try `iptables -h' or 'iptables --help' for more information.
        May 22 13:33:05 Inspiron-3542 wg-quick[24409]: [#] resolvconf -d wg-client0 -f
        May 22 13:33:05 Inspiron-3542 wg-quick[24409]: [#] ip link delete dev wg-client0
        May 22 13:33:05 Inspiron-3542 systemd[1]: wg-quick@wg-client0.service: Main process exited, code=exited, status=2/INVALIDARGUMENT
        May 22 13:33:05 Inspiron-3542 systemd[1]: wg-quick@wg-client0.service: Failed with result 'exit-code'.
        May 22 13:33:05 Inspiron-3542 systemd[1]: Failed to start WireGuard via wg-quick(8) for wg/client0.

        I wonder about the “bad integer value” that I see. I’ve obviously done something terribly wrong. What can I do to help figure this out?

    • What’s your output of sudo wg show wg-client0 fwmark? Mine is off

      • Ken Wright
        5 months ago

        I get

        Unable to access interface: No such device

        I must’ve missed something in the article, but I can’t tell what.

  • Arc System
    5 months ago

    Many thanks for useful tutorials!
    I just configured Wireguard server/client, but on the client I only can communicate to the server and cannot use/browse the internet as usual. I added the ‘Policy Routing’ to the client but I cannot start Wireguard.
    Error:

    May 22 12:28:15 client01 wg-quick[13658]: [#] ip -4 route add 0.0.0.0/0 dev wg-client0 table 1234
    May 22 12:28:15 client01 wg-quick[13658]: [#] ip rule add ipproto tcp dport 25 table 1234
    May 22 12:28:15 client01 wg-quick[13658]: Error: argument "ipproto" is wrong: Failed to parse rule type
    May 22 12:28:15 client01 wg-quick[13658]: [#] resolvconf -d wg-client0 -f
    May 22 12:28:15 client01 wg-quick[13658]: Too few arguments.
    May 22 12:28:15 client01 wg-quick[13658]: Too few arguments.
    May 22 12:28:15 client01 wg-quick[13658]: [#] ip link delete dev wg-client0
    May 22 12:28:15 client01 systemd[1]: wg-quick@wg-client0.service: Main process exited, code=exited, status=255/n/a
    May 22 12:28:15 client01 systemd[1]: wg-quick@wg-client0.service: Failed with result 'exit-code'.
    May 22 12:28:15 client01 systemd[1]: Failed to start WireGuard via wg-quick(8) for wg/client0.
    
    • Is the client running Ubuntu 18.04? I just found that the ip utility on Ubuntu 18.04 doesn’t support the ipproto argument.

      On Ubuntu 20.04, I can find the ipproto argument when checking the man page: man ip-rule. It can’t be found on Ubuntu 18.04.

      • Arc System
        5 months ago

        Yes I’m using Ubuntu 18.04. I don’t think I need Policy Routing now, I just gave it a try.
        But I was able to completely install Wireguard and now I’m using it.
        Thank you for the very comprehensive tutorial!

  • I followed your instruction, but on my ubuntu server, 18.04, shows
    ● wg-quick@wg0.service – WireGuard via wg-quick(8) for wg0
    Loaded: loaded (/lib/systemd/system/wg-quick@.service; disabled; vendor preset: enabled)
    Active: inactive (dead)
    Docs: man:wg-quick(8)

    So, but the wg0.con shows
    Endpoint = :22935

    from my client, ip address, 192.168.0.18, and try to ping server, 192.168.0.16, and it is not working.

    my client network -rn shows

    Destination Gateway Genmask Flags MSS Window irtt Iface
    0.0.0.0 192.168.2.1 0.0.0.0 UG 0 0 0 eth0
    169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
    192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 wg-client0
    192.168.2.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0

    show the 192.168.0.0 gateway should be 192.168.0.1 or 16(server)

    Thanks

  • From my client ip, 192.168.0.17, I should be able to ping or telnet into server ip, 192.168.0.16, Right? But I cannot

  • My bad, use the same ip as my internal lan, rather a separated tunnel.

  • Darth Nagar
    5 months ago

    Hi Xiao Guoan,

    Great turorial, precise, clear and easy to follow.

    I still have a couple of questions:
    1- about DNS: is there a way, in WireGuard server configuration, NOT to alter Client’s DNS like we can do in OpenVPN? I use Stubby for encrypted DNS (I followed your tutoral for that) and I surely do NOT want to use the ones on my Server side.

    2- is there a way to ‘see’ that Wireguard is in use (like you can see when you use OpenVPN a little ‘lock’)?

    Thanks in advance,

    • If you don’t want to use the server-side DNS resolver, edit the WireGuard client configuariton file.

      sudo nano /etc/wireguard/wg-client0.conf

      Remove the following line from the file.

      DNS = 10.10.10.1

      Save and close the file. Then restart WireGuard client.

      sudo systemctl restart wg-quick@wg-client0.service

      Actually, using 10.10.10.1 as DNS resolver will also encrypt your DNS queries. I don’t think you need to stick with Stubby.

      When the VPN client is running in command line mode, there’s no way to indicate that you are using VPN on your desktop environment. The only way to know is to check your current public IP address.

      • Darth Nagar
        5 months ago

        Thanks for your answers.
        It seems clear if I don’t use the DNS line in the client conf, it does mean then WireGuard on the Server side will use the DNS from my client, right?
        Besides, I keep Stubby for my OpenVPN connection

    • No. The server will use its own DNS resolver.

  • Outstanding tutorial. While I have my macbook up and running as a client, I can’t seem to get my iphone up and running despite adding an additional client section to the wg0.conf. Any thoughts?

  • i want to connect to vpn server with wiregaurd app on windows
    i downloaded it and i gave it the “wg-client0.conf” file. this is the error that app gave me:

    2020-07-31 02:32:23.616721: [MGR] Starting WireGuard/0.1.1 (Windows 10.0.18363; amd64)
    2020-07-31 02:32:23.622721: [MGR] Starting UI process for user ‘Vahid@DESKTOP-8BTKEQO’ for session 1
    2020-07-31 03:28:37.195610: [MGR] Exited UI process for user ‘Vahid@DESKTOP-8BTKEQO’ for session 1 with status 0
    2020-07-31 16:01:46.511021: [MGR] Starting WireGuard/0.1.1 (Windows 10.0.18363; amd64)
    2020-07-31 16:01:46.520022: [MGR] Starting UI process for user ‘Vahid@DESKTOP-8BTKEQO’ for session 1
    2020-07-31 16:02:03.899022: [TUN] [wg-client0] Starting WireGuard/0.1.1 (Windows 10.0.18363; amd64)
    2020-07-31 16:02:03.900022: [TUN] [wg-client0] Watching network interfaces
    2020-07-31 16:02:03.902023: [TUN] [wg-client0] Resolving DNS names
    2020-07-31 16:02:03.910023: [TUN] [wg-client0] Unable to resolve one or more DNS hostname endpoints: No such host is known.
    2020-07-31 16:02:03.932020: [TUN] [wg-client0] Shutting down
    2020-07-31 16:07:04.281539: [MGR] [wg-client0] Tunnel service tracker finished
    2020-07-31 16:07:10.150539: [TUN] [wg-client0] Starting WireGuard/0.1.1 (Windows 10.0.18363; amd64)
    2020-07-31 16:07:10.151538: [TUN] [wg-client0] Watching network interfaces
    2020-07-31 16:07:10.153538: [TUN] [wg-client0] Resolving DNS names
    2020-07-31 16:07:10.163538: [TUN] [wg-client0] Unable to resolve one or more DNS hostname endpoints: No such host is known.
    2020-07-31 16:07:10.163538: [TUN] [wg-client0] Shutting down

    • Maybe you missed some parts. Is your DNS running?

      Did you make these parts?

      systemctl status bind9

      Edit the BIND DNS server’s configuration file.

      sudo nano /etc/bind/named.conf.options

      Add the following line to allow VPN clients to send recursive DNS queries.

      allow-recursion { 127.0.0.1; 10.10.10.0/24; };

      Then you need to run the following command to allow VPN clients to connect to port 53.

      sudo ufw insert 1 allow in from 10.10.10.0/24

  • Hi Xiao Guoan

    I really love your awesome tutorials!!! Please dont stop and keep going on!!!
    So I finally configured my own wireguard using your tutorial.

    I have a question. I have changed the server wg0.conf “allowed client IP 10.10.10.2/32” to 10.10.10.2/24 “so that I am now able to have VPN tunnels with more clients but my VPN Clients are not able to ping eachother. please give me some advice on how to allow ping between VPN clients.

    Thanks in advance
    AN

    • Okii I notice a problem here. As soon as I changed the server wg0.conf “allowed client IP 10.10.10.2/32” to 10.10.10.2/24. So that I could have more VPN clients, e.g. 10.10.10.2,3,4 — / 24, and I was also able to surf the Internet with clients who had a public IP address through a tunnel. Everything was great. But I had always lost the packet. So something I could ping “10.10.10.1” and sometimes I couldn’t ping. After that i changed the server wg0.conf back to “allowed client IP 10.10.10.2/32”. So now i had no packet lose and everything was working great.

      But now i have two questions.

      How should I have more VPN clients? without lossing packets. In your tutorial, I can only have one VPN-client.
      How can I allow ping between VPN clients?

      Thanks in advance
      AN

    • WireGuard is designed to associate one IP address to one VPN client.

      To add more VPN clients, you need to create a unique private/public key pair for each client, then add each VPN client in the server’s config file (/etc/wireguard/wg0.conf) like this:

      [Interface]
      Address = 10.10.10.1/24
      PrivateKey = UIFH+XXjJ0g0uAZJ6vPqsbb/o68SYVQdmYJpy/FlGFA=
      ListenPort = 51820
      
      [Peer]
      PublicKey = 75VNV7HqFh+3QIT5OHZkcjWfbjx8tc6Ck62gZJT/KRA=
      AllowedIPs = 10.10.10.2/32
      
      [Peer]
      PublicKey = YYh4/1Z/3rtl0i7cJorcinB7T4UOIzScifPNEIESFD8=
      AllowedIPs = 10.10.10.3/32
      
      [Peer]
      PublicKey = EVstHZc6QamzPgefDGPLFEjGyedJk6SZbCJttpzcvC8=
      AllowedIPs = 10.10.10.4/32
      

      Then configure each VPN client as usual.

      • Nabisadah
        2 months ago

        Thanks Xiao it works perfect. Yes you’r right every client should have a unique private/public key. I just didnt notice that. Thanks mate : )

  • Hi Xiao Guoan,
    What a fantastic tutorial you have done! Awesome work
    I have followed it to a tee i thought, though the status of the server is showing as “inactive (dead) when i use the wg-quick up command to run it and even the alternative command to start the server results in the same. i have restarted Ubuntu 20.04 and still same also. Any ideas where to start looking to resolve at all?

    • Check the log.

      sudo journalctl -eu wg-quick@wg0.service
      • Hi Xiao,
        I am not sure what it all means 🙂 , i know enough IT to follow your tutorial, just not enough linux to know what to do 🙂 This is the log output;
        — Logs begin at Tue 2020-08-11 19:49:47 AEST, end at Sat 2020-08-15 18:56:29 AEST. —
        Aug 15 14:08:35 Wattserver systemd[1]: Starting WireGuard via wg-quick(8) for wg0…
        Aug 15 14:08:35 Wattserver wg-quick[173330]: wg-quick: `wg0′ already exists
        Aug 15 14:08:35 Wattserver systemd[1]: wg-quick@wg0.service: Main process exited, code=exited, status=1/FAILURE
        Aug 15 14:08:35 Wattserver systemd[1]: wg-quick@wg0.service: Failed with result ‘exit-code’.
        Aug 15 14:08:35 Wattserver systemd[1]: Failed to start WireGuard via wg-quick(8) for wg0.
        Aug 15 14:10:17 Wattserver systemd[1]: Starting WireGuard via wg-quick(8) for wg0…
        Aug 15 14:10:17 Wattserver wg-quick[173379]: wg-quick: `wg0′ already exists
        Aug 15 14:10:17 Wattserver systemd[1]: wg-quick@wg0.service: Main process exited, code=exited, status=1/FAILURE
        Aug 15 14:10:17 Wattserver systemd[1]: wg-quick@wg0.service: Failed with result ‘exit-code’.
        Aug 15 14:10:17 Wattserver systemd[1]: Failed to start WireGuard via wg-quick(8) for wg0.

    • Maybe there’s already a WireGuard process running. Stop it.

      sudo wg-quick down /etc/wireguard/wg0.conf

      Then use systemd service to start WireGuard.

      sudo systemctl start wg-quick@wg0.service
      • Worked! your the best Xiao! I will now go the next step and test from client.

        • Dallas
          2 months ago

          Hi Xiao,
          pinging from iOS after connecting WireGuard client and getting ‘204 bytes from xxx.xxx.x.xxx: Destination Unreachable’ . Any ideas of the issue here? Many thanks again

  • Thanks for this great tutorial. I am also trying to install Subspace (https://github.com/subspacecommunity/subspace) for self service configs with SSO. Subspace runs in a Docker container on the WireGuard server. It provides DNS (runs dnsmasq) which conflicts with anything running on port 53 on the WireGuard host. Do you have any recommendations for what to change/exclude from your instructions to deal with that?

  • Specifically with Ubuntu 20.04.

  • Dear Xiao Guoan,
    Thank you so much for this tutorial. After repeatedly breaking my head over wireguarding to my ubuntu server, I finally made it with your help. Unfortunately most other tutorials don’t go into the iptables details and just make do with the conf files. I have found other tutorials made by you equally helpful. Pl. keep up the good work.

  • Hi Xiao Guoan

    I follow your procedure and install on UBuntu 20,

    5.4.0-40-generic #44-Ubuntu SMP Tue Jun 23 00:01:04 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
    

    I think I hit the wall, when I edit the before.rule file. I can’t get my UFW running.
    it always say this error.

    ERROR: problem running ufw-init
    iptables-restore: line 9 failed

    Problem running ‘/etc/ufw/before.rules’

    [15:21] [localhost.com ~] # iptables -t nat -L POSTROUTING

    Chain POSTROUTING (policy ACCEPT)
    target     prot opt source               destination
    
    and line 9 is in before rules is the iptable filter
    here is my before.rule conf
    #
    # rules.before
    #
    # Rules that should be run before the ufw command line added rules. Custom
    # rules should be added to one of these chains:
    #   ufw-before-input
    #   ufw-before-output
    #   ufw-before-forward
    
    # Don't delete these required lines, otherwise there will be errors
    *filter
    :ufw-before-input - [0:0]
    :ufw-before-output - [0:0]
    :ufw-before-forward - [0:0]
    :ufw-not-local - [0:0]
    # End required lines
    
    
    # allow all on loopback
    -A ufw-before-input -i lo -j ACCEPT
    -A ufw-before-output -o lo -j ACCEPT
    
    # quickly process packets for which we already have a connection
    -A ufw-before-input -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
    -A ufw-before-output -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
    -A ufw-before-forward -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
    
    # drop INVALID packets (logs these in loglevel medium and higher)
    -A ufw-before-input -m conntrack --ctstate INVALID -j ufw-logging-deny
    -A ufw-before-input -m conntrack --ctstate INVALID -j DROP
    
    # ok icmp codes for INPUT
    -A ufw-before-input -p icmp --icmp-type destination-unreachable -j ACCEPT
    -A ufw-before-input -p icmp --icmp-type time-exceeded -j ACCEPT
    -A ufw-before-input -p icmp --icmp-type parameter-problem -j ACCEPT
    -A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT
    
    # ok icmp code for FORWARD
    -A ufw-before-forward -p icmp --icmp-type destination-unreachable -j ACCEPT
    -A ufw-before-forward -p icmp --icmp-type time-exceeded -j ACCEPT
    -A ufw-before-forward -p icmp --icmp-type parameter-problem -j ACCEPT
    -A ufw-before-forward -p icmp --icmp-type echo-request -j ACCEPT
    
    # allow forwarding for trusted network
    -A ufw-before-forward -s 10.8.0.0/8 -j ACCEPT
    -A ufw-before-forward -d 10.8.0.0/8 -j ACCEPT
    
    
    # allow dhcp client to work
    -A ufw-before-input -p udp --sport 67 --dport 68 -j ACCEPT
    
    #
    # ufw-not-local
    #
    -A ufw-before-input -j ufw-not-local
    
    # if LOCAL, RETURN
    -A ufw-not-local -m addrtype --dst-type LOCAL -j RETURN
    
    # if MULTICAST, RETURN
    -A ufw-not-local -m addrtype --dst-type MULTICAST -j RETURN
    
    # if BROADCAST, RETURN
    -A ufw-not-local -m addrtype --dst-type BROADCAST -j RETURN
    
    # all other non-local packets are dropped
    #-A ufw-not-local -m limit --limit 3/min --limit-burst 10 -j ufw-logging-deny
    #-A ufw-not-local -j DROP
    
    # allow MULTICAST mDNS for service discovery (be sure the MULTICAST line above
    # is uncommented)
    -A ufw-before-input -p udp -d 224.0.0.251 --dport 5353 -j ACCEPT
    
    # allow MULTICAST UPnP for service discovery (be sure the MULTICAST line above
    # is uncommented)
    -A ufw-before-input -p udp -d 239.255.255.250 --dport 1900 -j ACCEPT
    
    # don't delete the 'COMMIT' line or these rules won't be processed
    COMMIT
    
    # nat
    *nat
    :POSTROUTING ACCEPT [0:0]
    -A POSTROUTING -o eth0 -j MASQUERADE
    
    COMMIT
    

    could you point me to the right direction of troubleshooting this issues.
    thanks
    Jay

  • Ken Wright
    4 days ago

    Hello Xiao!

    I installed bind9 per your instructions, but when I try to start it it fails. I get an error message saying “/etc/bind/named.conf.options:25: unknown option ‘allow_recursion’ ” It worked before, but now the server is broken. If ‘allow_recursion’ is an unknown option, I must have missed something, but I can’t tell what.

    • Ken Wright
      6 hours ago

      Okay, I found the typo in named.conf.options; it was allow_recursion when it should have been allow-recursion. Got that problem fixed, but when I start Wireguard on the client it fails with the following status:

      ● wg-quick@wg-client0.service - WireGuard via wg-quick(8) for wg/client0
           Loaded: loaded (/lib/systemd/system/wg-quick@.service; enabled; vendor preset: enabled)
           Active: failed (Result: exit-code) since Mon 2020-10-26 19:07:40 EDT; 41s ago
             Docs: man:wg-quick(8)
                   man:wg(8)
                   https://www.wireguard.com/
                   https://www.wireguard.com/quickstart/
                   https://git.zx2c4.com/wireguard-tools/about/src/man/wg-quick.8
                   https://git.zx2c4.com/wireguard-tools/about/src/man/wg.8
          Process: 206719 ExecStart=/usr/bin/wg-quick up wg-client0 (code=exited, status=1/FAILURE)
         Main PID: 206719 (code=exited, status=1/FAILURE)
      
      Oct 26 19:07:40 Inspiron-3542 systemd[1]: Starting WireGuard via wg-quick(8) for wg/client0...
      Oct 26 19:07:40 Inspiron-3542 wg-quick[206719]: [#] ip link add wg-client0 type wireguard
      Oct 26 19:07:40 Inspiron-3542 wg-quick[206719]: [#] wg setconf wg-client0 /dev/fd/63
      Oct 26 19:07:40 Inspiron-3542 wg-quick[206732]: Line unrecognized: `PostUp-ipruleaddipprototcpdport25table1234'
      Oct 26 19:07:40 Inspiron-3542 wg-quick[206732]: Configuration parsing error
      Oct 26 19:07:40 Inspiron-3542 wg-quick[206719]: [#] ip link delete dev wg-client0
      Oct 26 19:07:40 Inspiron-3542 systemd[1]: wg-quick@wg-client0.service: Main process exited, code=exited, status=1/FAILURE
      Oct 26 19:07:40 Inspiron-3542 systemd[1]: wg-quick@wg-client0.service: Failed with result 'exit-code'.
      Oct 26 19:07:40 Inspiron-3542 systemd[1]: Failed to start WireGuard via wg-quick(8) for wg/client0.

      I checked the wg-client0.conf file, and it’s exactly as you specified in the Policy Routing section. Can you shed any light on this subject?

      • Ken Wright
        3 seconds ago

        You know, all this computer stuff would be easier if I learned to type. I found the problem here; another typo. It should have been = after PostUp instead of -.

        I don’t understand, though, why my Internet access stops after a few minutes. Web pages won’t load, email won’t send, nothing, but only after Wireguard has been running for a few minutes. At first everything works just fine. Do I need to tweak the PersistentKeepAlive parameter?

Leave a Comment

  • Comments with links are moderated by admin before published.
  • Your email address will not be published.
  • Use <pre> ... </pre> HTML tag to quote the output from your terminal/console.
  • Please use the community (https://community.linuxbabe.com) for questions unrelated to this article.
  • I don't have time to answer every question. Making a donation would incentivize me to spend more time answering questions.


The maximum upload file size: 2 MB.
You can upload: image.