Why run WireGuard on an OpenWrt router?

Deploying WireGuard directly on an OpenWrt router provides a single, high-performance VPN gateway for all devices on a network. Compared with per-client setups, a router-level WireGuard instance centralizes routing, conserves device resources, and enables simple site-to-site connectivity. For webmasters, system administrators, and developers, this approach reduces management overhead and enables advanced policies such as split tunneling, per-subnet routing, and persistent static IPs for services.

Prerequisites and environment

Before starting, ensure you have:

  • An OpenWrt device with sufficient kernel support (OpenWrt 19.07+ or any recent 21.x/22.x build). Most modern builds include kmod-wireguard and wireguard-tools in the package feed.
  • SSH access to the router and an administrative account.
  • Basic familiarity with UCI (Unified Configuration Interface) or LuCI network editor.
  • Public IPv4/IPv6 address on the WAN side if you plan to accept incoming WireGuard connections from remote peers.

Install WireGuard packages

Install the core packages via opkg. You can use LuCI to install packages or do it over SSH. The minimal set is:

  • kmod-wireguard — kernel module (if not built-in)
  • wireguard-tools — wg, wg-quick utilities
  • luci-app-wireguard (optional) — GUI for managing WireGuard peers and interfaces
  • luci-proto-wireguard (optional) — integrates WireGuard into the Interface menu

Command example via SSH: opkg update && opkg install kmod-wireguard wireguard-tools luci-app-wireguard luci-proto-wireguard. If kmod-wireguard is unavailable for your kernel, use an OpenWrt image that includes it or upgrade the firmware.

Key generation and cryptographic basics

WireGuard uses Curve25519 keypairs. Generate keys on the router or offline (preferable for security). On the router:

Generate a private key: wg genkey > /etc/wireguard/server_private.key

Generate public key from the private: cat /etc/wireguard/server_private.key | wg pubkey > /etc/wireguard/server_public.key

For each peer (client or site), repeat the process to produce a peer_private.key and peer_public.key. Keep private keys confidential and back them up securely.

Network interface configuration (UCI)

On OpenWrt the recommended approach is to use the network configuration to define a WireGuard interface. The configuration below shows a typical server-like interface that hands out addresses to peers (static addressing per peer):

  • Define a new interface in /etc/config/network:

    config interface ‘wg0’
        option proto ‘wireguard’
        option private_key ‘[server private key]
        option listen_port ‘51820’
        option mtu ‘1420’
        list addresses ‘10.200.200.1/24’

    The mtu 1420 value is a common starting point to avoid fragmentation when encapsulating over UDP; tune as needed for your path MTU.

  • Add peers with UCI blocks:

    config wireguard_wg0 ‘peer_alice’
        option public_key ‘[alice public key]
        option description ‘alice-phone’
        option allowed_ips ‘10.200.200.2/32’

    You can also add a persistent_keepalive value: option persistent_keepalive ’25’ for NAT traversal.

Firewall and NAT configuration

WireGuard interfaces must be attached to firewall zones so traffic can flow between LAN, WAN and the VPN. A typical setup:

  • Create a zone for the VPN in /etc/config/firewall:

    config zone
        option name ‘wgzone’
        option network ‘wg0’
        option input ‘REJECT’
        option output ‘ACCEPT’
        option forward ‘REJECT’

    Then allow forwarding from wgzone to lan (or wan) depending on your policy:

    config forwarding
        option src ‘wgzone’
        option dest ‘lan’

  • Enable masquerading if you want remote peers to use the router’s public IP for internet access:

    config zone
        option name ‘wan’
        option masq ‘1’

    Or specify a SNAT rule if you prefer finer control. Be clear about routing semantics: if only internal resources are needed, avoid NAT for end-to-end visibility.

  • Open the WireGuard UDP port in the firewall for incoming connections:

    config rule
        option name ‘Allow-WireGuard-UDP’
        option proto ‘udp’
        option dest_port ‘51820’
        option target ‘ACCEPT’
        option family ‘ipv4’

Peer configuration and AllowedIPs

AllowedIPs is the key routing control. For a client that should receive a single IP and route all traffic through the VPN, set AllowedIPs to the client’s /32 and 0.0.0.0/0 (if client-side config points route to server). There are two common patterns:

  • Site/host-specific routing: On the server, set AllowedIPs to the peer’s specific subnet like 10.200.200.2/32 so the server knows to route packets for that IP to the peer.
  • Full-tunnel client policy: Configure the client AllowedIPs to 0.0.0.0/0 (and ::/0 for IPv6) so the client sends all traffic to the server; on the server no special AllowedIPs are needed besides the client’s assigned IP to accept the peer.

Be explicit: mistaken AllowedIPs can create asymmetric routing or leak traffic.

Bring up the interface and test

After editing UCI, reload the network and firewall:

  • /etc/init.d/network restart
  • /etc/init.d/firewall restart

Check the WireGuard status with wg show. It should display the interface, listen port, public key, and any handshake times for peers. Troubleshoot common issues:

  • If there’s no handshake, verify the WAN firewall allows UDP/51820 and that NAT/firewall on any intermediate gateway forwards the port.
  • Check that the peer’s public key matches the server-side config and vice versa.
  • Confirm the assigned IPs are unique and not conflicting with LAN subnets.

Performance tuning and advanced tips

WireGuard is lean, but to maximize throughput consider:

  • MTU tuning: Start with MTU 1420 on wg0; if you experience fragmentation, test smaller values. For mobile networks or double-NAT paths, lower MTU may be necessary.
  • MSS clamping: Enable TCP MSS clamping on the firewall to avoid path MTU issues: in firewall zone rules set ‘option mss_clamp’ where supported, or add a custom iptables mangle rule to clamp MSS to 1360-1400.
  • CPU offload: WireGuard runs in kernel so it’s already efficient, but on low-end routers, CPU is the bottleneck. Consider hardware with a faster SoC or enable hardware crypto acceleration if available.
  • Concurrency: Avoid excessive peers on very low-powered devices. Each handshake and per-peer crypto costs CPU.
  • Use UDP port mapping: If you host behind CGNAT, consider using a VPS as a relay or use a few seconds persistent keepalive to maintain NAT mappings.

Security considerations

WireGuard’s design is minimal and secure, but you should still enforce best practices:

  • Rotate keys periodically for sensitive deployments.
  • Restrict firewall rules to the minimum necessary; do not bridge wg0 into a trusted LAN without ACLs.
  • Use persistent-keepalive for clients behind NAT only as needed (typical value 25 seconds).
  • Monitor handshakes and traffic with wg show or system monitoring tools to detect unusual activity.

IPv6 and dual-stack setups

WireGuard supports IPv6 natively. Assign IPv6 addresses to wg0 (for example fd86:ea04:1111::1/64) and add corresponding allowed-ips for peers. Remember to permit IPv6 forwarding and open the firewall for IPv6 UDP ports. If your WAN has native IPv6, exposing IPv6 for WireGuard can simplify NAT traversal.

Troubleshooting checklist

  • No handshake: ensure UDP port is reachable and public keys match.
  • Packets reach server but no response: check local route table and firewall FORWARD rules.
  • DNS leaks: configure clients to use the router’s DNS (dnsmasq) or a privacy DNS server over the tunnel.
  • Performance drops: profile CPU and check kernel messages (logread / dmesg) for crypto errors.

Automating and managing peers

For production use, maintain a small inventory file with peer public keys, allowed IPs, and descriptions. LuCI’s WireGuard app simplifies adding and removing peers. For even larger setups, consider orchestration with scripts that generate configs and push them to clients, or integrate with a configuration management tool.

Summary and next steps

Running WireGuard on OpenWrt provides a fast, secure, and maintainable VPN gateway. The key steps are installing the correct packages, generating and protecting keys, correctly configuring the network interface and firewall, and carefully setting AllowedIPs to control routing. Pay attention to MTU and CPU limits when tuning for performance. Once stable, you can extend the setup to site-to-site tunnels, dynamic DNS for mobile peers, or integrate with network monitoring and logging.

For more advanced tutorials, configuration examples, and managed static-IP VPN guides, visit Dedicated-IP-VPN at https://dedicated-ip-vpn.com/.