How To Install WireGuard on Ubuntu 26.04 LTS

Install WireGuard on Ubuntu 26.04

WireGuard has become the go-to VPN choice for many Linux admins because it is easy to audit, quick to configure, and fast in daily use. On Ubuntu 26.04 LTS, the package is available from the default repositories, so you do not need third-party sources for a normal install.

In this guide, you will learn how to install the server side, generate keys, configure the tunnel, open the firewall, and connect a client peer. I will also explain why each command matters, so you understand the logic behind the setup instead of just copying commands.

This is written for beginner to intermediate Linux users, developers, and sysadmins who want a dependable WireGuard on Ubuntu 26.04 setup without messy theory or copied documentation language. By the end, you will have a working VPN and the confidence to troubleshoot it when something does not behave as expected.

Prerequisites

Before you start, make sure you have these basics ready:

  • Ubuntu 26.04 LTS on the server and, ideally, on the client too.
  • Sudo or root access on the machine that will run WireGuard.
  • A public IP address or reachable endpoint for the server, plus UDP port 51820 open in your firewall or cloud security group.
  • A second machine or device for testing the VPN client side.
  • Basic command-line tools such as apt, systemctl, ip, wg, wg-quick, and a text editor like nano or vim.

Step 1: Update your system

Refresh package lists

Start by updating the package index so Ubuntu knows about the latest repository data.

sudo apt update

This command does not install anything yet. It only refreshes the local package list so the next install step can find the correct WireGuard package.

Upgrade existing packages

If the server has been sitting idle for a while, upgrade the existing packages first.

sudo apt upgrade -y

This lowers the risk of dependency problems during installation. On a fresh VPS, it also helps you avoid weird behavior caused by older libraries or security fixes waiting to be applied.

Step 2: Install WireGuard

Install the package

Now install WireGuard and the tools needed to manage it.

sudo apt install -y wireguard wireguard-tools

wireguard provides the kernel-side support, while wireguard-tools gives you the wg and wg-quick commands you will use for config and testing. Ubuntu 26.04 includes WireGuard in the default APT repositories, so this is a normal package install, not a special setup.

Confirm the install

Check that the tools are available.

wg --version

A successful output should show a WireGuard tools version, which confirms the installation completed correctly. If the command fails, the problem is usually a broken package install or an incomplete apt update step.

Step 3: Generate server keys

Create the WireGuard directory

WireGuard config files belong in /etc/wireguard.

sudo mkdir -p /etc/wireguard
cd /etc/wireguard

This keeps the setup standard and easy to manage later. Ubuntu docs recommend placing wg-quick configs in /etc/wireguard and naming them after the interface, such as wg0.conf.

Generate the key pair

Create a private and public key for the server.

sudo sh -c 'umask 077; wg genkey | tee server_private.key | wg pubkey > server_public.key'

umask 077 is important because it forces private files to stay readable only by root. That matters because the private key must never be exposed, even for a short time.

Check the keys

Display them if you need to copy the public key later.

sudo cat /etc/wireguard/server_public.key
sudo cat /etc/wireguard/server_private.key

Only the public key should be shared with a peer. The private key stays secret and should not appear in screenshots, tickets, chats, or version control.

Step 4: Configure the server tunnel

Open the config file

Create the WireGuard interface file.

sudo nano /etc/wireguard/wg0.conf

The file name wg0.conf matches the interface name wg0, which makes wg-quick easier to use and understand.

Add the server config

Paste this example and replace the key value and interface name where needed.

[Interface]
Address = 10.100.0.1/24
ListenPort = 51820
PrivateKey = SERVER_PRIVATE_KEY_HERE
SaveConfig = false

PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

Address gives the server a VPN-side IP address, which creates the network identity for the tunnel. ListenPort tells WireGuard where to wait for incoming UDP traffic, and PrivateKey lets the server authenticate itself.

PostUp and PostDown matter because they handle NAT and forwarding. Without them, clients may connect but still fail to reach the internet through the tunnel. Replace eth0 with your real outbound interface if your server uses a different one such as ens3 or enp1s0.

Lock down the file

Set strict permissions on the config.

sudo chmod 600 /etc/wireguard/wg0.conf

This protects the private key inside the file. It also follows the same security logic Ubuntu recommends for WireGuard keys and interface files.

Step 5: Enable IP forwarding

Turn on kernel forwarding

WireGuard can encrypt traffic, but Linux still needs permission to route packets between interfaces.

echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-wireguard.conf
sudo sysctl -p /etc/sysctl.d/99-wireguard.conf

This tells the kernel to forward traffic between the VPN interface and the public interface. If you skip this step, your VPN may connect but the client will not browse the internet through the server.

Verify the setting

Confirm that forwarding is active.

sysctl net.ipv4.ip_forward

The expected result should be net.ipv4.ip_forward = 1. That means Linux is now acting as a router for this tunnel instead of blocking transit packets.

Step 6: Open the firewall

Allow SSH first

Never lock yourself out.

sudo ufw allow 22/tcp

This keeps remote admin access alive while you turn the firewall on. If you are using a custom SSH port, allow that one instead.

Allow WireGuard traffic

Open the UDP port used by the VPN.

sudo ufw allow 51820/udp

WireGuard uses UDP, not TCP, so this rule must be UDP or the tunnel will never receive packets.

Enable UFW

Turn the firewall on after the rules are ready.

sudo ufw --force enable
sudo ufw status verbose

This protects the host while keeping the VPN and SSH reachable. On a production system, firewall policy matters because VPN traffic can reach back into your network unless you restrict it carefully.

Step 7: Start WireGuard on the server

Bring the interface up

Use systemd to start the tunnel now and on boot.

sudo systemctl enable --now wg-quick@wg0

wg-quick@wg0 tells systemd to read /etc/wireguard/wg0.conf and apply it as the wg0 interface. enable --now means the tunnel starts immediately and also comes back after reboot.

Confirm the service state

Check that the service is active.

sudo systemctl status wg-quick@wg0 --no-pager

A healthy service may show active (exited), which is normal for this unit type. wg-quick sets up the interface and exits after the job is done.

Inspect the interface

Verify the tunnel IP exists.

ip addr show wg0

You should see the 10.100.0.1/24 address assigned to wg0. That confirms the server side is ready for peer connections.

Step 8: Create the client peer

Install WireGuard on the client

On the second machine, install the same tools.

sudo apt update
sudo apt install -y wireguard wireguard-tools

This gives the client side the same wg and wg-quick utilities used on the server. A matching toolset makes setup and troubleshooting much easier.

Generate client keys

Create a new key pair for the client.

sudo mkdir -p /etc/wireguard
cd /etc/wireguard
sudo sh -c 'umask 077; wg genkey | tee client_private.key | wg pubkey > client_public.key'

Each peer should have its own key pair. That keeps identities separate and lets you revoke one peer later without breaking the others.

Build the client config

Create /etc/wireguard/wg0.conf on the client.

[Interface]
Address = 10.100.0.2/24
PrivateKey = CLIENT_PRIVATE_KEY_HERE
DNS = 1.1.1.1

[Peer]
PublicKey = SERVER_PUBLIC_KEY_HERE
Endpoint = YOUR_SERVER_PUBLIC_IP:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

AllowedIPs = 0.0.0.0/0 sends all traffic through the tunnel, which creates a full-tunnel VPN setup. PersistentKeepalive = 25 helps keep the UDP session alive behind home routers and NAT devices.

DNS = 1.1.1.1 gives the client a resolver through the tunnel. That helps avoid DNS leaks and makes name resolution behave more predictably during the VPN session.

Step 9: Register the client on the server

Add the peer block

Back on the server, add the client public key to wg0.conf.

[Peer]
PublicKey = CLIENT_PUBLIC_KEY_HERE
AllowedIPs = 10.100.0.2/32

This AllowedIPs value does two jobs. It tells the server which source IP the peer is allowed to claim, and it also tells WireGuard where to route traffic for that peer.

Reload the live config

Apply the updated peer list.

sudo wg syncconf wg0 <(sudo wg-quick strip wg0)

This reloads the configuration without taking the interface fully down. That helps avoid interrupting existing traffic while you add a peer.

Step 10: Start and test the client

Bring the client interface up

Activate the tunnel on the client.

sudo systemctl enable --now wg-quick@wg0

This tells the client to connect using its wg0.conf file and start automatically on reboot. If the config is correct, the handshake should happen almost instantly.

Check tunnel status

Look for the handshake and byte counters.

sudo wg

A successful output should show a recent latest handshake time and increasing transfer counts. If the handshake stays empty, the issue is usually a blocked UDP port, a wrong endpoint, or mismatched keys.

Test tunnel reachability

Ping the server tunnel address.

ping -c 4 10.100.0.1

If this works, the encrypted link is alive and routing is in place. That is the fastest proof that the VPN is functioning at layer 3.

Test public IP routing

Check whether internet traffic exits through the server.

curl -s ifconfig.me

If the output matches the server public IP, your full-tunnel configuration is working correctly. That also confirms NAT masquerade is doing its job.

Troubleshooting

1. No handshake at all

If sudo wg shows no handshake, start by checking the endpoint, the public IP, and the UDP firewall rule. This problem usually means the server port is blocked somewhere between the client and the server.

2. Handshake works, but no internet

If the tunnel connects but web traffic fails, check net.ipv4.ip_forward and the NAT rule in PostUp. The kernel must forward packets, and the server must rewrite source addresses for return traffic to work.

3. DNS works badly

If IP-based traffic works but domain names fail, the client probably did not apply the DNS setting. Install or check your resolver support, then reconnect the interface.

4. Wrong interface name in NAT

If your server uses ens3 or another name instead of eth0, the masquerade rule will point at the wrong device. Run ip route show default and replace eth0 with the real outbound interface.

5. Private key exposed

If you ever pasted the private key into a ticket, chat, or forum, regenerate the key pair and update the peer config. Ubuntu docs warn that WireGuard config files often leak secrets during troubleshooting, so keep private keys separate when possible.

[su_box title=”VPS Manage Service Offer” style=”bubbles” box_color=”#000000″ radius=”10″]If you don’t have time to do all of this stuff, or if this is not your area of expertise, we offer a service to do “VPS Manage Service Offer”, starting from $10 (Paypal payment). Please contact us to get the best deal![/su_box]

r00t is a Linux Systems Administrator and open-source advocate with over ten years of hands-on experience in server infrastructure, system hardening, and performance tuning. Having worked across distributions such as Debian, Arch, RHEL, and Ubuntu, he brings real-world depth to every article published on this blog. r00t writes to bridge the gap between complex sysadmin concepts and practical, everyday application — whether you are configuring your first server or optimizing a production environment. Based in New York, US, he is a firm believer that knowledge, like open-source software, is best when shared freely.

Related Posts