WireGuard VPS Setup Guide: Build a Private VPN for Maximum Security
As you must know, public VPN services can help to protect your data, but they often come with limitations and trust concerns. A better solution is to build a private VPN inside a VPS using WireGuard, which is a modern, fast, and lightweight VPN protocol.
In this guide, we will show you how to set up a secure and efficient private VPN inside your VPS using WireGuard so that you can take full control of your online privacy and network traffic.
If you don’t already have a server, you can check PerLod Hosting, which offers fast, affordable, and secure hosting solutions for VPN setups.
Table of Contents
Requirements To Build a Private VPN Inside a VPS Using WireGuard
Before you start to set up your private VPN, you must make sure to meet the following requirements:
- A fresh VPS with a public IPv4 address and optional IPv6.
- Root or sudo access.
- Open port 51820/UDP in your provider firewall.
- Operating system: Ubuntu 22.04/24.04 or Debian 12, and AlmaLinux 9 notes will be included in the guide.
Define the Private VPN Network
It is recommended to plan the IP addresses, ports, and key variables that will allow your clients to connect securely to your server. Here is a set of defaults, which you can adjust to fit your existing home network and prevent subnet conflicts:
- VPN interface: wg0
- WireGuard UDP port: 51820
- VPN network (IPv4): 10.8.0.0/24
- Server’s VPN IP: 10.8.0.1
- DNS for clients: 1.1.1.1, 1.0.0.1
Also, record the values below carefully, as they are the foundation of your entire setup:
- Server public IP: YOUR_SERVER_PUBLIC_IP
- Server public DNS or hostname: vpn.example.com
System Preparation: Install WireGuard and Enable IP Forwarding
Run the system update and install the required tools and WireGuard VPN network on your server with the following commands, depending on your OS.
On Ubuntu and Debian, use the commands below:
sudo apt update
sudo apt install wireguard qrencode iproute2 iptables ca-certificates -y
On AlmaLinux 9, use the following commands:
sudo dnf update -y
sudo dnf install epel-release -y
sudo dnf install wireguard-tools qrencode iproute-tc iptables -y
Then, enable IP forwarding for IPv4 and optional IPv6, which is the core function that allows your server to pass traffic from your VPN clients out to the internet:
sudo tee /etc/sysctl.d/99-wireguard-forward.conf >/dev/null <<'EOF'
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
EOF
Apply the changes with the command below:
sudo sysctl --system
Generate WireGuard VPN Keys
You must generate the WireGuard private and public key pair for your server. To do this, you can use the following command:
umask 077
wg genkey | sudo tee /etc/wireguard/server_private.key | wg pubkey | sudo tee /etc/wireguard/server_public.key
Once you are done, verify them with the following commands:
sudo cat /etc/wireguard/server_private.key
sudo cat /etc/wireguard/server_public.key
Create WireGuard Server Configuration and Enable NAT
In this step, you must create a WireGuard server config file, which defines the server’s VPN interface and establishes the firewall rules that enable network address translation (NAT) and packet forwarding. This is what allows your VPN clients to access the internet through the server.
We use iptables commands that execute when the interface starts (PostUp) and stops (PostDown) to manage this automatically.
Create the directory and set the correct permissions for it:
sudo mkdir -p /etc/wireguard
sudo chmod 700 /etc/wireguard
Then, create the Wireguard server config file and enable NAT with:
SERVER_PRIV_KEY=$(cat /etc/wireguard/server_private.key)
SERVER_PUB_IP="YOUR_SERVER_PUBLIC_IP" # or vpn.example.com
WG_PORT=51820
WG_NET_IPV4="10.8.0.0/24"
WG_SVR_IPV4="10.8.0.1/24"
sudo tee /etc/wireguard/wg0.conf >/dev/null <<EOF
[Interface]
Address = ${WG_SVR_IPV4}
ListenPort = ${WG_PORT}
PrivateKey = ${SERVER_PRIV_KEY}
# Optional: set a stable interface MTU (usually auto is fine; 1420 helps on some VPS)
# MTU = 1420
# NAT and forwarding (IPv4)
PostUp = iptables -t nat -A POSTROUTING -s ${WG_NET_IPV4} -o $(ip route show default | awk '/default/ {print $5; exit}') -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -s ${WG_NET_IPV4} -o $(ip route show default | awk '/default/ {print $5; exit}') -j MASQUERADE
# Allow forwarding between wg and the outside
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT
PostUp = iptables -A FORWARD -o wg0 -j ACCEPT
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT
PostDown = iptables -D FORWARD -o wg0 -j ACCEPT
EOF
Configure Firewall Rules for WireGuard
Your server is now configured; you must now open the UDP port 51820 to allow incoming VPN connections from your clients.
On Ubuntu and Debian, if you use UFW, run the commands below:
sudo ufw allow 51820/udp
sudo ufw allow OpenSSH
sudo ufw enable # if it wasn't enabled yet
sudo ufw status
On AlmaLinux, you can use the commands below:
sudo firewall-cmd --add-port=51820/udp --permanent
sudo firewall-cmd --reload
Start and Verify the WireGuard Service
At this point, you must enable the WireGuard service to run automatically at boot and then verify that the wg0 interface is up and running correctly with the following commands:
sudo systemctl enable --now wg-quick@wg0
sudo systemctl status wg-quick@wg0
Check the interface with:
ip a show wg0
wg show
You must see wg0 with IP 10.8.0.1/24 and no clients yet.
Add the First Client Peer To WireGuard
Your WireGuard server is up and running, but it doesn’t have clients. You can generate a unique key pair for a device, for example, “user-phone”, and add it as a trusted peer to the server. You can repeat these steps for each client you want to add.
First, generate the client keys with the following commands:
umask 077
wg genkey | sudo tee ~/user-phone_private.key | wg pubkey | sudo tee ~/user-phone_public.key
For the first client, we chose the 10.8.0.2/32 VPN IP and created the config as shown below:
CLIENT_NAME="user-phone"
CLIENT_PRIV_KEY=$(cat ~/user-phone_private.key)
CLIENT_PUB_KEY=$(cat ~/user-phone_public.key)
SERVER_PUB_KEY=$(cat /etc/wireguard/server_public.key)
SERVER_ENDPOINT="YOUR_SERVER_PUBLIC_IP:51820" # or vpn.example.com:51820
CLIENT_IPv4="10.8.0.2/32"
tee ~/${CLIENT_NAME}.conf >/dev/null <<EOF
[Interface]
PrivateKey = ${CLIENT_PRIV_KEY}
Address = ${CLIENT_IPv4}
DNS = 1.1.1.1, 1.0.0.1
# Optional: MTU = 1420
[Peer]
PublicKey = ${SERVER_PUB_KEY}
AllowedIPs = 0.0.0.0/0
Endpoint = ${SERVER_ENDPOINT}
PersistentKeepalive = 25
EOF
Note: AllowedIPs = 0.0.0.0/0 means all traffic goes through the VPN. For split tunnel to only reach your VPS network, set AllowedIPs = 10.8.0.0/24.
Once you are done, you can add the client to the server and assign its VPN IP with the following commands:
sudo wg set wg0 peer ${CLIENT_PUB_KEY} allowed-ips 10.8.0.2/32
sudo wg-quick save wg0
To verify it, run the command below:
wg show
You must see the client listed.
Transfer WireGuard Configuration to Client Device
The final step is to install the generated configuration on your client device. Install the official WireGuard application from your device’s app store or the WireGuard website, then transfer the “user-phone.conf” file.
For phones and tablets, the easiest method is to generate a QR code to scan directly.
qrencode -t ansiutf8 < ~/${CLIENT_NAME}.conf
For desktop operating systems, use the import function within the WireGuard application to load the file.
Test and Verify WireGuard VPN Connection
Now you must activate the tunnel in your WireGuard client app and use the following commands to check and confirm everything is working correctly.
Check the external IP with the following command:
curl https://ifconfig.me
It should show your VPS public IP if you’re using full tunnel.
Then, ping your server’s VPN IP with:
ping 10.8.0.1
On the server, you must confirm the handshakes with the command below:
wg show
You should see the client with the latest handshake and some RX/TX bytes.
Optional: Use Private Unbound DNS Resolver on VPN Server
For maximum privacy, you can replace the public DNS servers (1.1.1.1) with your own recursive resolver running directly on the VPN server. This prevents your DNS queries from being visible to third-party DNS providers and can improve response times through caching.
To do this, you can use Unbound, which is a secure and lightweight DNS resolver that will listen for requests from your VPN clients.
Install Unbound with the command below:
sudo apt install unbound -y
Here is a minimal recursive config you can use:
sudo tee /etc/unbound/unbound.conf.d/wg-recursive.conf >/dev/null <<'EOF'
server:
verbosity: 0
interface: 127.0.0.1
port: 5353
do-ip4: yes
do-ip6: no
do-udp: yes
do-tcp: yes
hide-identity: yes
hide-version: yes
harden-referral-path: yes
prefetch: yes
access-control: 10.8.0.0/24 allow
access-control: 127.0.0.0/8 allow
# Root hints auto-managed on modern distros, otherwise add a root.hints file.
EOF
Then, enable the Unbound service with:
sudo systemctl enable --now unbound
Next, you must set client DNS = 10.8.0.1:5353 in their configs.
Stop and Uninstall WireGuard Private VPN Service
If you plan to stop and remove the WireGuard VPN service, you can use the commands below.
To stop temporarily, run:
sudo systemctl stop wg-quick@wg0
Disable auto start with:
sudo systemctl disable wg-quick@wg0
Remove the package with:
sudo apt remove --purge wireguard -y
FAQs
Why should I build my own VPN instead of using a paid one?
Building your own VPN gives you full control over your data, encryption keys, and logging policies. Unlike commercial VPNs, your traffic isn’t routed through a third party, which makes it ideal for privacy, security, and learning.
What if the VPS provider blocks UDP traffic?
You can change WireGuard’s port to another UDP port or use TCP tunneling through tools like udp2raw or WireGuard over WebSocket, which need advanced setup.
How do I revoke a WireGuard client’s access?
Remove the peer from the server config and restart the service with:sudo wg set wg0 peer remove
sudo systemctl restart wg-quick@wg0
Conclusion
Build a private VPN inside a VPS gives you full control over your online privacy and network security. By using WireGuard’s modern architecture, you can create a high-speed, low-latency VPN with minimal setup and maximum reliability.
Remember to explore our flexible VPS hosting solutions, which provide secure, high-performance environments perfect for VPN deployment, web applications, or personal projects.
We hope you enjoy this guide. Subscribe to our X and Facebook channels to stay up-to-date with the latest articles and network security updates.
For further reading: