WireGuard VPS Setup Guide: Build a Private VPN for Maximum Security

Build a Private VPN Inside a VPS Using WireGuard

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.

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:

API gateway security on VPS

Set up MFA and RBAC Configuration

File Integrity Monitoring for Secure Data Integrity

Post Your Comment

PerLod delivers high-performance hosting with real-time support and unmatched reliability.

Contact us

Payment methods

payment gateway
Perlod Logo
Privacy Overview

This website uses cookies so that we can provide you with the best user experience possible. Cookie information is stored in your browser and performs functions such as recognising you when you return to our website and helping our team to understand which sections of the website you find most interesting and useful.