Last updated: March 22, 2026

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:


Prerequisites

Before you begin, make sure you have the following ready:

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:

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

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.