Skip to main content
COSMICBYTEZLABS
NewsSecurityHOWTOsToolsTraining
StudyProjectsNewsletterHire MeAbout
Subscribe

Press Enter to search or Esc to close

News
Security
HOWTOs
Tools
Training
Study
Projects
Newsletter
Hire Me
About
RSS Feed
Reading List
Subscribe

Stay in the Loop

Get the latest security alerts, tutorials, and tech insights delivered to your inbox.

Subscribe NowFree forever. No spam.
COSMICBYTEZLABS

Your trusted source for IT intelligence, cybersecurity insights, and hands-on technical guides.

2090+ Articles
154+ Guides

CONTENT

  • Latest News
  • Security Alerts
  • HOWTOs
  • Checklists
  • Projects
  • Exam Prep

RESOURCES

  • Search
  • Browse Tags
  • Newsletter Archive
  • Reading List
  • RSS Feed

COMPANY

  • About Us
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CosmicBytez Labs. All rights reserved.

System Status: Operational
  1. Home
  2. HOWTOs
  3. WireGuard VPN: Secure Remote Access for IT Professionals
WireGuard VPN: Secure Remote Access for IT Professionals
HOWTOIntermediate

WireGuard VPN: Secure Remote Access for IT Professionals

Deploy a modern, high-performance WireGuard VPN server on Linux for secure remote access. Covers server setup, client configuration, multi-peer management, and firewall rules.

Dylan H.

Tutorials

July 27, 2026
9 min read

Prerequisites

  • Linux server (Ubuntu 22.04/24.04 or Debian 12) with a public IP
  • sudo/root access on the server
  • Basic familiarity with Linux networking and systemd
  • UFW or iptables knowledge helpful

Introduction

WireGuard is a modern VPN protocol that cuts through the complexity of OpenVPN and IPsec while delivering better performance and a dramatically smaller attack surface — its entire kernel implementation is under 4,000 lines of code. For IT professionals running remote infrastructure, protecting cloud workloads, or enabling secure site-to-site connectivity, WireGuard is the practical choice in 2026.

This guide walks through a production-ready WireGuard deployment: server hardening, key management, multi-client configuration, NAT rules, and split tunneling. You will end up with a functional VPN server that routes client traffic through an encrypted UDP tunnel using modern Curve25519 cryptography.


Prerequisites

Before starting, confirm you have:

  • A Linux server running Ubuntu 22.04+, Ubuntu 24.04, or Debian 12 with a static public IP
  • sudo or root shell access on that server
  • Firewall control (UFW or direct iptables/nftables)
  • A client machine (Linux, macOS, Windows, or Android/iOS) for testing
  • Outbound UDP port 51820 unblocked by your upstream provider

Step 1: Install WireGuard

WireGuard has been in the Linux kernel since 5.6, so installation is simply pulling the userspace tools.

# Ubuntu / Debian
sudo apt update && sudo apt install -y wireguard wireguard-tools
 
# Verify the kernel module loads
sudo modprobe wireguard && echo "WireGuard kernel module OK"

On RHEL/Rocky/AlmaLinux 9:

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

Step 2: Generate Server Keys

WireGuard uses Curve25519 key pairs. Generate them with strict permissions — private keys must never be world-readable.

# Create the config directory with tight permissions
sudo mkdir -p /etc/wireguard
sudo chmod 700 /etc/wireguard
 
# Generate the server keypair
wg genkey | sudo tee /etc/wireguard/server_private.key | \
  wg pubkey | sudo tee /etc/wireguard/server_public.key
 
# Lock down the private key
sudo chmod 600 /etc/wireguard/server_private.key
 
# Display the public key — you will share this with clients
sudo cat /etc/wireguard/server_public.key

Save the public key output somewhere accessible; clients need it to authenticate the server.


Step 3: Configure the WireGuard Server

Identify your server's primary network interface — the one with the public IP:

ip route get 1.1.1.1 | awk '{print $5; exit}'
# Example output: eth0

Create the server configuration file. Replace SERVER_PRIVATE_KEY with the contents of /etc/wireguard/server_private.key and eth0 with your actual interface name.

sudo nano /etc/wireguard/wg0.conf
[Interface]
# The VPN subnet this server owns
Address = 10.8.0.1/24
 
# Listen on UDP 51820 (WireGuard default)
ListenPort = 51820
 
# Paste the server private key here
PrivateKey = SERVER_PRIVATE_KEY
 
# Enable IP forwarding and NAT so clients can reach the internet
PostUp   = sysctl -w net.ipv4.ip_forward=1
PostUp   = iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
PostUp   = iptables -A FORWARD -i wg0 -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
PostDown = iptables -A FORWARD -i wg0 -j ACCEPT
 
# Peers are added below — one [Peer] block per client

Set restrictive permissions on the config:

sudo chmod 600 /etc/wireguard/wg0.conf

Step 4: Make IP Forwarding Persistent

The PostUp sysctl above sets forwarding for the current session, but it resets on reboot. Make it permanent:

sudo nano /etc/sysctl.d/99-wireguard.conf
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
sudo sysctl --system

Step 5: Open the Firewall

UFW users:

# Allow WireGuard UDP port
sudo ufw allow 51820/udp
 
# Allow forwarded traffic from the VPN subnet
sudo ufw route allow in on wg0 out on eth0
sudo ufw route allow in on eth0 out on wg0
 
sudo ufw status

iptables users (if not using UFW):

sudo iptables -A INPUT -p udp --dport 51820 -j ACCEPT
sudo iptables -A FORWARD -i wg0 -j ACCEPT
sudo iptables -A FORWARD -o wg0 -m state --state RELATED,ESTABLISHED -j ACCEPT
 
# Save rules
sudo iptables-save | sudo tee /etc/iptables/rules.v4

Step 6: Generate Client Keys

Repeat this for every peer. You can generate client keys directly on the server for convenience, then transfer securely, or generate them on the client machine itself.

# Generate a keypair for the first client
wg genkey | tee /tmp/client1_private.key | wg pubkey > /tmp/client1_public.key
 
cat /tmp/client1_private.key  # Keep this secret — goes in the client config
cat /tmp/client1_public.key   # Share with the server — goes in [Peer] on wg0.conf

Clean up after transferring:

shred -u /tmp/client1_private.key /tmp/client1_public.key

Step 7: Add Clients to the Server Config

For each client, append a [Peer] block to /etc/wireguard/wg0.conf. Each client gets a unique IP in the VPN subnet.

sudo nano /etc/wireguard/wg0.conf
[Peer]
# Client 1 — laptop
PublicKey = CLIENT1_PUBLIC_KEY
AllowedIPs = 10.8.0.2/32
 
[Peer]
# Client 2 — home workstation
PublicKey = CLIENT2_PUBLIC_KEY
AllowedIPs = 10.8.0.3/32

AllowedIPs = 10.8.0.X/32 restricts each peer to a single VPN IP. WireGuard uses this as both a routing table and an access control list — traffic from a peer that does not match its AllowedIPs is silently dropped.


Step 8: Create the Client Configuration

Create this file on each client machine. The [Interface] section is the client's own identity; [Peer] points at your server.

[Interface]
# This client's VPN IP
Address = 10.8.0.2/24
 
# Client private key (generated in Step 6)
PrivateKey = CLIENT1_PRIVATE_KEY
 
# Use Cloudflare DNS over the VPN tunnel
DNS = 1.1.1.1, 1.0.0.1
 
[Peer]
# Server's public key
PublicKey = SERVER_PUBLIC_KEY
 
# Route ALL traffic through the VPN (full tunnel)
# For split tunnel, list only the subnets you want routed
AllowedIPs = 0.0.0.0/0, ::/0
 
# Server public IP and port
Endpoint = YOUR_SERVER_IP:51820
 
# Send a keepalive every 25s to maintain NAT mappings
PersistentKeepalive = 25

Save this as wg0.conf (Linux/macOS) or import it in the WireGuard GUI app (Windows/iOS/Android).

Split tunneling — to route only specific subnets through the VPN instead of all traffic, replace AllowedIPs = 0.0.0.0/0 with your target networks, e.g.:

AllowedIPs = 10.8.0.0/24, 192.168.1.0/24

Step 9: Start the WireGuard Interface

On the server:

# Start immediately and enable on boot
sudo systemctl enable --now wg-quick@wg0
 
# Verify the interface is up
sudo wg show

Expected output:

interface: wg0
  public key: <your server pubkey>
  private key: (hidden)
  listening port: 51820

peer: <client pubkey>
  allowed ips: 10.8.0.2/32

On the client (Linux):

sudo apt install -y wireguard-tools   # if not already installed
 
# Copy the client config to /etc/wireguard/wg0.conf, then:
sudo systemctl enable --now wg-quick@wg0

On macOS: Install the WireGuard app from the Mac App Store, import the .conf file, and click Activate.

On Windows: Download the official WireGuard installer from wireguard.com, import the tunnel, and activate.


Step 10: Add Peers Dynamically Without Restarting

You can add new peers to a running WireGuard interface without any downtime:

# Add a new peer on the fly
sudo wg set wg0 peer NEW_CLIENT_PUBKEY allowed-ips 10.8.0.4/32
 
# Persist the change so it survives a restart
sudo wg-quick save wg0

Remove a peer:

sudo wg set wg0 peer CLIENT_PUBKEY remove
sudo wg-quick save wg0

Verification and Testing

After activating the VPN on a client, run these checks:

# 1. Confirm the WireGuard interface is up on the client
ip addr show wg0
 
# 2. Ping the server's VPN IP
ping 10.8.0.1
 
# 3. Check your public IP — it should show the server's IP if doing full tunnel
curl https://ifconfig.me
 
# 4. On the server, watch live handshake and transfer stats
sudo watch -n 2 wg show
 
# 5. Confirm traffic is flowing (bytes transferred should increase)
sudo wg show wg0 transfer

The latest handshake timestamp in wg show confirms the peer has authenticated successfully. WireGuard only sends traffic when there is data to send, so you may not see a handshake until the first packet.


Troubleshooting

No handshake / connection timeout

  • Verify UDP 51820 is open on the server firewall: sudo ss -ulnp | grep 51820
  • Check that the client Endpoint IP and port are correct
  • Ensure the server's public key in the client config matches server_public.key
  • If behind a double NAT, set PersistentKeepalive = 25 on the client

Traffic flows but internet does not work (full tunnel mode)

  • Confirm IP forwarding is enabled: cat /proc/sys/net/ipv4/ip_forward should return 1
  • Verify the NAT masquerade rule is active: sudo iptables -t nat -L POSTROUTING -n -v
  • Check that the PostUp interface name (eth0) matches your actual interface

DNS leaks

  • Use drill or dig to confirm DNS queries go through the VPN: dig +short myip.opendns.com @resolver1.opendns.com
  • If leaking, add DNS = 1.1.1.1 to the client [Interface] block and ensure the OS respects it (resolvconf issues are common on Ubuntu — install resolvconf: sudo apt install -y resolvconf)

Permission denied on wg0.conf

  • Config files in /etc/wireguard/ must be mode 600 and owned by root
  • Run: sudo chmod 600 /etc/wireguard/wg0.conf && sudo chown root:root /etc/wireguard/wg0.conf

Logs and diagnostics

# WireGuard service logs
sudo journalctl -u wg-quick@wg0 -f
 
# Enable kernel debug logging temporarily
echo module wireguard +p | sudo tee /sys/kernel/debug/dynamic_debug/control
dmesg | grep wireguard

Summary

You now have a production-ready WireGuard VPN server with:

  • Curve25519 key-pair authentication per peer
  • NAT masquerading for full-tunnel internet routing
  • Per-peer AllowedIPs acting as an access control list
  • Persistent IP forwarding and firewall rules
  • Hot peer add/remove without interface restarts

WireGuard's minimal codebase and cryptographic simplicity make it straightforward to audit and maintain compared to legacy VPN solutions. For multi-site deployments, the same peer model scales to site-to-site tunnels by setting AllowedIPs to entire remote subnets rather than single /32 addresses. For larger fleets, tools like wg-easy (Docker-based GUI) or Netmaker build on top of this same foundation to automate peer management at scale.

#wireguard#vpn#networking#linux#security#remote-access#firewall

Related Articles

FortiGate Security Hardening: Best Practices for Enterprise

Complete FortiGate hardening guide covering admin access lockdown, firmware management, interface hardening, DNS/NTP security, certificate management,...

31 min read

SentinelOne Control vs Complete Feature Comparison

This document provides a comprehensive comparison between SentinelOne Singularity Control and Singularity Complete SKUs to help MSP teams understand the...

17 min read

SentinelOne Deep Visibility Threat Hunting

Deep Visibility is SentinelOne's EDR telemetry engine that provides comprehensive endpoint data collection for threat hunting, incident investigation, and...

22 min read
Back to all HOWTOs