How to Install and Configure a WireGuard VPN Server on Ubuntu and Debian Linux

WireGuard is a modern, lightweight, and high-performance VPN solution designed to be simpler and faster than traditional VPN protocols. This guide explains how to install and configure a WireGuard VPN server on an Ubuntu or Debian Linux machine. You will learn how to generate encryption keys, configure server and client tunnels, enable packet forwarding, configure firewall rules, and connect devices securely using WireGuard.

Prerequisites

⚠️ Switch to Root Environment

All commands in this guide should be executed with root privileges. Switch to a root shell before proceeding:

sudo -i

Alternatively:

su -

Step-by-Step Installation and Configuration

1. Install WireGuard

Install the WireGuard package:

apt update
apt install wireguard

After installation, the wg and wg-quick utilities will be available.

2. Generate Server Keys

Create the WireGuard configuration directory and generate the server key pair:

cd /etc/wireguard
umask 077

wg genkey | tee server_private.key | wg pubkey > server_public.key

The generated files are:

3. Enable IPv4 Forwarding

Edit the sysctl configuration file:

nano /etc/sysctl.conf

Add or uncomment the following line:

net.ipv4.ip_forward = 1

Apply the changes:

sysctl -p

This allows the Linux machine to route traffic between WireGuard clients and other networks.

4. Create Client Keys

mkdir myclient
cd myclient

wg genkey | tee client_private.key | wg pubkey > client_public.key

Display the client public key:

cat client_public.key

5. Display Generated Server Keys

cat server_private.key
cat server_public.key

Save these values as they will be required during server and client configuration.

6. Create Client Configuration

nano client.conf

Insert the following configuration:

[Interface]
Address = 10.0.0.2/32
PrivateKey = <CLIENT_PRIVATE_KEY>
DNS = 1.1.1.1

[Peer]
PublicKey = <SERVER_PUBLIC_KEY>
Endpoint = YOUR_SERVER_IP_OR_HOSTNAME:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

Replace YOUR_SERVER_IP_OR_HOSTNAME with the public IP, private IP, or DNS hostname of the Linux machine hosting WireGuard.

7. Generate QR Codes for Mobile Clients

Generate a terminal QR code:

qrencode -t ansiutf8 < client.conf

Create a PNG image:

qrencode -o wireguard.png < client.conf

Mobile devices can import the configuration directly by scanning the QR code from the WireGuard application.

8. Configure the WireGuard Server

nano /etc/wireguard/wg0.conf

Add the following configuration:

[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = <SERVER_PRIVATE_KEY>

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

[Peer]
PublicKey = <CLIENT_PUBLIC_KEY>
AllowedIPs = 10.0.0.2/32

Replace eth0 with the network interface connected to your network.

To identify the correct interface:

ip route get 8.8.8.8

Common interface names include: eth0, ens3, enp1s0, and wlan0.

9. Configure the Firewall

Allow incoming WireGuard traffic:

ufw allow 51820/udp
ufw reload

Verify the firewall status:

ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), allow (routed)

To                         Action      From
--                         ------      ----
22/tcp (OpenSSH)           ALLOW IN    Anywhere
51820/udp                  ALLOW IN    Anywhere
22/tcp (OpenSSH (v6))      ALLOW IN    Anywhere (v6)
51820/udp (v6)             ALLOW IN    Anywhere (v6)

Output 1: UFW firewall configuration allowing WireGuard VPN traffic.

10. Start the WireGuard Interface

wg-quick down wg0 || true
wg-quick up wg0

Verify network interfaces:

ip a

11. Verify VPN Connectivity

Display WireGuard tunnel information:

wg show
interface: wg0
  public key: +jEmBhVA6zUiVyYOTMQrQTQFl/1NU49h6GPBr1zueyw=
  private key: (hidden)
  listening port: 51820

peer: RHEhm6jAJWD4LNjo7XKwDmPLzyiP0yYhM/gcnmgBHm8=
  endpoint: 180.12.74.13:13220
  allowed ips: 10.0.0.0/24
  latest handshake: 44 minutes ago
  transfer: 47.54 MiB received, 278.44 MiB sent

Output 2: Successful WireGuard peer connection and traffic statistics.

Configure WireGuard on Android and iPhone

After creating the client configuration file, you can connect your mobile device to the VPN using either a QR code or by manually entering the tunnel configuration.

Method 1: Import Using a QR Code (Recommended)

The easiest way to configure WireGuard on a mobile device is by scanning the QR code generated from the client configuration file.

Generate the QR code on the Linux server:

qrencode -o wireguard.png < client.conf

Or display it directly in the terminal:

qrencode -t ansiutf8 < client.conf

Install the WireGuard application from the Google Play Store or Apple App Store, then follow these steps:

  1. Open the WireGuard application.
  2. Tap the + button.
  3. Select Scan from QR Code.
  4. Scan the generated QR code.
  5. Enter a tunnel name if prompted.
  6. Tap Save.
  7. Enable the tunnel using the toggle switch.

Once connected, all traffic configured by the AllowedIPs setting will be routed through the WireGuard tunnel.

Method 2: Manual Mobile Configuration

If scanning a QR code is not possible, you can manually create the tunnel configuration inside the WireGuard application.

  1. Open the WireGuard application.
  2. Tap the + button.
  3. Select Create from Scratch.
  4. Enter a tunnel name such as Home VPN.
  5. Populate the Interface and Peer sections using the values below.

Interface Settings

Address: 10.0.0.2/32
DNS: 1.1.1.1
Private Key: <CLIENT_PRIVATE_KEY>

Peer Settings

Public Key: <SERVER_PUBLIC_KEY>
Endpoint: YOUR_SERVER_IP_OR_HOSTNAME:51820
Allowed IPs: 0.0.0.0/0
Persistent Keepalive: 25

Save the tunnel and enable it using the toggle switch.

ℹ️ Understanding Allowed IPs

The value 0.0.0.0/0 routes all internet traffic through the VPN tunnel. If you only want access to resources on the VPN network, you can replace it with:

10.0.0.0/24

This configuration is commonly known as split tunneling.

Verify the Connection

After enabling the tunnel, verify that the connection is active:

  1. Open the WireGuard application.
  2. Confirm that the tunnel status shows Connected.
  3. Check that data transfer counters are increasing.
  4. Open a web browser and verify internet connectivity.

You can also verify that the server has detected the mobile device by running:

wg show

A successful connection will display a recent handshake timestamp and increasing transfer statistics for the configured peer.

Troubleshooting

No Handshake Detected

Connected but Internet Access Fails

View WireGuard Logs

journalctl -u wg-quick@wg0 -f

Conclusion

You now have a fully functional WireGuard VPN server running on Ubuntu or Debian Linux. This configuration can be deployed on physical servers, virtual machines, mini PCs, Raspberry Pi devices, or cloud-hosted systems to provide secure remote access and encrypted network connectivity.