Kokil Thapa - Professional Web Developer in Nepal
Freelancer Web Developer in Nepal with 15+ Years of Experience

Kokil Thapa is an experienced full-stack web developer focused on building fast, secure, and scalable web applications. He helps businesses and individuals create SEO-friendly, user-focused digital platforms designed for long-term growth.

Set Up a WireGuard VPN Server

By Kokil Thapa | Last reviewed: September 2026

Remote teams need a fast, auditable path into private servers without exposing SSH to the public internet. When you set up a WireGuard VPN server on a small Ubuntu VPS, you get a modern UDP tunnel that is simpler to maintain than legacy OpenVPN stacks. I have deployed WireGuard on production Linux hosts for client admin access, staging environments, and database maintenance windows. This guide walks through a complete server build you can copy on Ubuntu 22.04 or 24.04 LTS, with firewall rules, NAT, and client onboarding that match what I use alongside Linux system administration work.

Why should you set up a WireGuard VPN server instead of OpenVPN?

WireGuard lives in the Linux kernel as a lightweight module. It uses modern cryptography—Curve25519, ChaCha20, Poly1305—and keeps configuration in a few plain-text files. OpenVPN still works, but its TLS stack and larger codebase add operational overhead on small VPS plans common in Nepal and abroad.

On a real client project I needed secure SSH access to a Laravel staging box without opening port 22 globally. WireGuard solved it in under an hour. The tunnel came up faster after reboots than any OpenVPN profile I had maintained before. For teams already running Ubuntu server setup workflows, WireGuard fits naturally next to UFW and fail2ban.

WireGuard VPN Server ArchitectureRemote ClientLaptop / PhoneRemote ClientHome OfficeWireGuard ServerUDP 51820 · wg010.8.0.1/24Web Server10.0.1.10Database10.0.1.20Staging App10.0.1.30Encrypted UDP tunnel · Private RFC1918 routing
Set up a WireGuard VPN server as a secure gateway between remote clients and private infrastructure
FeatureWireGuardOpenVPNIPsec (StrongSwan)
Codebase size~4,000 linesLarge C + OpenSSLComplex multi-daemon
Default transportUDP (single port)UDP or TCPUDP 500/4500
Config styleINI-like key=valueCertificates + .ovpnXML / swanctl
Mobile clientsOfficial apps, QR importThird-party appsPlatform-dependent
Typical use caseSmall team remote accessLegacy enterprise VPNSite-to-site tunnels
Ops burden on 1 GB VPSLowMediumHigh

WireGuard is not a zero-trust replacement for every scenario. It provides network-layer access. You still need SSH keys, application auth, and audit logging on target hosts. For a comparison of tunnel types versus exposing services directly, see the guide on Cloudflare Tunnel vs traditional VPN.

What do you need before you install WireGuard on Ubuntu?

Start with a fresh Ubuntu 22.04 or 24.04 VPS with a public IPv4 address. A 1 GB RAM instance handles five to fifteen concurrent peers comfortably. WireGuard uses minimal CPU compared to PHP-FPM workloads on the same box.

Complete basic hardening first. Follow an initial Ubuntu server setup checklist: create a sudo user, disable root SSH login, and install unattended upgrades. Your VPN server becomes a high-value target because it sits at the edge of your private network.

Server prerequisites checklist

  • Ubuntu 22.04 LTS or 24.04 LTS with kernel WireGuard support (default on both)
  • A dedicated UDP port—51820 is conventional but any high port works
  • Static public IP or stable DNS A record (e.g. vpn.example.com)
  • IP forwarding enabled when clients need internet or LAN routing
  • Documented IP plan: VPN subnet (10.8.0.0/24) separate from LAN (10.0.1.0/24)
  • Backup plan for /etc/wireguard/ before you edit production configs

If you host client sites on the same provider, keep the VPN on a separate VPS when possible. Collapsing VPN and production web roles on one box saves Rs 800–1,500/month (~USD 6–11) but increases blast radius. For multi-server Laravel setups, VPN access pairs well with advice in Laravel session configuration for multi-server environments where admins reach internal Redis or database nodes.

How do you install and configure the WireGuard server step by step?

The following steps produce a working wg0 interface on Ubuntu. Commands assume you are logged in as a sudo-capable user. Official reference material lives at wireguard.com/quickstart and in the Ubuntu WireGuard server documentation.

Step 1: Install packages

sudo apt update
sudo apt install wireguard qrencode -y

The qrencode package lets you generate QR configs for mobile onboarding. It is optional but saves time when directors need phone access during travel.

Step 2: Generate server keys

umask 077
wg genkey | tee /etc/wireguard/server_private.key | wg pubkey > /etc/wireguard/server_public.key
sudo chmod 600 /etc/wireguard/server_private.key

Never commit private keys to Git. Store them in your password manager or encrypted backup. I use the password generator tool for unrelated credentials but WireGuard keys must come from wg genkey only.

Step 3: Create /etc/wireguard/wg0.conf

sudo nano /etc/wireguard/wg0.conf

Add the server block and at least one peer. Replace placeholders with your real keys and server public IP.

[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = SERVER_PRIVATE_KEY_HERE
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
# Alice laptop
PublicKey = CLIENT1_PUBLIC_KEY_HERE
AllowedIPs = 10.8.0.2/32

Change eth0 to your actual outbound interface. Run ip route to confirm—it is often ens3, enp1s0, or eth0 on cloud providers. PostUp and PostDown hooks handle NAT so VPN clients reach the internet or private LAN through the server.

WireGuard Server Setup Flow1. Install2. Gen Keys3. wg0.conf4. UFW + NATEnable Servicewg-quick@wg0Client ConfigPeer block + QRVerify Tunnelping 10.8.0.1 · wg show · SSH test
Step-by-step flow to set up a WireGuard VPN server from package install through client verification

Step 4: Enable IP forwarding

echo "net.ipv4.ip_forward=1" | sudo tee /etc/sysctl.d/99-wireguard.conf
sudo sysctl -p /etc/sysctl.d/99-wireguard.conf

Without forwarding, peers can ping the VPN gateway but cannot reach LAN hosts or the internet. This step trips up many first-time setups.

Step 5: Start and enable WireGuard

sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0
sudo wg show

The wg show output lists the interface, listening port, and connected peers with latest handshake times. No handshake after five minutes usually means firewall, wrong public key, or incorrect Endpoint on the client.

How do you create WireGuard client configs and onboard users?

Each client needs its own key pair. Generate them on the server or locally—never reuse keys across devices.

wg genkey | tee client1_private.key | wg pubkey > client1_public.key

Add the client public key as a new [Peer] block on the server. Assign the next free address in your VPN subnet.

Sample client configuration file

[Interface]
PrivateKey = CLIENT1_PRIVATE_KEY_HERE
Address = 10.8.0.2/32
DNS = 1.1.1.1

[Peer]
PublicKey = SERVER_PUBLIC_KEY_HERE
Endpoint = vpn.example.com:51820
AllowedIPs = 10.8.0.0/24, 10.0.1.0/24
PersistentKeepalive = 25

AllowedIPs controls routing. Use 10.8.0.0/24, 10.0.1.0/24 when the client should reach VPN and LAN only. Use 0.0.0.0/0 for full-tunnel mode that sends all traffic through the VPN. Full tunnel protects coffee-shop Wi-Fi but adds latency for general browsing.

Export a QR code for phones:

sudo qrencode -t ansiutf8 < /etc/wireguard/client1.conf

Scan with the official WireGuard app on iOS or Android. Desktop users import the same .conf file into the WireGuard GUI on Windows, macOS, or Linux.

Onboarding discipline matters. Maintain a simple spreadsheet: peer name, assigned IP, public key, device owner, date issued, date revoked. When a laptop is lost, remove its [Peer] block and reload wg0. No certificate revocation list gymnastics—just delete the peer and restart the interface.

How do you configure UFW firewall rules for WireGuard?

UFW is the default firewall on Ubuntu servers I administer. WireGuard needs UDP ingress on your chosen port plus forward rules for NAT. Detailed patterns appear in UFW firewall rules for web servers; VPN rules extend the same mindset.

sudo ufw allow 51820/udp comment 'WireGuard VPN'
sudo ufw route allow in on wg0 out on eth0
sudo ufw enable
sudo ufw status verbose

If UFW default forward policy is drop, edit /etc/default/ufw and set DEFAULT_FORWARD_POLICY="ACCEPT", then reload. Alternatively, keep the PostUp iptables rules in wg0.conf as shown earlier—they integrate with UFW when configured correctly.

Do not expose SSH on 0.0.0.0/0 once VPN works. Restrict SSH to the VPN subnet:

sudo ufw delete allow 22/tcp
sudo ufw allow from 10.8.0.0/24 to any port 22 proto tcp comment 'SSH via VPN only'

Test from a client before closing your current SSH session. Lock yourself out once and you will never skip that step again.

UFW Rules for WireGuard VPNInternet (untrusted)All other inbound traffic denied by defaultUFW on VPN ServerALLOW 51820/udp · FORWARD wg0 → eth0ALLOW SSHfrom 10.8.0.0/24DENY SSHfrom 0.0.0.0/0
Firewall layering when you set up a WireGuard VPN server with UFW on Ubuntu

Align these rules with broader hardening from server hardening for Ubuntu web servers and Ubuntu server security best practices. VPN access does not replace fail2ban, automatic security updates, or strong SSH key policies.

How do you harden and maintain a production WireGuard VPN?

A VPN server that stays up for years still needs monitoring, backups, and periodic key rotation. Treat it like any other production edge node.

Operational best practices

  1. Back up /etc/wireguard/ nightly alongside other config paths in your Ubuntu server backup strategies plan.
  2. Monitor handshake age with a cron script or integrate into Nagios monitoring for servers or Netdata alerts.
  3. Rotate server keys annually or after staff turnover; update all client configs when you do.
  4. Run unattended-upgrades for kernel and wireguard-dkms if applicable.
  5. Log wg show output to a central syslog host for audit trails.
  6. Document which AllowedIPs each peer receives—principle of least privilege.

For legal-tech and client portals I have built, such as secure document workflows on Mijar Law Associates, VPN access is one layer among many. Application-level auth, HTTPS everywhere, and encrypted storage still apply. VPN gets admins to the private network; it does not replace app security.

WireGuard Production Maintenance CycleBackup ConfigMonitorRotate KeysPatch KernelAudit Peers
Ongoing maintenance after you set up a WireGuard VPN server for production remote access

Common troubleshooting fixes

When a peer shows no handshake, verify UDP 51820 reaches the server from the client network. Some hotel and mobile networks block UDP except on well-known ports. PersistentKeepalive = 25 on the client helps NAT traversal for clients behind carrier-grade NAT common in Kathmandu residential connections.

When the tunnel connects but LAN hosts are unreachable, check AllowedIPs on the client and confirm IP forwarding plus MASQUERADE rules are active. Run sudo iptables -t nat -L POSTROUTING -v on the server.

When wg-quick fails at boot, a typo in PostUp usually causes it. Test with sudo wg-quick up wg0 manually and read the error. Compare against CIS benchmarks for server hardening if you need a compliance checklist beyond VPN-specific steps.

Site-to-site WireGuard between cloud VPCs follows the same peer model with broader AllowedIPs. For AWS and GCP specifics, see AWS to GCP networking and VPN setup. The kernel module and config syntax stay identical—only routing tables and security groups change.

If you prefer managed tunnels without opening UDP ports, evaluate alternatives in Cloudflare Tunnel vs traditional VPN. WireGuard wins when you want full L3 control, lowest latency, and no third-party proxy in the path.

Ongoing support for VPN and server stacks is part of what I deliver through support and maintenance services and domain registration and hosting engagements. A VPN you cannot restore from backup after a disk failure is not production-ready.

For broader security context on Nepali hosting environments, read how to secure your website and server in Nepal. WireGuard sits alongside TLS certificates from Let's Encrypt and Certbot setup, not instead of them.

Automate server provisioning with Ansible playbooks if you run multiple VPN gateways for staging and production. The wg0.conf template parameterises cleanly across inventory groups.

On booking platforms like Adventure Third Pole Trek, admin VPN access kept supplier CRM and Laravel queues off public routes during peak season traffic. The pattern scales from one VPS to a small fleet.

Key Takeaways

  • Install wireguard and qrencode on Ubuntu, generate unique key pairs per server and client, and never reuse private keys.
  • Define wg0.conf with Address, ListenPort, PostUp/PostDown NAT rules, and one [Peer] block per device with AllowedIPs scoped to least privilege.
  • Enable net.ipv4.ip_forward and allow UDP 51820 through UFW before restricting SSH to the VPN subnet only.
  • Distribute client .conf files or QR codes, verify handshakes with wg show, and remove lost devices immediately from the server config.
  • Back up /etc/wireguard/, monitor handshake age, and patch the kernel on the same schedule as your other production servers.
  • WireGuard provides network access—not application auth—so layer SSH keys, HTTPS, and RBAC on every service behind the tunnel.

People Also Ask

Does WireGuard work on Ubuntu 24.04 out of the box?

Yes. Ubuntu 24.04 LTS ships with WireGuard in the default kernel. Install the wireguard package with apt, and wg-quick manages the interface without third-party kernel modules. Ubuntu 22.04 LTS behaves the same way.

What port should WireGuard use?

51820/udp is the conventional choice and appears in most tutorials and client examples. Any unused UDP port works if your firewall and client Endpoint match. Avoid conflicting with DNS, NTP, or custom application ports on the same host.

Can WireGuard replace a commercial VPN for remote workers?

For small teams accessing private servers, yes. WireGuard gives you self-hosted control without per-seat licensing. It does not include built-in MFA, split admin audit dashboards, or client posture checks—that is your responsibility via SSH, app auth, and logging.

How many clients can one WireGuard server handle?

A 1 GB VPS comfortably supports ten to twenty idle peers with occasional traffic. Throughput limits depend on CPU and network bandwidth, not WireGuard itself. Heavy file transfers or full-tunnel browsing for many users need a larger instance or dedicated gateway.

Deploy your WireGuard VPN with confidence

You now have a complete path to set up a WireGuard VPN server: keys, wg0.conf, NAT, UFW, client onboarding, and production maintenance habits that match real Linux administration work. Start on a staging VPS, confirm handshakes and SSH-over-VPN, then cut public SSH access. If you want help hardening VPN gateways alongside Laravel apps, eCommerce stacks, or multi-server deployments, contact us or explore Linux system administration services. You can also browse the blog for related server guides and the homepage for full service coverage.

Frequently Asked Questions

Install wireguard on Ubuntu, generate server and client key pairs, define peers in /etc/wireguard/wg0.conf, enable IP forwarding, add UFW NAT rules, start wg-quick@wg0, then distribute client configs.

WireGuard lives in the Linux kernel as a lightweight module with a roughly 4,000-line codebase, using Curve25519, ChaCha20, and Poly1305 cryptography and plain-text INI-style config files. OpenVPN relies on a larger TLS stack and certificate management that adds operational overhead on small VPS plans. On a real client project I needed secure SSH access to a Laravel staging box without opening port 22 globally; WireGuard came up in under an hour and recovered faster after reboots than OpenVPN profiles I had maintained. WireGuard is not zero-trust—it provides network-layer access, and you still need SSH keys and application auth on target hosts.

Start with a fresh Ubuntu 22.04 or 24.04 LTS VPS with a public IPv4 address; a 1 GB RAM instance handles five to fifteen concurrent peers comfortably. Complete basic hardening first: create a sudo user, disable root SSH login, and install unattended upgrades, because the VPN server becomes a high-value edge target. You also need a dedicated UDP port (51820 is conventional), a static public IP or stable DNS A record such as vpn.example.com, a documented IP plan with VPN subnet 10.8.0.0/24 separate from LAN 10.0.1.0/24, and a backup plan for /etc/wireguard/ before editing production configs.

Run sudo apt update and sudo apt install wireguard qrencode -y. Generate server keys with wg genkey, storing them in /etc/wireguard/ with chmod 600 on the private key. Create /etc/wireguard/wg0.conf with an [Interface] block (Address, ListenPort 51820, PrivateKey, PostUp/PostDown iptables NAT rules using your real outbound interface such as eth0, ens3, or enp1s0) and [Peer] blocks per client. Enable IP forwarding via net.ipv4.ip_forward=1 in /etc/sysctl.d/99-wireguard.conf, then sudo systemctl enable and start wg-quick@wg0. Verify with sudo wg show for interface status and peer handshake times.

51820/udp is the conventional choice and appears in most tutorials and client Endpoint fields. Any unused UDP port works if your firewall and client config match.

Yes. Ubuntu 24.04 LTS ships with WireGuard in the default kernel; install the wireguard package with apt and wg-quick manages the interface without third-party kernel modules. Ubuntu 22.04 LTS behaves the same way.

Generate a unique key pair per device with wg genkey—never reuse keys across devices. Add each client public key as a new [Peer] block on the server with the next free address in your VPN subnet. The client config needs PrivateKey, Address such as 10.8.0.2/32, DNS, the server PublicKey, Endpoint like vpn.example.com:51820, AllowedIPs, and PersistentKeepalive = 25 for NAT traversal. Export QR codes with qrencode for mobile onboarding via the official WireGuard app. Maintain a spreadsheet tracking peer name, assigned IP, public key, device owner, and revocation dates; remove lost devices by deleting their [Peer] block and reloading wg0.

Allow UDP ingress on your WireGuard port with sudo ufw allow 51820/udp, add route rules with sudo ufw route allow in on wg0 out on eth0, then enable UFW. If the default forward policy is drop, set DEFAULT_FORWARD_POLICY="ACCEPT" in /etc/default/ufw and reload, or rely on the PostUp iptables rules in wg0.conf. Once VPN access works, restrict SSH to the VPN subnet only: delete the global port 22 rule and allow from 10.8.0.0/24 to port 22. Test from a client before closing your current SSH session to avoid locking yourself out.

A 1 GB VPS comfortably supports ten to twenty idle peers with occasional traffic, and the article's server prerequisites note five to fifteen concurrent peers on the same plan. Throughput limits depend on CPU and network bandwidth rather than WireGuard itself; WireGuard uses minimal CPU compared to PHP-FPM workloads on the same box. Heavy file transfers or full-tunnel routing where AllowedIPs is 0.0.0.0/0 will consume more resources than split-tunnel access limited to private subnets.

For small teams accessing private servers, yes—WireGuard gives self-hosted control without per-seat licensing. It does not include built-in MFA, split admin audit dashboards, or client posture checks; those remain your responsibility via SSH, application auth, and logging. WireGuard provides network-layer access to private infrastructure, not application-level security. Teams already running Ubuntu server workflows with UFW and fail2ban will find WireGuard fits naturally as a secure gateway for admin access, staging environments, and database maintenance windows.

Keep the VPN on a separate VPS when possible. Collapsing VPN and production web roles on one box saves Rs 800–1,500/month (~USD 6–11) but increases blast radius—a compromised VPN gateway exposes everything on that host. For multi-server Laravel setups, VPN access pairs well with reaching internal Redis or database nodes that should never sit on public routes. On booking platforms like Adventure Third Pole Trek, admin VPN access kept supplier CRM and Laravel queues off public routes during peak season traffic.

Without net.ipv4.ip_forward=1 enabled in /etc/sysctl.d/99-wireguard.conf and applied with sysctl -p, VPN peers can ping the VPN gateway at 10.8.0.1 but cannot reach LAN hosts or the internet. IP forwarding lets the server route traffic between the wg0 interface and your outbound interface. Combined with PostUp iptables FORWARD accept rules and POSTROUTING MASQUERADE on eth0 (or your actual outbound interface), forwarding is what makes the VPN a usable gateway rather than an isolated subnet.

Verify UDP 51820 reaches the server from the client network—some hotel and mobile networks block UDP except on well-known ports. Confirm the client Endpoint, public keys, and server firewall rules match. Set PersistentKeepalive = 25 on the client to help NAT traversal for clients behind carrier-grade NAT common in Kathmandu residential connections. Run sudo wg show on the server; no handshake after five minutes usually means firewall blockage, wrong public key, or incorrect Endpoint on the client. If the tunnel connects but LAN hosts are unreachable, check AllowedIPs on the client and confirm IP forwarding plus MASQUERADE rules are active with sudo iptables -t nat -L POSTROUTING -v.

Back up /etc/wireguard/ nightly alongside other config paths, monitor handshake age with cron scripts or monitoring tools like Nagios or Netdata, and rotate server keys annually or after staff turnover—updating all client configs when you do. Run unattended-upgrades for kernel patches, log wg show output to a central syslog host for audit trails, and document AllowedIPs per peer following least privilege. VPN access is one layer among many; application-level auth, HTTPS everywhere, and encrypted storage still apply on services behind the tunnel, as on secure document workflows for platforms like Mijar Law Associates.

AllowedIPs defines which destination traffic routes through the VPN tunnel. Use 10.8.0.0/24 and 10.0.1.0/24 when the client should reach only the VPN subnet and private LAN—this split-tunnel mode keeps general browsing off the VPN and reduces latency. Use 0.0.0.0/0 for full-tunnel mode that sends all traffic through the VPN, which protects coffee-shop Wi-Fi but adds latency for everyday browsing. On the server side, each [Peer] block uses AllowedIPs to specify which client addresses the server accepts; scope these to least privilege and remove lost devices immediately by deleting their peer entry.

Share this article

0 Comments

Leave a comment

Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

Quick Contact Options
Choose how you want to connect me: