IPv4 & IPv6 Leasing - Any RIR, Any LocationOrder Now
Hostperl

WireGuard VPN Setup on Ubuntu and AlmaLinux VPS

By Raman Kumar

Share:

Updated on Aug 17, 2026

WireGuard VPN Setup on Ubuntu and AlmaLinux VPS

What this WireGuard VPN setup covers

This WireGuard VPN setup walks you through building a private tunnel on a fresh VPS, starting with the first SSH login and ending with firewall rules, routing, and connection tests. It covers Ubuntu, Debian, AlmaLinux, and Rocky Linux, so you can follow the right commands for your server.

If you are moving a small team, a remote admin workflow, or a customer support network onto a Hostperl VPS, WireGuard is easier to manage than older VPN stacks. It keeps the configuration small, uses strong cryptography, and performs well on modest hardware. If you are still choosing a server, a Hostperl VPS is a straightforward place to start because you control the OS, firewall, and routing from top to bottom.

For readers who want a broader background on network decisions, Hostperl’s colocation hosting checklist and shared hosting limits and upgrade triggers help explain when a private VPS is the better fit for remote access and routing control.

Before you begin

  • One fresh VPS with Ubuntu 24.04, Ubuntu 22.04, Debian 12, AlmaLinux 9, or Rocky Linux 9.
  • Root SSH access for the first login.
  • A second terminal on your local computer for testing the new VPN connection.
  • At least one public IPv4 address. IPv6 works too, and this guide includes both.

Open your SSH session from your local computer:

ssh root@203.0.113.10

Replace 203.0.113.10 with the real public IP assigned to your server. It is a reserved documentation address, not a live host.

If your provider gives you a default non-root account, use that first login instead, then become root with sudo -i after you verify access.

Confirm the operating system

On the VPS as root, detect the distribution before you install anything:

cat /etc/os-release

You should see Ubuntu or Debian entries with ID=ubuntu or ID=debian, or AlmaLinux/Rocky Linux with ID=almalinux or ID=rocky. Use the matching command set below.

Create a non-root admin user

Keep your root session open. Create the daily login user first, then test it in a second terminal before changing SSH access rules. This sequencing avoids lockout.

Ubuntu and Debian

On the VPS as root:

apt update

Then create the admin account, set a password, and add it to sudo:

adduser deploy
usermod -aG sudo deploy

Now prepare SSH access for that user. First create the directory with safe permissions:

mkdir -p /home/deploy/.ssh
chmod 700 /home/deploy/.ssh
chown -R deploy:deploy /home/deploy/.ssh

From your local computer, copy your public key to the VPS. Replace the sample IP with your real server IP if different:

ssh-copy-id deploy@203.0.113.10

Back on the VPS, harden ownership and permissions:

chmod 600 /home/deploy/.ssh/authorized_keys
chown deploy:deploy /home/deploy/.ssh/authorized_keys

Open a second terminal on your local computer and test the new login:

ssh deploy@203.0.113.10

After you connect, confirm sudo works:

sudo -i
whoami

Successful output should show root. Leave the original root session open until this test passes.

AlmaLinux and Rocky Linux

On the VPS as root:

dnf makecache

Create the admin account, set a password, and add it to the wheel group:

useradd -m deploy
passwd deploy
usermod -aG wheel deploy

Prepare the SSH directory and permissions:

mkdir -p /home/deploy/.ssh
chmod 700 /home/deploy/.ssh
chown -R deploy:deploy /home/deploy/.ssh

From your local computer, copy the public key:

ssh-copy-id deploy@203.0.113.10

Then lock down the key file:

chmod 600 /home/deploy/.ssh/authorized_keys
chown deploy:deploy /home/deploy/.ssh/authorized_keys

In a second local terminal, test the new account:

ssh deploy@203.0.113.10

Verify sudo access:

sudo -i
whoami

Again, expect root. Do not change root SSH access until this works.

Install WireGuard

WireGuard needs the kernel module and userspace tools. Install the packages for your distribution, then confirm the service binary is available.

Ubuntu and Debian

On the VPS as root or the non-root sudo user:

apt update
apt install -y wireguard wireguard-tools

Check the kernel and tool version:

wg --version

On modern Ubuntu and Debian kernels, WireGuard is usually ready without extra module work.

AlmaLinux and Rocky Linux

On the VPS as root or the non-root sudo user:

dnf install -y epel-release
dnf install -y wireguard-tools

Check the tool version:

wg --version

If the kernel module is not loaded yet, the next step will confirm it. AlmaLinux and Rocky Linux 9 usually support WireGuard directly.

Generate server and client keys

Run these commands on the VPS as root. Keep the private key private. Anyone with it can impersonate the server.

umask 077
wg genkey | tee /etc/wireguard/server.key | wg pubkey > /etc/wireguard/server.pub
wg genkey | tee /etc/wireguard/client1.key | wg pubkey > /etc/wireguard/client1.pub

Check that the files exist:

ls -l /etc/wireguard/*.key /etc/wireguard/*.pub

You should see restrictive permissions and separate key files for server and client.

Find your network interface and local routing details

WireGuard needs the VPS’s public interface for NAT. Detect it now.

ip route show default

The output usually shows an interface such as eth0 or ens3. You will use that name in the firewall and forwarding rules below.

Also check whether IPv6 is available:

ip -6 addr show scope global

If you see a global IPv6 address, you can route IPv6 through the tunnel as well.

Enable IP forwarding safely

WireGuard can carry traffic, but forwarding must be enabled for the VPS to route client packets to the internet. Set this before you add the firewall rule.

Ubuntu and Debian

On the VPS as root:

cat >/etc/sysctl.d/99-wireguard.conf <<'EOF'
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
EOF
sysctl --system

Successful output shows the new values loaded without errors.

AlmaLinux and Rocky Linux

On the VPS as root:

cat >/etc/sysctl.d/99-wireguard.conf <<'EOF'
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
EOF
sysctl --system

On RHEL-compatible systems, this works the same way. If SELinux is enforcing, no special change is needed for WireGuard itself.

Create the WireGuard server configuration

Now write the tunnel config. Replace eth0 if your default route uses a different interface. Replace the sample tunnel IPs only if you want a different subnet.

cat >/etc/wireguard/wg0.conf <<'EOF'
[Interface]
Address = 10.44.0.1/24, fd42:44:44::1/64
ListenPort = 51820
PrivateKey = REPLACE_WITH_SERVER_PRIVATE_KEY
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
PublicKey = REPLACE_WITH_CLIENT_PUBLIC_KEY
AllowedIPs = 10.44.0.2/32, fd42:44:44::2/128
EOF

Open the file and replace the two REPLACE_WITH... values with the actual contents of these commands:

cat /etc/wireguard/server.key
cat /etc/wireguard/client1.pub

Use nano /etc/wireguard/wg0.conf if you prefer interactive editing. Save and exit after inserting the real keys. The file must not contain the placeholder text when you start the service.

Create the client configuration

On the VPS as root, print the client private key and the server public key. You will paste them into a client file on your local computer or mobile device.

cat /etc/wireguard/client1.key
cat /etc/wireguard/server.pub

Create a client config on your local computer using the real key values. The example below assumes your VPN client will use the private IPs from the server config above.

[Interface]
PrivateKey = CLIENT_PRIVATE_KEY
Address = 10.44.0.2/24, fd42:44:44::2/64
DNS = 1.1.1.1

[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = 203.0.113.10:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25

Replace 203.0.113.10 with your real VPS IP. If you only want access to the VPN subnet and server, narrow AllowedIPs instead of sending all traffic through the tunnel.

Open the firewall before starting the tunnel

Add the new rule first, then start WireGuard. That avoids a short lockout if the service comes up before the port is open.

Ubuntu and Debian with UFW

On the VPS as root:

apt install -y ufw
ufw allow 22/tcp
ufw allow 51820/udp
ufw enable
ufw status verbose

The status output should list SSH and UDP port 51820 as allowed. If you already use a custom SSH port, allow it before enabling UFW.

AlmaLinux and Rocky Linux with firewalld

On the VPS as root:

dnf install -y firewalld
systemctl enable --now firewalld
firewall-cmd --permanent --add-service=ssh
firewall-cmd --permanent --add-port=51820/udp
firewall-cmd --reload
firewall-cmd --list-all

You should see ssh and 51820/udp in the active zone. If you manage SELinux strictly, WireGuard still works with the standard UDP port.

Start WireGuard and enable it at boot

Before you start the service, check the config syntax and ensure the private key entries are real values.

chmod 600 /etc/wireguard/wg0.conf
systemctl enable --now wg-quick@wg0
systemctl status wg-quick@wg0 --no-pager

A healthy status shows the service as active and running. If it fails, jump to the troubleshooting section below.

Confirm the interface came up and the peer is loaded:

wg show
ip addr show wg0

You should see the wg0 interface with the 10.44.0.1 and fd42:44:44::1 addresses.

Test the client connection

On your local computer, import the client config into the WireGuard app or apply it with wg-quick on Linux. Then activate the tunnel and check basic connectivity.

ping 10.44.0.1

If IPv6 is enabled, test that too:

ping6 fd42:44:44::1

Then confirm internet routing if you set AllowedIPs = 0.0.0.0/0, ::/0:

curl -4 https://ifconfig.me
curl -6 https://ifconfig.me

The returned addresses should match the VPS public IPv4 and IPv6, not your home connection.

Check logs and packet flow

If traffic does not pass, inspect the service and recent journal entries on the VPS as root:

journalctl -u wg-quick@wg0 -n 50 --no-pager

For live packet counters, run:

wg show wg0

The latest handshake and transfer counters should update after the client connects.

Common problems and fixes

The tunnel starts but no internet traffic passes

Run this on the VPS as root to confirm forwarding and NAT rules:

sysctl net.ipv4.ip_forward net.ipv6.conf.all.forwarding
iptables -t nat -S POSTROUTING
ip6tables -t nat -S POSTROUTING

If forwarding is 0, reapply sysctl --system. If the NAT rule shows the wrong interface name, edit /etc/wireguard/wg0.conf, replace eth0 with the real interface from ip route show default, then restart:

systemctl restart wg-quick@wg0

The client cannot handshake

Check the public port and the peer key:

ss -lunp | grep 51820
wg show

If nothing is listening, the service did not start. If it listens but handshake stays empty, the client public key in wg0.conf is probably wrong or the endpoint IP points to the wrong server.

SSH is blocked after enabling the firewall

On the VPS, review the active rules:

UFW

ufw status numbered

firewalld

firewall-cmd --list-services
firewall-cmd --list-ports

If SSH is missing, add it first, then reload the firewall. Never remove the old access path until the new one is confirmed.

Final verification and reboot test

Before you call the setup finished, test persistence. On the VPS as root, reboot once and check that the service returns automatically:

reboot

After the VPS comes back, reconnect over SSH and run:

systemctl status wg-quick@wg0 --no-pager
wg show
ip addr show wg0

You want the interface, the service, and the peer state to survive the reboot. Then run one more client-side smoke test:

curl https://ifconfig.me

If the address is the VPS public IP, the tunnel is routing correctly.

If you want to run WireGuard on infrastructure that you control fully, a Hostperl VPS gives you the routing, firewall, and kernel access you need. For larger teams or higher traffic remote access, a dedicated server can provide more headroom for multiple tunnels and heavier throughput.

Hostperl’s support team is used to real launch-day issues: missing firewall rules, broken NAT, and SSH lockouts. That matters when you are building a production VPN for admins, agencies, or customer operations.

FAQ

Can I use WireGuard on both IPv4 and IPv6?

Yes. The server and client configs above include both address families. If your provider only gives you IPv4, remove the IPv6 lines and keep the IPv4 tunnel addresses.

Which port does WireGuard use?

The default in this guide is UDP 51820. You can change it, but remember to open the new port in UFW or firewalld before restarting the service.

Do I need a public static IP?

For a stable VPN endpoint, yes. Dynamic addresses make client configs break after every change. If your VPS IP changes rarely, update the Endpoint line in every client profile.

How do I remove the tunnel later?

Stop the service, disable it at boot, remove the firewall port, and delete the config files:

systemctl disable --now wg-quick@wg0
rm -f /etc/wireguard/wg0.conf /etc/wireguard/*.key /etc/wireguard/*.pub

Only do this after you have confirmed you no longer need the tunnel.