Why WireGuard and Why Now?
WireGuard has become one of the most practical VPN technologies for modern networks because it is fast, lightweight, and easier to audit than older VPN stacks. For remote work, home labs, or small business admin access, a WireGuard server on Ubuntu 24.04 is a clean way to reach internal services without exposing them directly to the internet. This tutorial walks through a secure, real-world setup: server installation, firewall and forwarding, client configuration, and a few troubleshooting checks.
What You Need Before You Start
You will need an Ubuntu 24.04 server with root or sudo access, a public IPv4 address (or port-forwarding from your router), and a client device (Windows, macOS, Linux, Android, or iOS). Make sure you know your server’s public IP or DNS name. In this guide, we’ll use a private VPN subnet of 10.10.10.0/24 and the server will be 10.10.10.1.
Step 1: Install WireGuard on Ubuntu 24.04
Update packages and install WireGuard and basic firewall tooling:
Commands:
sudo apt update
sudo apt install -y wireguard ufw
Step 2: Generate Server Keys
WireGuard uses public key cryptography. Generate a private/public key pair for the server and protect the private key permissions:
Commands:
sudo umask 077
wg genkey | sudo tee /etc/wireguard/server.key | wg pubkey | sudo tee /etc/wireguard/server.pub
View the public key (you’ll share this with clients):
Command:
sudo cat /etc/wireguard/server.pub
Step 3: Create the WireGuard Interface Configuration
Create /etc/wireguard/wg0.conf. Replace YOUR_SERVER_PRIVATE_KEY with the contents of /etc/wireguard/server.key. If your server’s network interface is not eth0, replace it accordingly (common alternatives are ens3, enp1s0, etc.).
Command:
sudo nano /etc/wireguard/wg0.conf
Example wg0.conf:
[Interface]
Address = 10.10.10.1/24
ListenPort = 51820
PrivateKey = YOUR_SERVER_PRIVATE_KEY
PostUp = ufw route allow in on wg0 out on eth0; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = ufw route delete allow in on wg0 out on eth0; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
This configuration enables NAT so VPN clients can reach the internet or other networks through the server. If you only want access to internal resources and do not need internet tunneling, you can skip the NAT portion and route traffic differently, but NAT is the most common starter setup.
Step 4: Enable IP Forwarding
To route packets between the VPN interface and your main network interface, enable IPv4 forwarding:
Commands:
echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-wireguard-forward.conf
sudo sysctl --system
Step 5: Configure the Firewall (UFW)
Allow the WireGuard UDP port and enable the firewall:
Commands:
sudo ufw allow 51820/udp
sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw status
If SSH is not already allowed and you are connected remotely, ensure OpenSSH is permitted before enabling UFW to avoid locking yourself out.
Step 6: Start and Enable the WireGuard Service
Bring up the interface and configure it to start at boot:
Commands:
sudo systemctl enable --now wg-quick@wg0
sudo wg show
The wg show output is your first verification point. At this stage you will not see peers yet, which is normal.
Step 7: Create a Client (Peer) Configuration
On your client device (or on the server if you prefer and then copy files securely), generate client keys. On Linux, you can run:
Commands (client side):
umask 077
wg genkey | tee client1.key | wg pubkey | tee client1.pub
Now add the client as a peer on the server by editing /etc/wireguard/wg0.conf and appending a [Peer] block. Replace CLIENT1_PUBLIC_KEY with the contents of client1.pub:
Server wg0.conf (append):
[Peer]
PublicKey = CLIENT1_PUBLIC_KEY
AllowedIPs = 10.10.10.2/32
Restart WireGuard to apply changes:
Command:
sudo systemctl restart wg-quick@wg0
Step 8: Build the Client VPN Profile
Create a client configuration file (for example client1.conf) and import it into the WireGuard app (Windows/macOS) or WireGuard mobile app (Android/iOS). Replace placeholders with your real values:
Example client1.conf:
[Interface]
PrivateKey = CLIENT1_PRIVATE_KEY
Address = 10.10.10.2/32
DNS = 1.1.1.1
[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = YOUR_SERVER_PUBLIC_IP_OR_DNS:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
If you only want access to your internal network and not full tunneling, replace AllowedIPs = 0.0.0.0/0 with only the networks you want to reach (for example 192.168.1.0/24 and 10.10.10.0/24). Keeping AllowedIPs tight is a simple way to reduce risk and avoid routing surprises.
Step 9: Verify the Connection and Troubleshoot
After activating the tunnel on the client, run these checks on the server:
Commands:
sudo wg show
sudo ss -lunp | grep 51820
In wg show, look for a recent latest handshake time and increasing transfer counters. If the handshake never happens, confirm UDP port 51820 is reachable from the internet (cloud security group, router port-forwarding, ISP restrictions). If handshake works but you cannot browse, re-check NAT rules, IP forwarding, and the client’s AllowedIPs. Also confirm your main interface name is correct in the PostUp/PostDown rules.
Security Tips for a Cleaner VPN Deployment
Keep your server updated, use SSH keys instead of passwords, and consider installing Fail2ban for SSH hardening. For WireGuard itself, the strongest control is peer management: only add the peers you need, assign each peer a single /32 address, and remove peers immediately when a device is lost or a user no longer needs access. WireGuard is simple by design, so good operational habits make the biggest difference.
Once this is working, you can expand the setup by adding more peers, routing to additional internal subnets, or placing WireGuard behind a firewall appliance. But even as-is, this Ubuntu 24.04 WireGuard server provides a modern, reliable VPN foundation for secure remote access.
3.
Comments
Post a Comment