What WireGuard gives you
WireGuard is a fast, small VPN built into the Linux kernel. With a VPS as the server, your laptop or phone can send its traffic through the server, which is useful on untrusted networks, or reach private services that listen only on the server. It uses one UDP port and key pairs instead of passwords.
Use it only for lawful purposes and in line with the acceptable use policy. Traffic leaving the VPS appears to come from the VPS address.
Install WireGuard
Ubuntu includes the tools. On AlmaLinux 9 the tools are in the EPEL repository and the kernel provides the module. Check the installation by printing the version.
sudo apt update
sudo apt install wireguardsudo dnf install epel-release
sudo dnf install wireguard-toolswg --versionCreate keys
Each device has a private key that never leaves it and a public key you share. Generate the server pair now, in a folder only root can read. Generate the client pair on the client if you can. For a quick test you can create it on the server and move it securely, then delete it.
sudo sh -c 'umask 077; mkdir -p /etc/wireguard; wg genkey | tee /etc/wireguard/server.key | wg pubkey > /etc/wireguard/server.pub'
sudo cat /etc/wireguard/server.pubumask 077; wg genkey | tee client.key | wg pubkey > client.pub; cat client.pubEnable forwarding
The server must forward packets between the VPN and the internet. Turn that on permanently with a sysctl file, and find the name of your public network interface, which you need for the next step.
echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-wireguard.conf
sudo sysctl --system | grep ip_forward
ip route get 1.1.1.1 | grep -o "dev [^ ]*"Write the server configuration
This file gives the server the address 10.8.0.1 on the VPN and listens on UDP 51820. The PostUp and PostDown lines add and remove firewall rules for forwarding and NAT. Replace eth0 with the interface you found, and paste the keys. On AlmaLinux with firewalld, skip the iptables lines and use the firewalld commands in the next section.
WAN_IF=$(ip -4 route get 1.1.1.1 | awk '{for(i=1;i<=NF;i++) if($i=="dev"){print $(i+1);exit}}')
test -n "$WAN_IF" || { echo "No IPv4 outbound interface found"; exit 1; }
sudo tee /etc/wireguard/wg0.conf >/dev/null <<EOF
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = $(sudo cat /etc/wireguard/server.key)
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o $WAN_IF -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o $WAN_IF -j MASQUERADE
[Peer]
# laptop
PublicKey = CLIENT_PUBLIC_KEY
AllowedIPs = 10.8.0.2/32
EOF
sudo chmod 600 /etc/wireguard/wg0.confOpen the firewall and start it
Allow UDP 51820. On Ubuntu with UFW, add the port. On AlmaLinux, open the port, turn on masquerade for the zone and put the VPN interface in the trusted zone. Then start the tunnel and enable it at boot.
sudo ufw allow 51820/udpsudo firewall-cmd --permanent --add-port=51820/udp
sudo firewall-cmd --permanent --add-masquerade
sudo firewall-cmd --permanent --zone=trusted --add-interface=wg0
sudo firewall-cmd --reloadsudo systemctl enable --now wg-quick@wg0
sudo wg showConfigure the client
On the client create a configuration with its own private key, the server's public key and the server address. Setting AllowedIPs to 0.0.0.0/0, ::/0 sends all traffic through the VPN. Setting it to 10.8.0.0/24 sends only VPN traffic through it. On a phone, the official WireGuard app can import the same text or a QR code.
This example routes IPv4 only. Add ::/0 only after configuring IPv6 addresses, forwarding and firewall rules on both peers. Decide how your client handles IPv6 to prevent traffic bypassing an IPv4-only VPN.
[Interface]
Address = 10.8.0.2/24
PrivateKey = CLIENT_PRIVATE_KEY
DNS = 1.1.1.1
[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = YOUR_SERVER_IP:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25sudo wg-quick up ./wg0.conf
ping -c 3 10.8.0.1
curl https://ifconfig.meinterface: wg-client
allowed ips: 0.0.0.0/0
latest handshake: 2 seconds ago
transfer: 476 B received, 564 B sent
persistent keepalive: every 25 secondsAdd devices and troubleshoot
Each new device gets its own key pair, a unique VPN address and a [Peer] block on the server. Apply changes without disconnecting others by syncing the configuration. If there is no handshake, check that UDP 51820 is open at the host firewall and at any provider-level firewall, and that the public keys are not swapped.
sudo wg-quick strip wg0 | sudo wg syncconf wg0 /dev/stdin
sudo wg show
sudo ss -lunp | grep 51820Official documentation
These upstream references provide more detail on the commands and workflows in this guide.