WireGuard is an open-source virtual private network (VPN) solution that uses modern cryptography to secure server-client network communications. It's lightweight, with a smaller codebase than alternatives like OpenVPN, focused on core functionality for speed and security. This guide walks through installing WireGuard on Ubuntu 24.04, generating server and client key pairs, configuring the server and firewall for a NAT-routed VPN tunnel, and connecting a client device. By the end, you'll have a running WireGuard VPN server with an active, tested client tunnel connection.
1. Install WireGuard
WireGuard is available in the default APT repositories on Ubuntu 24.04.
1. Install WireGuard:
$ sudo apt install wireguard -y
2. View the installed WireGuard version:
$ sudo wg --version
Output:
wireguard-tools v1.0.20210914 - https://git.zx2c4.com/wireguard-tools/
2. Configure WireGuard
WireGuard uses Cryptokey routing to enable VPN tunnels by validating public keys associated with specific IP addresses. A valid server configuration needs a private key and a public key associated with an interface.
1. Generate a new server private key:
$ sudo wg genkey | sudo tee /etc/wireguard/server_private.key
2. Restrict the private key file permissions:
$ sudo chmod 600 /etc/wireguard/server_private.key
3. Generate a public key from the private key:
$ sudo cat /etc/wireguard/server_private.key | wg pubkey | sudo tee /etc/wireguard/server_public.key
4. Check your network interfaces:
$ ip a
Note the main network interface name (for example, enp1s0) and its IP address — WireGuard uses this interface to forward tunnel traffic to the internet.
5. Create the WireGuard server configuration file:
$ sudo nano /etc/wireguard/wg0.conf
6. Add the following configuration, replacing the private key with the one you generated and enp1s0 with your server's main network interface name:
[Interface]
Address = 10.8.0.1/24
SaveConfig = true
PrivateKey = UOO//MO2GCC+5hHOz91YCP60/Zv/cnSskEH2j4eRPXo= # Server-Private-Key
PostUp = ufw route allow in on wg0 out on enp1s0
PostUp = iptables -t nat -I POSTROUTING -o enp1s0 -j MASQUERADE
PreDown = ufw route delete allow in on wg0 out on enp1s0
PreDown = iptables -t nat -D POSTROUTING -o enp1s0 -j MASQUERADE
ListenPort = 51820
This creates a new interface with the private IP 10.8.0.1/24 and lets connected clients reach the internet through NAT. Key fields:
-
Address: the private IP subnet assigned to the interface. -
SaveConfig: whentrue, saves the runtime interface configuration if the interface shuts down. -
PrivateKey: the server's private key. -
PostUp/PreDownUFW rules: allow (or remove) incoming traffic fromwg0to the external interface. -
PostUp/PreDowniptables rules: enable (or remove) NAT viaMASQUERADE, letting VPN clients reach the internet using the server's public IP. -
ListenPort: the port WireGuard listens on for incoming connections (51820).
Generate Client Configurations
1. Generate a client private key:
$ sudo wg genkey | sudo tee /etc/wireguard/client1_private.key
2. Generate a public key from the client private key:
$ sudo cat /etc/wireguard/client1_private.key | wg pubkey | sudo tee /etc/wireguard/client1_public.key
3. View the client private key:
$ sudo cat /etc/wireguard/client1_private.key
4. View the client public key:
$ sudo cat /etc/wireguard/client1_public.key
5. Create the client configuration file:
$ sudo nano /etc/wireguard/client1.conf
6. Add the following configuration, replacing the private key, server public key, and IP with your own values:
[Interface]
PrivateKey = KBUxCUqNEJqN3DBO5xu2kiBQFT8Gv46Kkqu6OIKZu3Q= # Client-Private-Key
Address = 10.8.0.2/24
DNS = 8.8.8.8
[Peer]
PublicKey = W+l7Uapd98bsNhN1g3Hs4iTCfKzcV03KNwhDPFgzqR4= # Server-Public-Key
AllowedIPs = 0.0.0.0/0
Endpoint = 192.0.2.161:51820
PersistentKeepalive = 15
This lets the client tunnel through 10.8.0.2 to reach the internet. PrivateKey/PublicKey set the client and server keys, AllowedIPs sets which IPs route through the VPN, Endpoint is the server's public IP and port, and PersistentKeepalive sends a keepalive packet every 15 seconds.
7. Copy the client config to your home directory to avoid permission errors when downloading it:
$ sudo cp /etc/wireguard/client1.conf client1.conf
8. Reopen the server configuration to register the new client:
$ sudo nano /etc/wireguard/wg0.conf
9. Add the client's public key as a new peer at the end of the file:
[Peer]
PublicKey = xZB9I6953ebGqWVLCR7L6yJw7YJi0shJ+Sub9gfUFVU=
AllowedIPs = 10.8.0.2/32
3. Manage the WireGuard Service
WireGuard runs under systemd, with wg-quick handling bringing interfaces up and down.
1. Start the WireGuard interface:
$ sudo systemctl start wg-quick@wg0.service
2. Enable it to start on boot:
$ sudo systemctl enable wg-quick@wg0.service
3. Check the service status:
$ sudo systemctl status wg-quick@wg0.service
4. Check the interface status:
$ sudo wg show wg0
5. View interface logs for troubleshooting:
$ sudo journalctl -u wg-quick@wg0.service
4. Set Up Firewall Rules
Configure the firewall to allow traffic on the WireGuard port and enable NAT forwarding between the tunnel and the internet.
1. Check the UFW status:
$ sudo ufw status
If UFW is inactive, allow SSH and enable it:
$ sudo ufw allow 22 && sudo ufw enable
2. Allow the WireGuard UDP port:
$ sudo ufw allow 51820/udp
3. Reload UFW:
$ sudo ufw reload
4. Verify the firewall rules:
$ sudo ufw status
5. Enable IPv4 forwarding:
$ echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.conf
6. Reload the sysctl configuration:
$ sudo sysctl -p
7. Enable NAT translation for the WireGuard subnet on your main interface:
$ sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o enp1s0 -j MASQUERADE
8. Save the iptables rules permanently:
$ sudo iptables-save | sudo tee /etc/iptables/rules.v4
5. Connect a Client to the VPN
1. Download the client configuration file to your device:
$ scp linuxuser@wireguard-server-ip:client1.conf .
2. Install the WireGuard client application for your device's OS.
3. Open the WireGuard client, choose "Add Tunnel" or "Import tunnel(s) from file," and load the configuration file you downloaded.
4. Activate the tunnel and confirm the connection.
5. Test connectivity to the VPN server's private IP:
$ ping -c 4 10.8.0.1
Output:
PING 10.8.0.1 (10.8.0.1) 56(84) bytes of data.
64 bytes from 10.8.0.1: icmp_seq=1 ttl=64 time=0.056 ms
64 bytes from 10.8.0.1: icmp_seq=2 ttl=64 time=0.076 ms
64 bytes from 10.8.0.1: icmp_seq=3 ttl=64 time=0.064 ms
64 bytes from 10.8.0.1: icmp_seq=4 ttl=64 time=0.065 ms
--- 10.8.0.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3049ms
rtt min/avg/max/mdev = 0.056/0.065/0.076/0.007 ms
Next Steps
- Create additional client configurations to support more devices or user groups.
- Rotate keys periodically and revoke unused peers from
wg0.conf. - Add a second WireGuard interface with a separate subnet to segment traffic between user groups.
- Explore split-tunneling by narrowing
AllowedIPsinstead of routing all client traffic through the VPN.
For the full guide with additional tips, visit the original article on Vultr Docs.
Top comments (0)