Table of Contents
Router Requirements
Not every router can run a VPN. you need one with custom firmware support or a VPN-capable chipset.
Supported options:
| Option | Notes |
|---|---|
| OpenWrt-compatible routers | GL.iNet, Linksys WRT series, many TP-Link models |
| GL.iNet routers | WireGuard built into stock firmware |
| pfSense/OPNsense boxes | PC-based, most capable |
| Asus Merlin firmware | Supports OpenVPN and WireGuard on Asus routers |
Check openwrt.org/toh for hardware compatibility before buying.
Minimum specs for WireGuard:
- 128MB RAM
- 16MB flash
- MIPS or ARM CPU (ARM preferred for speed)
Prerequisites
Before you begin, make sure you have the following ready:
- A computer running macOS, Linux, or Windows
- Terminal or command-line access
- Administrator or sudo privileges (for system-level changes)
- A stable internet connection for downloading tools
Step 1 - Flash OpenWrt (if needed)
Check your router model at https://openwrt.org/toh
Download the correct factory image for your model
Access router admin → Firmware upgrade
Upload the OpenWrt factory image
Wait 3-5 minutes. do not power off
After reboot, SSH in:
ssh root@192.168.1.1
Default - no password, set one immediately:
passwd
Step 2 - Install WireGuard on OpenWrt
SSH into your router
ssh root@192.168.1.1
Update package list and install WireGuard
opkg update
opkg install wireguard-tools luci-app-wireguard kmod-wireguard
Generate router's WireGuard keys
wg genkey | tee /etc/wireguard/router_private.key | wg pubkey > /etc/wireguard/router_public.key
chmod 600 /etc/wireguard/router_private.key
Display keys
echo "Private - $(cat /etc/wireguard/router_private.key)"
echo "Public: $(cat /etc/wireguard/router_public.key)"
Step 3 - Configure WireGuard Client (Connecting to VPN Provider)
This example uses Mullvad, but works with any WireGuard VPN provider. Download your provider’s WireGuard config file and extract the values.
Create WireGuard interface config
cat > /etc/config/network_wg << 'EOF'
Values from your VPN provider's WireGuard config
PRIVATE_KEY="your_private_key_here"
SERVER_PUBKEY="server_public_key_here"
SERVER_ENDPOINT="1.2.3.4:51820"
ALLOWED_IPS="0.0.0.0/0"
DNS="10.64.0.1"
CLIENT_ADDRESS="10.68.x.x/32"
EOF
Configure via UCI (OpenWrt config system):
Add WireGuard interface
uci set network.wg0=interface
uci set network.wg0.proto=wireguard
uci set network.wg0.private_key="$(cat /etc/wireguard/router_private.key)"
uci set network.wg0.addresses="10.68.x.x/32"
Add VPN peer (your provider's server)
uci add network wireguard_wg0
uci set network.@wireguard_wg0[-1].public_key="SERVER_PUBLIC_KEY"
uci set network.@wireguard_wg0[-1].endpoint_host="1.2.3.4"
uci set network.@wireguard_wg0[-1].endpoint_port="51820"
uci set network.@wireguard_wg0[-1].route_allowed_ips="1"
uci set network.@wireguard_wg0[-1].allowed_ips="0.0.0.0/0"
uci set network.@wireguard_wg0[-1].persistent_keepalive="25"
uci commit network
/etc/init.d/network restart
Step 4 - Configure Firewall and Routing
Add WireGuard interface to WAN firewall zone
uci add_list firewall.@zone[1].network="wg0"
uci commit firewall
Create routing table for VPN traffic
cat >> /etc/iproute2/rt_tables << 'EOF'
100 vpn
EOF
Route all LAN traffic through VPN
cat > /etc/hotplug.d/iface/30-vpn-route << 'EOF'
#!/bin/sh
if [ "$ACTION" = ifup ] && [ "$INTERFACE" = wg0 ]; then
ip rule add from 192.168.1.0/24 table vpn
ip route add default dev wg0 table vpn
fi
EOF
chmod +x /etc/hotplug.d/iface/30-vpn-route
/etc/init.d/firewall restart
Step 5 - Verify the VPN Tunnel
Check WireGuard status from the router
wg show
Check the router's public IP (should be VPN server's IP)
curl -s https://am.i.mullvad.net/json
Or from any device on your network
curl https://ifconfig.me
Verify DNS isn't leaking
nslookup whoami.akamai.net
Expected output from wg show:
interface: wg0
public key: ...
private key: (hidden)
listening port: xxxxx
peer: SERVER_PUBLIC_KEY
endpoint: 1.2.3.4:51820
allowed ips: 0.0.0.0/0
latest handshake: X seconds ago
transfer: X MiB received, X MiB sent
Step 6 - Split Tunneling (Exclude Specific Devices)
You may want some devices (like a gaming console) to bypass the VPN:
Create a separate routing mark for bypass devices
Get the MAC address of the device to exclude
cat /tmp/dhcp.leases
Add iptables rule to bypass VPN for specific IP
iptables -t mangle -A PREROUTING -s 192.168.1.105 -j MARK --set-mark 1
ip rule add fwmark 1 table main
This device uses the normal WAN, others go through VPN
Step 7 - OpenVPN Fallback (Older Routers)
If your router doesn’t support WireGuard:
Install OpenVPN on OpenWrt
opkg install openvpn-openssl luci-app-openvpn
Download .ovpn config from your VPN provider
Place it in /etc/openvpn/
cp provider.ovpn /etc/openvpn/
Start OpenVPN
/etc/init.d/openvpn start
/etc/init.d/openvpn enable
OpenVPN is slower than WireGuard (especially on underpowered routers). expect 20-50% of WireGuard throughput on the same hardware.
Step 8 - Kill Switch (Prevent Traffic if VPN Drops)
Block all WAN traffic if WireGuard interface goes down
uci set firewall.@zone[1].input="REJECT"
uci set firewall.@zone[1].output="REJECT"
uci set firewall.@zone[1].forward="REJECT"
Allow only WireGuard traffic to VPN server on WAN
uci add firewall rule
uci set firewall.@rule[-1].src="lan"
uci set firewall.@rule[-1].dest="wan"
uci set firewall.@rule[-1].dest_ip="1.2.3.4"
uci set firewall.@rule[-1].proto="udp"
uci set firewall.@rule[-1].dest_port="51820"
uci set firewall.@rule[-1].target="ACCEPT"
uci commit firewall
/etc/init.d/firewall restart
Step 9 - DNS Leak Prevention
Even with the VPN tunnel active, DNS queries can bypass the tunnel and reveal your browsing activity to your ISP. This is the most common privacy failure in router VPN setups.
Force all DNS through the VPN tunnel on OpenWrt
Set the router's DNS to your VPN provider's DNS
uci set dhcp.@dnsmasq[0].server="10.64.0.1" # Mullvad DNS
uci set dhcp.@dnsmasq[0].noresolv="1"
uci commit dhcp
/etc/init.d/dnsmasq restart
Block DNS queries that try to leave on port 53 via WAN
iptables -I FORWARD -i br-lan -o wan -p udp --dport 53 -j REJECT
iptables -I FORWARD -i br-lan -o wan -p tcp --dport 53 -j REJECT
Verify there are no leaks after configuration:
From a device on your LAN, visit https://dnsleaktest.com
Or test via command line from a LAN device:
nslookup whoami.akamai.net
dig +short myip.opendns.com @resolver1.opendns.com
All answers should show the VPN server's IP, not your real IP
For providers that support DNS over HTTPS (DoH), configure it at the router level using https-dns-proxy:
opkg install https-dns-proxy luci-app-https-dns-proxy
uci set https-dns-proxy.@https-dns-proxy[0].resolver_url="https://dns.mullvad.net/dns-query"
uci commit https-dns-proxy
/etc/init.d/https-dns-proxy restart
Step 10 - Choose a VPN Provider for Router Use
Not every VPN provider works well at the router level. Key requirements:
| Requirement | Why It Matters |
|---|---|
| WireGuard support | Native performance; OpenVPN is 30-50% slower |
| Multiple simultaneous connections | Router counts as one device. all LAN devices share it |
| Port forwarding (optional) | Required for hosting services behind the VPN |
| Static IP support | Useful for allowlisting the VPN exit IP in services |
| No-logs policy (audited) | Third-party audits matter more than marketing claims |
Mullvad works well for router use: WireGuard config files downloadable per-server, audited no-logs policy, anonymous account numbers (no email required). Download the WireGuard config at mullvad.net/en/account/wireguard-config.
ProtonVPN provides WireGuard configs for router use and supports Secure Core (routing through Switzerland or Iceland before the VPN exit). The ProtonVPN app cannot be installed on a router, but the raw WireGuard config can.
IVPN is another audited option with WireGuard support and multi-hop configurations that route traffic through two VPN servers before exiting.
Avoid providers that only offer proprietary apps without WireGuard config download. those cannot be used on OpenWrt.
Performance Tuning
Router CPUs are significantly weaker than desktop CPUs. WireGuard’s ChaCha20 cipher is hardware-friendly, but you may still see throughput limitations on budget routers.
Check current WireGuard throughput
wg show wg0 transfer
Test real-world speeds via the router
SSH into router and run:
wget -O /dev/null https://speedtest.net/ # basic test
For ARM routers, enable hardware crypto acceleration if available
opkg install kmod-crypto-hw-tegra kmod-crypto-cbc
Expected throughput on common hardware:
- GL.iNet GL-AX1800 (ARM, WiFi 6): ~200 Mbps WireGuard
- GL.iNet GL-MT1300 (MIPS): ~50-80 Mbps WireGuard
- Raspberry Pi 4 as router: ~300+ Mbps WireGuard
If your ISP provides more than 200 Mbps and you have a MIPS-based router, the router CPU is your bottleneck. Either upgrade hardware or accept that the VPN limits your throughput.
Monitor router CPU during speed test
top # watch CPU usage on the router SSH session
If CPU hits 100% during transfer, hardware is the limit
For high-throughput setups, the PC-based pfSense or OPNsense approach with an AES-NI capable CPU and WireGuard provides near-wire speeds regardless of ISP bandwidth.
Step 11 - Maintaining the VPN Configuration
Router VPN configurations require periodic maintenance:
Rotate WireGuard keys periodically. Most VPN providers allow generating new keys without changing your account. Generate new keys every 3-6 months:
Generate new key pair
wg genkey | tee /etc/wireguard/new_private.key | wg pubkey > /etc/wireguard/new_public.key
Update your VPN account with the new public key
Then update the UCI config:
uci set network.wg0.private_key="$(cat /etc/wireguard/new_private.key)"
uci commit network
/etc/init.d/network restart
Check for OpenWrt security updates:
Check available package updates
opkg update && opkg list-upgradable
Upgrade all packages
opkg upgrade $(opkg list-upgradable | awk '{print $1}')
Test the kill switch after every firmware update. Firmware updates can reset firewall rules. After any OpenWrt upgrade, verify the kill switch still blocks non-VPN traffic by temporarily disabling the WireGuard interface and confirming that LAN devices lose internet access entirely.
Troubleshooting
Configuration changes not taking effect
Restart the relevant service or application after making changes. Some settings require a full system reboot. Verify the configuration file path is correct and the syntax is valid.
Permission denied errors
Run the command with sudo for system-level operations, or check that your user account has the necessary permissions. On macOS, you may need to grant terminal access in System Settings > Privacy & Security.
Connection or network-related failures
Check your internet connection and firewall settings. If using a VPN, try disconnecting temporarily to isolate the issue. Verify that the target server or service is accessible from your network.
Related Articles
- OpenWrt VPN Router Setup with WireGuard
- How to Set Up VPN on Router Firmware: Complete Guide
- How to Use WireGuard for Self-Hosted VPN in 2026
- Set Up a Personal VPN with WireGuard
- Best VPN for Linux Desktop: A Developer Guide
- AI Coding Assistant Session Data Lifecycle Built by theluckystrike. More at zovo.one
Frequently Asked Questions
How long does it take to set up a vpn on your router?
For a straightforward setup, expect 30 minutes to 2 hours depending on your familiarity with the tools involved. Complex configurations with custom requirements may take longer. Having your credentials and environment ready before starting saves significant time.
What are the most common mistakes to avoid?
The most frequent issues are skipping prerequisite steps, using outdated package versions, and not reading error messages carefully. Follow the steps in order, verify each one works before moving on, and check the official documentation if something behaves unexpectedly.
Do I need prior experience to follow this guide?
Basic familiarity with the relevant tools and command line is helpful but not strictly required. Each step is explained with context. If you get stuck, the official documentation for each tool covers fundamentals that may fill in knowledge gaps.
Is this approach secure enough for production?
The patterns shown here follow standard practices, but production deployments need additional hardening. Add rate limiting, input validation, proper secret management, and monitoring before going live. Consider a security review if your application handles sensitive user data.
Where can I get help if I run into issues?
Start with the official documentation for each tool mentioned. Stack Overflow and GitHub Issues are good next steps for specific error messages. Community forums and Discord servers for the relevant tools often have active members who can help with setup problems.