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

Updated on Apr 16, 2026
Joey SH
8 MINS READ
Table of Contents
Build a Private VPN Inside a VPS Using WireGuard

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:

Bash
sudo apt updatesudo apt install wireguard qrencode iproute2 iptables ca-certificates -y

On AlmaLinux 9, use the following commands:

Bash
sudo dnf update -ysudo dnf install epel-release -ysudo 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:

Bash
sudo tee /etc/sysctl.d/99-wireguard-forward.conf >/dev/null <<'EOF'net.ipv4.ip_forward=1net.ipv6.conf.all.forwarding=1EOF

Apply the changes with the command below:

Bash
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:

Bash
umask 077wg 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:

Bash
sudo cat /etc/wireguard/server_private.keysudo 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:

Bash
sudo mkdir -p /etc/wireguardsudo chmod 700 /etc/wireguard

Then, create the Wireguard server config file and enable NAT with:

Bash
SERVER_PRIV_KEY=$(cat /etc/wireguard/server_private.key)SERVER_PUB_IP="YOUR_SERVER_PUBLIC_IP"   # or vpn.example.comWG_PORT=51820WG_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 MASQUERADEPostDown = 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 outsidePostUp = iptables -A FORWARD -i wg0 -j ACCEPTPostUp = iptables -A FORWARD -o wg0 -j ACCEPTPostDown = iptables -D FORWARD -i wg0 -j ACCEPTPostDown = iptables -D FORWARD -o wg0 -j ACCEPTEOF

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:

Bash
sudo ufw allow 51820/udpsudo ufw allow OpenSSHsudo ufw enable   # if it wasn't enabled yetsudo ufw status

On AlmaLinux, you can use the commands below:

Bash
sudo firewall-cmd --add-port=51820/udp --permanentsudo 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:

Bash
sudo systemctl enable --now wg-quick@wg0sudo systemctl status wg-quick@wg0

Check the interface with:

Bash
ip a show wg0wg 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:

Bash
umask 077wg 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:

Bash
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:51820CLIENT_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/0Endpoint = ${SERVER_ENDPOINT}PersistentKeepalive = 25EOF

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:

Bash
sudo wg set wg0 peer ${CLIENT_PUB_KEY} allowed-ips 10.8.0.2/32sudo wg-quick save wg0

To verify it, run the command below:

Bash
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.

Bash
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:

Bash
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:

Bash
ping 10.8.0.1

On the server, you must confirm the handshakes with the command below:

Bash
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:

Bash
sudo apt install unbound -y

Here is a minimal recursive config you can use:

Bash
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:

Bash
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:

Bash
sudo systemctl stop wg-quick@wg0

Disable auto start with:

Bash
sudo systemctl disable wg-quick@wg0

Remove the package with:

Bash
sudo apt remove --purge wireguard -y

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

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.

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.

Remove the peer from the server config and restart the service with: sudo wg set wg0 peer remove sudo systemctl restart wg-quick@wg0