WireGuard on Raspberry Pi 5: Complete Step-by-Step Guide from Installation to Speed Testing
A beginner-friendly step-by-step guide to setting up a WireGuard server on Raspberry Pi 5: from preparation and configuration to load testing and real-world speed checks. In 2–3 hours, you’ll have your own personal VPN, test throughput, and optimize performance.
Content of the article
- Introduction
- Preparation
- Basic concepts
- Step 1: preparing raspberry pi 5 and operating system
- Step 2: network settings, static ip, and ssh access
- Step 3: installing wireguard and preparing the kernel
- Step 4: creating keys, address scheme, and basic wg0 configuration
- Step 5: routing, nat, and port forwarding on router
- Step 6: adding clients (phone, laptop), qr code, and initial testing
- Step 7: speed tests, load, and bottleneck diagnostics
- Result verification
- Common issues and solutions
- Additional features
- Faq
- Conclusion
Introduction
In this step-by-step guide, you’ll set up a fast and reliable VPN server on your Raspberry Pi 5 using WireGuard. You’ll configure routing and encryption, connect clients from your computer and phone, test real speeds, run load tests, and learn how to diagnose and fix common issues. By the end, you'll have your own secure VPN tunnel for safe access to your home network, encrypting traffic on public Wi-Fi, and bypassing restrictions.
Who this guide is for. It’s designed for beginners using Raspberry Pi who have never set up a VPN before, as well as those comfortable with the terminal looking for a detailed tutorial plus a few advanced tips. We’ll explain every step clearly but also include optimization blocks for those who want to maximize speed and stability.
What you should know beforehand. Basic Raspberry Pi skills and willingness to run commands in the terminal. Deep Linux knowledge isn’t required, but attention to detail helps. We’ll explain all key concepts in simple terms.
How much time it takes. Installing the system and updates takes 20–40 minutes. Basic WireGuard setup and adding first clients takes 30–60 minutes. Router configuration and testing require 20–40 minutes. Plan for 2–3 hours if you take your time with each step.
Preparation
Needed tools and access. You’ll need a Raspberry Pi 5, a 27W USB-C power supply or a quality 5V 5A adapter, a 32–128 GB microSD card rated A1 or better, an Ethernet cable to connect to your home router, a computer with Raspberry Pi Imager installed, router access for port forwarding setup, and your ISP login info if you need to check for CGNAT. A monitor and keyboard are helpful for the first boot but optional with headless setup.
System requirements. Raspberry Pi OS 64-bit (Bookworm or newer) is recommended, with WireGuard support built into the kernel by default. For speeds up to 1 Gbps, the standard setup is fine. For best stability, use wired Ethernet rather than Wi-Fi. Any current mobile or desktop WireGuard client will work on your devices.
What to download and install. Install Raspberry Pi Imager on your computer and prepare the Raspberry Pi OS Lite 64-bit image for a minimal environment. On the Pi, we will install wireguard-tools, iperf3 for testing, nftables or iptables-nft for NAT, and qrencode to easily add mobile clients.
Backups. If your card already has important data or an OS, create an image backup with any suitable tool. After configuring WireGuard, we'll show you how to save a backup of your config to quickly restore on a new card if your memory card fails.
Basic Concepts
Key terms in plain English. WireGuard is a modern VPN protocol that creates an encrypted tunnel between devices. The server is your Raspberry Pi 5 accepting incoming connections. The client is your phone or laptop connecting to it. Keys are pairs of private and public keys used for encryption and authentication. The wg0 interface is a virtual network adapter handling encrypted traffic. AllowedIPs is the list of subnets and addresses routed through the tunnel.
How it works. Each tunnel participant has a permanent key pair and an IP from a virtual subnet like 10.6.0.0/24. The client sends UDP packets to the server’s public IP and port. The server decrypts traffic and routes it to the internet or local network depending on your settings. Routes are defined on the client side by AllowedIPs and on the server side by routing and NAT rules.
What’s important to understand before starting. WireGuard’s speed depends on CPU, MTU, network quality, and routing between providers. Raspberry Pi 5 is powerful enough for near-gigabit speeds on local LAN and hundreds of Mbps over the internet, provided the ISP’s network isn’t a bottleneck. Proper MTU and NAT settings are crucial for stability and performance.
Step 1: Preparing Raspberry Pi 5 and Operating System
Goal
Set up a fresh 64-bit Raspberry Pi OS Lite system, enable SSH, and configure basic settings to start installing WireGuard.
Step-by-step
- Launch Raspberry Pi Imager on your computer. Select Raspberry Pi OS Lite (64-bit).
- Choose your microSD card as the target. Double-check to avoid erasing the wrong drive.
- Click the settings gear icon in Imager. Enable SSH, select password authentication or set a public SSH key. Enter username (e.g., “pi”) and a strong password of at least 12 characters.
- Set hostname, for example “rpi5-wg”. Choose country, language, and keyboard layout. Enable Wi-Fi only if no wired connection is available—enter SSID and password. Ethernet is recommended.
- Click “Save” then “Write”. Wait for writing and verification to finish (3–10 minutes).
- Remove the card from your PC and insert it into the Raspberry Pi 5. Connect Ethernet to your router and power up the Pi. Wait 20–60 seconds for boot.
- Find the Pi’s IP address. Check your router’s client list or use a mobile network scanner. It’s usually 192.168.1.XX.
- SSH into the Pi: “ssh pi@192.168.1.XX”. Accept the fingerprint on first login and enter your password.
- Update the system: “sudo apt update && sudo apt full-upgrade -y”. Reboot: “sudo reboot” and reconnect via SSH.
- Install latest firmware and tools: “sudo rpi-eeprom-update -a”. You may need to reboot again with “sudo reboot”.
⚠️ Warning: Don’t turn off power during SD card writing or firmware updates—it can corrupt the card’s filesystem.
Tip: Give your Pi a unique hostname to avoid confusion if you have multiple devices on your network.
✅ Check: Run “uname -m” and confirm output is “aarch64”. Check OS version with “cat /etc/os-release” for Raspberry Pi OS Bookworm. Ensure “ssh pi@address” connects without errors.
Expected result: You have a fresh 64-bit Raspberry Pi OS Lite running with stable SSH access, and your device is reachable on the local network.
Common issues and solutions: If SSH is unavailable, verify you enabled it in Imager settings. If device isn't visible, check Ethernet cable and router port, try different port if needed. If system won’t boot, rewrite the image or use another microSD card.
Step 2: Network Settings, Static IP, and SSH Access
Goal
Assign a permanent local IP to your Raspberry Pi 5, set the correct timezone, and ensure SSH is stable. This is critical for port forwarding and smooth management.
Step-by-step
- Set the timezone: run “sudo raspi-config”, go to “Localization Options” and select your region. This helps accurate logs and connection diagnostics.
- Check the network interface: “ip -4 addr”. Ethernet is usually “eth0” with IP like 192.168.X.Y.
- Reserve a static IP in your router’s admin panel using DHCP reservation. Find the Pi’s MAC address with “ip link show eth0” and reserve an IP, e.g., 192.168.1.10. This is preferred and easiest.
- If no DHCP reservation is available, set a static IP directly. Edit “sudo nano /etc/dhcpcd.conf” and add: “interface eth0”, “static ip_address=192.168.1.10/24”, “static routers=192.168.1.1”, “static domain_name_servers=1.1.1.1 8.8.8.8”. Save and restart networking with “sudo systemctl restart dhcpcd”.
- Test internet connectivity: “ping -c 3 1.1.1.1” and “ping -c 3 debian.org”. If successful, network works.
- Reconnect via SSH to new static IP: “ssh pi@192.168.1.10”.
Tip: Write your Pi’s local IP on a sticker and attach it to the case — saves time during troubleshooting.
✅ Check: “ip route” should show default gateway through your router, and “ip -4 addr show eth0” shows your static IP. SSH connects reliably to this IP.
Expected result: Raspberry Pi has a static local IP, internet access works, timezone is correct, and you’re ready to install WireGuard.
Common issues and fixes: If no internet, check gateway and DNS in config. If IP conflicts occur, pick another available address in your subnet.
Step 3: Installing WireGuard and Preparing the Kernel
Goal
Install WireGuard tools, confirm the kernel and module are ready, and prepare the system for creating the VPN tunnel.
Step-by-step
- Update package lists: “sudo apt update”.
- Install WireGuard and tools: “sudo apt install -y wireguard wireguard-tools qrencode iperf3 nftables resolvconf”. The wireguard-dkms package isn’t needed on recent kernels as the module is built-in.
- Load the WireGuard module: “sudo modprobe wireguard” then check with “lsmod | grep wireguard”. If you see “wireguard”, it's loaded.
- Enable autostart for nftables and systemd-resolved services: “sudo systemctl enable nftables” and “sudo systemctl enable systemd-resolved”. The latter ensures DNS works properly.
- Check the WireGuard version: “wg --version” should display wg-quick and wireguard-tools versions.
⚠️ Warning: Don’t install conflicting legacy iptables and nftables rulesets. This guide uses nftables as it’s more modern and compatible with Debian Bookworm.
Tip: If you updated the kernel, reboot before verifying WireGuard module to ensure it loads.
✅ Check: Running “wg” without args should produce empty output without errors. “lsmod | grep wireguard” shows the module. No installation errors should appear.
Expected result: WireGuard is installed, kernel module loaded, CLI tools ready, and nftables enabled for NAT setup.
Common issues and solutions: If module doesn’t load, check “uname -r” for kernel version and update system. If packages aren’t found, verify sources in “/etc/apt/sources.list” and run “sudo apt update” again.
Step 4: Creating Keys, Address Scheme, and Basic wg0 Configuration
Goal
Generate server keys, set the VPN subnet, and create the wg0 interface config that will bring up the server tunnel.
Step-by-step
- Create config directory with restricted permissions: “sudo mkdir -p /etc/wireguard && sudo chmod 700 /etc/wireguard”.
- Generate server keys securely: “umask 077; wg genkey | sudo tee /etc/wireguard/server_private.key | wg pubkey | sudo tee /etc/wireguard/server_public.key > /dev/null”. This creates private and public keys with correct permissions.
- View the private key: “sudo cat /etc/wireguard/server_private.key”. Copy this for your config. The public key “sudo cat /etc/wireguard/server_public.key” is given to clients.
- Choose VPN subnet: 10.6.0.0/24 with server IP 10.6.0.1 is safe and unlikely to conflict with typical home networks.
- Create the interface config: “sudo nano /etc/wireguard/wg0.conf”. Paste:
“[Interface]”
“Address = 10.6.0.1/24”
“ListenPort = 51820”
“PrivateKey = YOUR_PRIVATE_KEY”
“SaveConfig = true”
Don’t add PostUp/PostDown yet—we’ll set up NAT next. - Secure the config file: “sudo chmod 600 /etc/wireguard/wg0.conf”.
- Enable IPv4 forwarding: “echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-sysctl.conf”. Apply settings: “sudo sysctl --system” and verify with “sysctl net.ipv4.ip_forward” (should be “1”).
- Bring up the interface: “sudo wg-quick up wg0”. Check with “ip addr show wg0” for the 10.6.0.1/24 address.
- Enable auto-start on boot: “sudo systemctl enable wg-quick@wg0”.
Tip: You can rename the interface from “wg0” if you want, but for simplicity we keep wg0. For multiple tunnels, use wg1, wg2, etc.
✅ Check: “wg show” lists wg0 with ListenPort 51820 and your server’s public key. “wg-quick up wg0” runs without errors. “ip a” shows wg0 is UP.
Expected result: WireGuard server interface is running, listening on UDP port 51820, IPv4 forwarding enabled, ready for client setup.
Common issues and solutions: “RTNETLINK answers: File exists” means conflicting routes—run “sudo wg-quick down wg0” then up again. If “Cannot find device wg0”, check module and config file.
Step 5: Routing, NAT, and Port Forwarding on Router
Goal
Set up NAT with nftables so clients can access the internet through the server, and forward UDP port 51820 on your router for external access.
Step-by-step
- Identify your Pi’s external interface: “ip route get 1.1.1.1”. The output shows “dev eth0” or similar as external interface.
- Create a basic nftables config: “sudo nano /etc/nftables.conf”. Paste:
“flush ruleset”
“table inet wg {”
“ chain prerouting { type nat hook prerouting priority -100; }”
“ chain input { type filter hook input priority 0; policy accept; }”
“ chain forward { type filter hook forward priority 0; policy accept; }”
“ chain output { type filter hook output priority 0; policy accept; }”
“ chain postrouting { type nat hook postrouting priority 100; }”
“}”
Save the file. - Add MASQUERADE rule: inside the postrouting chain add:
“oifname "eth0" ip saddr 10.6.0.0/24 counter masquerade”
Make sure “eth0” matches your actual external interface. - Load the rules: “sudo nft -f /etc/nftables.conf”. Verify with “sudo nft list ruleset” showing your wg table and MASQUERADE rule.
- Add PostUp/PostDown commands to wg0 config for automatic NAT rule loading. Edit “/etc/wireguard/wg0.conf”, under [Interface] add:
“PostUp = nft -f /etc/nftables.conf”
“PostDown = nft flush ruleset”
Note: This is a simple approach; a persistent config is better for production to avoid flushing all rules on shutdown. - Restart WireGuard interface: “sudo wg-quick down wg0 || true && sudo wg-quick up wg0”. Check nftables and WireGuard status again.
- Forward UDP port 51820 on your router. Log into router admin, find port forwarding/NAT, create a rule forwarding external UDP 51820 to Raspberry Pi’s internal IP (e.g., 192.168.1.10) port 51820 UDP. Save.
- Check port listening on Pi: “sudo ss -ulnpt | grep 51820”. You should see UDP listener on *:51820.
⚠️ Warning: If your ISP uses CGNAT, port forwarding won’t work. Contact your provider for a public IP or use alternatives like an external VPS as a traffic relay, or WireGuard with client-server-transit setups.
Tip: Disable UPnP for port 51820 on your router if it’s enabled, to avoid conflicts with static port forwarding.
✅ Check: Inside your LAN, run “nc -u -zv 192.168.1.10 51820” which should succeed without permission errors. From outside your network (e.g., phone on mobile data), verify handshake via “wg show”.
Expected result: NAT enabled, client traffic masqueraded as Raspberry Pi’s IP, UDP port 51820 forwarded and accessible externally if public IP is available.
Common issues and solutions: If clients have no internet, confirm ip_forward=1 and MASQUERADE rule. If inaccessible externally, check for double NAT (ISP modem + router) and switch to bridge mode or adjust forwarding accordingly.
Step 6: Adding Clients (Phone, Laptop), QR Code, and Initial Testing
Goal
Create client configs, register them on the server as peers, connect your phone and laptop, and verify that traffic flows through the tunnel.
Step-by-step
- Generate client1 keys: “wg genkey | tee client1_private.key | wg pubkey | tee client1_public.key”. For security, generate as your user and set file permissions to 600.
- Find your server’s public IP or DNS name. If dynamic IP, set up DDNS on your router. For testing, get current public IP with “curl ifconfig.me” from the Raspberry Pi.
- Create client1.conf on the Pi:
“[Interface]”
“PrivateKey = CLIENT_PRIVATE_KEY”
“Address = 10.6.0.2/32”
“DNS = 1.1.1.1”
“[Peer]”
“PublicKey = SERVER_PUBLIC_KEY”
“Endpoint = YOUR_IP_OR_DNS:51820”
“AllowedIPs = 0.0.0.0/0, ::/0”
“PersistentKeepalive = 25”
This routes all client traffic through the VPN. - Add the client to server config “sudo nano /etc/wireguard/wg0.conf” at the end:
“[Peer]”
“PublicKey = CLIENT_PUBLIC_KEY”
“AllowedIPs = 10.6.0.2/32”
Save. - Apply config: “sudo wg addconf wg0 <(wg-quick strip wg0)” or restart interface “sudo wg-quick down wg0 && sudo wg-quick up wg0”.
- Generate a QR code for mobile client: “qrencode -t ansiutf8 < client1.conf”. Scan the terminal QR code from the WireGuard app on iOS or Android by choosing “Create from QR code”.
- Install the official WireGuard app on your laptop, import “client1.conf”, and save the profile.
- Connect clients. Activate the tunnel on your phone. On your laptop, hit “Activate”. On the server, run “sudo wg show”—you should see the latest handshake timestamp and growing transfer counters.
Tip: To have the client use its local internet connection but access your home LAN via VPN, replace AllowedIPs with “10.6.0.0/24, 192.168.1.0/24” and remove “0.0.0.0/0”. This creates a split tunnel.
✅ Check: On the phone, visit IP lookup sites to confirm your home IP is shown. Ping 10.6.0.1 and 192.168.1.1 should work if LAN access is permitted.
Expected result: Clients connect successfully, traffic routes through the VPN, transfer stats grow, and latency is stable.
Common issues and fixes: No handshake? Check port forwarding and public IP. Handshake but no internet? Verify MASQUERADE and ip_forward. Mobile network dropouts? Increase PersistentKeepalive to 25–30 seconds.
Step 7: Speed Tests, Load, and Bottleneck Diagnostics
Goal
Measure WireGuard throughput on Raspberry Pi 5 objectively, assess CPU load, determine actual LAN and internet speeds, and identify bottlenecks.
Step-by-step
- Install iperf3 on both ends. It’s already installed on the Pi. On your laptop, install iperf3 and run the server on the Pi: “iperf3 -s”. Keep this window open.
- From the client, test with multiple streams: “iperf3 -c 10.6.0.1 -P 4 -t 20”. The “-P 4” runs 4 parallel streams for better load. Note the average speed.
- Test single-stream performance with: “iperf3 -c 10.6.0.1 -P 1 -t 20” to see raw tunnel behavior without aggregation.
- Watch CPU usage on the Pi during tests: open another terminal and run “top” or “htop”. Cortex-A76 cores at 2.4 GHz on Pi 5 easily handle hundreds of Mbps with multiple threads.
- Measure internet speed over VPN: run iperf3 server on a VPS or external point, connect from client with VPN active using “iperf3 -c SERVER -P 4 -t 20”. Alternatively, compare speedtest-cli results with and without VPN to gauge encryption and routing overhead.
- Optimize MTU: test with “sudo ping -M do -s 1380 1.1.1.1” from the Pi over the internet. If no fragmentation, set MTU=1420 by default. If issues arise, lower the MTU for wg0 by adding “MTU = 1380” under [Interface] in wg0.conf and restart.
- Update queue disciplines to reduce bufferbloat: run “sudo tc qdisc replace dev eth0 root fq_codel” and “sudo tc qdisc replace dev wg0 root fq_codel”. This smooths latency spikes under load.
- Repeat iperf3 tests to compare performance before and after MTU and qdisc tweaks. Note stability, jitter, and peak speeds.
Tip: For a stress test, use “-P 8” and “-t 60” to better understand behavior under prolonged heavy load and detect overheating or throttling if cooling isn’t sufficient.
Tip: Enable performance CPU governor: “sudo apt install -y cpufrequtils” then “echo 'GOVERNOR="performance"' | sudo tee /etc/default/cpufrequtils && sudo systemctl restart cpufrequtils”. This can boost speeds by 5–10% during peak load.
✅ Check: Expect hundreds of Mbps locally over VPN, often in the 700–900 Mbps range with multiple streams. Internet speeds depend on your ISP and remote server. Stable handshake and no iperf3 retries indicate correct MTU settings.
Expected results and “real speeds”. On Raspberry Pi 5, WireGuard LAN speeds usually reach gigabit Ethernet limits and TCP stack traits. Practical results show 0.7–0.95 Gbps total UDP throughput with multiple streams and proper MTU. Internet speeds are typically limited by provider bottlenecks and routing, with good channels seeing 300–600 Mbps normal and some scenarios exceeding 700 Mbps. Lower results warrant checking MTU, overheating, or CGNAT transit.
Common problems and solutions: If CPU maxes out one core with low speeds, ensure iperf3 uses multiple streams and qdisc isn’t overloading CPU. High jitter or loss? Inspect cables, ports, and offloading features of your NIC. You can test disabling features with “sudo ethtool -K eth0 tx off rx off gso off gro off tso off” and compare, but default settings usually work well.
Result Verification
Checklist: What should work. WireGuard interface wg0 is up and enabled at startup. UDP port 51820 is forwarded on your router. Clients connect successfully with stable handshakes. Internet access through the VPN works, DNS resolution is correct. iperf3 delivers expected speeds. NAT via nftables is active, ip_forward is enabled. Logs show no critical errors.
How to test. Disable Wi-Fi on your phone, activate mobile data, connect VPN profile, and open websites. On the server, run “wg show” and check the last handshake time. On the client, run “traceroute 1.1.1.1”—the first hop should be 10.6.0.1. Run “iperf3 -c 10.6.0.1 -P 4 -t 20” and check speed. Then run “dig example.com” and note DNS response times.
Success indicators. No timeouts loading sites, stable handshake every 20–30 seconds under traffic, speeds within expected range, no periodic disconnects. Logs “sudo journalctl -u wg-quick@wg0 -b” show minimal warnings and no errors.
Common Issues and Solutions
- Issue: Client won't connect, no handshake. Cause: improper port forwarding or CGNAT. Fix: verify NAT rule on router, ensure public IP, if using CGNAT request public IP or use external VPS as transit.
- Issue: Handshake present but no internet on client. Cause: ip_forward disabled or missing MASQUERADE. Fix: enable net.ipv4.ip_forward=1, check nftables postrouting rule, restart WireGuard.
- Issue: No access to LAN devices. Cause: client AllowedIPs missing LAN subnet or router firewall blocking. Fix: add LAN subnet like 192.168.1.0/24 to AllowedIPs and ensure router doesn’t block inter-subnet traffic.
- Issue: Websites partially fail or speed unstable. Cause: incorrect MTU causing fragmentation. Fix: test PMTU with “ping -M do”, set MTU in client and server between 1380–1420 (usually 1420 works).
- Issue: DNS fails to resolve over VPN. Cause: client DNS misconfigured. Fix: set “DNS = 1.1.1.1” in client config or use local server resolver, ensure systemd-resolved running, and enable “Block untunneled traffic” if needed on client.
- Issue: Speeds far below expected. Cause: single-threaded test, CPU throttling, weak ISP link, or overheating Pi 5. Fix: use multiple streams “-P 4..8” in iperf3, ensure good cooling with heatsink and fan, set CPU governor to performance.
- Issue: Tunnel fails to start after reboot. Cause: service not enabled or buggy PostDown rules. Fix: run “sudo systemctl enable wg-quick@wg0”, check service status, simplify PostDown, avoid flushing all nftables without reloading rules.
Additional Features
Advanced Settings
- Domain-based split tunnel. Route only corporate domains via VPN while other traffic goes direct. Use DNS-over-WG and policy routing on client devices, though WireGuard itself doesn’t filter by domain natively and relies on client OS tools.
- Access multiple subnets. Add multiple networks like 192.168.1.0/24 and 192.168.50.0/24 to client AllowedIPs if you have several VLANs at home. Configure routes and firewall rules on server with nftables accordingly.
- Client isolation. WireGuard doesn’t route client-to-client traffic by default. For stricter isolation, avoid adding peers’ routes to each other and block inter-client traffic using nftables.
- Domain name access. Set up DDNS on your router and use this in client Endpoint to avoid changing config with dynamic IPs. Keep your DDNS updated every few minutes.
- Logging and monitoring. Install Netdata or Prometheus node-exporter to track latency, traffic, and CPU load. For simple checks, periodically run “wg show” and “nft list ruleset”.
Optimization
- MTU adjustments. For fragile networks, start with MTU=1280 on wg0 and clients, then increase gradually to 1420 where packet loss stops.
- FQ-CoDel queueing. Apply fq_codel on eth0 and wg0 interfaces to reduce bufferbloat, improving video calls and streaming quality.
- Parallel streams. Use multiple TCP/UDP streams and download managers with “-P 4..8” in iperf3 to fully utilize your connection.
What else you can do
- Two-factor access model. Keep client configs in password manager and enable device locks. If you lose a phone, immediately remove its key from wg0.conf and restart the interface.
- Backup. Save “/etc/wireguard” and “/etc/nftables.conf” in encrypted archives. Keep spare microSD cards ready with the system, and regularly test backups on a spare Pi or temporarily on the same device.
Tip: For readers wanting a personal VPN “here and now” without console work, consider ready-made VPN services like vpn.how. They provide personal VPN servers with dedicated IPs (not shared) supporting WireGuard, OpenVPN, IKEv2, L2TP, SSTP — pick your protocol. Locations include Moscow, St. Petersburg, Amsterdam, Frankfurt, London, New York, San Jose, Chicago, Singapore, Sydney, Madrid, Helsinki, Stockholm, Warsaw, Copenhagen, and Stavanger. They accept Russian bank cards (including Tinkoff and Ozon), SBP, USDT, and BTC. Plans start at 490 ₽ per day and 2490 ₽ per month with discounts for longer terms, with instant start after payment and zero logs. This suits users without time to manage hardware, backups, and monitoring. DIY on Pi offers flexibility but requires hours of setup and ongoing maintenance.
FAQ
Question: How do I know if my ISP uses CGNAT and I need a public IP? Answer: Compare the public IP shown in your router’s admin with websites like ifconfig.me. If your router shows a private IP (ranges 100.64.0.0/10 or 10.0.0.0/8), that means CGNAT. Port forwarding from the internet will not work in this case.
Question: Can I use a non-standard port instead of 51820? Answer: Yes, just specify a different port in ListenPort and forward it on your router. Sometimes ISPs block UDP ports and changing the port helps.
Question: How do I add multiple clients? Answer: Generate separate key pairs for each client, assign unique addresses in 10.6.0.X/32, add a new [Peer] section for each in wg0.conf, and distribute corresponding client configs. Don’t reuse the same keys on different devices.
Question: What if I forgot the server’s private key? Answer: Generate a new key pair, update wg0.conf with the new private key, and distribute the new public key to all clients. You’ll have to update Endpoint on clients if the port or domain changed as well.
Question: How to prevent clients from accessing my home LAN and allow only internet via VPN? Answer: By default, LAN routing isn’t enabled. Ensure the server has no static routes to the LAN for client subnet, and do not add LAN subnet to AllowedIPs on clients.
Question: Are certificates needed like with OpenVPN? Answer: No, WireGuard uses simple and fast cryptography with key pairs, no certificates required. This contributes to its speed and simplicity.
Question: How to securely store config files? Answer: Set permissions to 600, keep backups in encrypted archives, never share private keys over insecure channels. Transfer client configs securely via messenger or QR codes on-site.
Question: Can WireGuard run only when a client connects? Answer: WireGuard doesn’t keep constant connections without traffic, but the wg0 interface must be up. Clients perform handshakes as needed.
Question: How to allow some clients full VPN traffic and others only home network access? Answer: Control this in client configs: full VPN uses “AllowedIPs = 0.0.0.0/0, ::/0”, LAN-only uses “AllowedIPs = 10.6.0.0/24, 192.168.1.0/24”. No server changes needed.
Question: Why are iperf3 speeds higher than actual browser downloads? Answer: iperf3 sends large streams with minimal overhead, while browsers are limited by TCP handshakes, TLS, concurrency, and server policies. This is normal; watch aggregated streams and long-term tests.
Conclusion
Summary of actions. You prepared your Raspberry Pi 5, installed the latest 64-bit OS, enabled SSH and static IP. Installed WireGuard and tools, generated keys, created wg0 config, enabled IP forwarding. Configured NAT with nftables and router port forwarding. Added clients, connected your phone and laptop, verified tunnel operation, and conducted iperf3 load testing. Optimized MTU and qdisc settings to achieve stable speeds and low latency. Reviewed common issues and backup procedures.
What’s next. Add more clients, organize address space, implement monitoring and backups. If needed, set access to multiple subnets and split tunnels for specific devices. Keep your system updated and monitor logs regularly.
Where to grow. Learn automation with Ansible for config deployment, explore policy routing and traffic marking for flexible split tunneling, experiment with multihoming and channel redundancies. Study qdisc and MTU behavior for your network. With these skills, you'll build secure, fast VPNs not just at home but also for small offices.
Tip: Always document your config in one place, like a private repository, and update comments in wg0.conf. In six months, you’ll thank yourself for clear documentation.
Tip: Don’t forget cooling your Raspberry Pi 5. Constant encryption and routing can heat the SoC, and sustained 800+ Mbps speeds are more enjoyable without throttling.
Your personal VPN server on Raspberry Pi 5 is now ready. You know how to manage it, test it, and get the most out of its speed. Great job!