WireGuard extras

If you want to manage VPN settings and view VPN status using web interface. Install the necessary packages.

# Install packages
luci-proto-wireguard qrencode
service rpcd restart
  • Navigate to LuCI → Network → Interfaces to configure WireGuard.
  • Navigate to LuCI → Status → WireGuard to view WireGuard status.

No current VPN providers have a Luci app for OpenWrt that acts like their OS-specific desktop, laptop & mobile VPN clients. Those apps can dynamically pull VPN server info, and connect on an as-needed basis, to the closest/fastest VPN server, or other preferences you have (example). When moving your VPN client connection from your individual devices to the router, you must initially make your own (wireguard) interface(s) on the router. ( ProtonVPN examples: see here, and here ). However, since individual VPN servers can go down for maintenance, or have other issues, and you would otherwise lose the oversight, redundancy and error-checking provided by using a direct client-based app, one way to improve the conditions at the router, is to have a boot script periodically checking your VPN profile for connectivity. If the check fails, it either addresses the basic wan connectivity, if that failed, or if that is ok, it tries bringing up each VPN profile, one at a time. If none of them are able to connect, it logs that information so you can take corrective action.

ABOUT
This script is an upgraded version of the script here, and was originally built from it, adding VPN, then options for SQM and CAKE-AUTORATE, on top of devices that have a cell modem, particularly Quectel devices that seem to have firmware stability issues, but are also one of the most common devices. Sierra Wireless modem support was added later.

  • GENERICWAN support (fiber/ethernet) was recently added to the modem_reset section of the script (see changelog). Since this script originated as a cell modem watchdog script, that feature, of supporting a generic WAN connection (for instance, into a fiber bridge) had been accidentally excluded. If your WAN link goes down, the 'modem_reset' function in the script, has a GENERICWAN section at the top, now, and is configured to do an 'ifup' on your wan link (equivalent of ifdown && ifup). If you want/need more functionality, you can add it to that section, and, if needed, borrow from the other modem sections to make an 'advanced reset' for your situation.

REQUIREMENTS and PREREQUISITES

  • Set all values in the script to match your actual values: e.g. wan, qmi, wwan0, /dev/cdc-wdm0, etc. See the instructions in the script for instructions. Save the script as /root/wan-watchdog.sh. Do chmod +x wan-watchdog.sh.
  • This script requires the fping and, for cellular modems, the socat package. Add to your build image, or use the built-in software manager (apk/opkg).
  • Functions of Cake-Autorate/SQM auto-management are disabled by default in the script, as they require OpenWRT SQM guide (luci-app-sqm) and cake-autorate installation. Cake-Autorate provides automatic bandwidth and other adjustments for variable-bandwidth WAN connections (Cell) compensation-optimization, beyond and on top of, SQM.
    • SQM can significantly increase router CPU requirements, and SQM requires the firewall's Flow-Offloading option to be set to Software, not Hardware. See this chart for benchmark results that will be similar to the router performance requirements with SQM Cake enabled: https://github.com/cyyself/wg-bench
  • Generic WAN connections, and, for cellular modems, plain QMI and plain MBIM are supported. Not tested on other methods of cell modem WWAN protocols. ModemManager's additional built-in auto-management routines would interfere with this script. Quectel devices seem to have hard-lock issues after a few minutes of uptime, if the MTU (through QMI, MBIM or ModemManager) is set, but if un-set, plain QMI seems quite stable. This script evolved from a cell modem router watch-dog script, incorporating VPN aspects later.
  • fping tests both IPv4 & IPv6, in that order, and will report failure if either fails. Therefore, if you are using the VPN option, your VPN must support IPv4 & IPv6, or, you can modify the check_fping function in the script to only test what you have (e.g. IPv4-only).
    • Change the IPv4 & 6 sites, preferably to your ISP's DNS servers. The script has them set for Verizon.
  • VPN Option Requires: Setting up 4 VPN interfaces
    • Make sure each VPN works, by itself, individually. Here is a set-up guide: Wireguard on OpenWrt guide. Uncheck 'Bring up on boot' for each VPN interface.
    • Modify the variable declarations in the script to match your VPN interfaces (e.g. protonvpn, protonvpn2, protonvpn3, protonvpn4).
    • If you are here for the cellular and other aspects and not using a VPN, simply leave the default values.
    • Set VPN=“0” if you do not want VPN support with this script (e.g. only other functions, qmi/wwan0/WAN connectivity-checking).
  • Script's BOOTWAIT time is pre-set to 5 seconds in this example, for testing purposes from the shell, and so as long as the value is low, the script is in testing mode and never reboots your device. The script will run-once, then exit (not loop), and NOT REBOOT, even if there is a connectivity failure, until you set BOOTWAIT to 45 or more. Only do so, when you have manually run this script and it works. When you are ready, execute '/root/wan-watchdog.sh &' and it will run in the background, then you can exit the shell. If you've modified the rc.local as described below, it will be called at next boot.
    • If the script is run as ./wan-watchdog.sh test, that will over-ride the BOOTWAIT timer, and run it immediately in test mode. This way, as you prepare to put it into production, or make changes, you are not constantly editing the script and changing the BOOTWAIT value, to toggle it in and out of testing mode.
    • Another new feature was added, that if the script runs in test mode, logging will go to /root/wwatch.log.
    • Run this script until you have no errors. Only then increase the BOOTWAIT time to move it out of Test Mode.

Click Here for the script (hidden by default)

Preserve default route to restore WAN connectivity when VPN is disconnected.

# Preserve default route
uci set network.wan.metric="1024"
uci commit network
service network restart

Periodically re-resolve inactive peer hostnames for VPN peers with dynamic IP addresses.

# Periodically re-resolve inactive peers
cat << "EOF" >> /etc/crontabs/root
* * * * * /usr/bin/wireguard_watchdog
EOF
uci set system.@system[0].cronloglevel="9"
uci commit system
service cron restart

Resolve the race condition with sysntpd service when RTC is missing.

# Resolve race conditions
cat << "EOF" >> /etc/crontabs/root
* * * * * date -s 2030-01-01; service sysntpd restart
EOF
uci set system.@system[0].cronloglevel="9"
uci commit system
service cron restart

Implement plain routing between server side LAN and client side LAN assuming that:

  • 192.168.1.0/24 - server side LAN
  • 192.168.2.0/24 - client side LAN

Add route to client side LAN on VPN server.

uci set network.wgclient.route_allowed_ips="1"
uci add_list network.wgclient.allowed_ips="192.168.2.0/24"
uci commit network
service network restart

Add route to server side LAN on VPN client.

uci set network.wgserver.route_allowed_ips="1"
uci add_list network.wgserver.allowed_ips="192.168.1.0/24"
uci commit network
service network restart

Consider VPN network as private and assign VPN interface to LAN zone on VPN client.

uci del_list firewall.wan.network="vpn"
uci add_list firewall.lan.network="vpn"
uci commit firewall
service firewall restart

Provide IPv6 site-to-site connectivity assuming that:

  • fd00:0:0:1::/64 - server side LAN
  • fd00:0:0:2::/64 - client side LAN

Add route to client side LAN on VPN server.

uci set network.lan.ip6assign="64"
uci set network.lan.ip6hint="1"
uci set network.vpn.ip6prefix="fd00::/48"
uci add_list network.wgclient.allowed_ips="fd00:0:0:2::/64"
uci commit network
service network restart

Add route to server side LAN on VPN client.

uci set network.lan.ip6assign="64"
uci set network.lan.ip6hint="2"
uci set network.vpn.ip6prefix="fd00::/48"
uci add_list network.wgserver.allowed_ips="fd00:0:0:1::/64"
uci commit network
service network restart

If you do not need to route all traffic to VPN. Disable gateway redirection on VPN client.

uci del_list network.wgserver.allowed_ips="0.0.0.0/0"
uci del_list network.wgserver.allowed_ips="::/0"
uci commit network
service network restart

If you want to disable automatic routes for allowed IPs.

uci -q delete network.wgserver.route_allowed_ips
uci commit network
service network restart

If VPN gateway is separate from your LAN gateway. Implement plain routing between LAN and VPN networks assuming that:

  • 192.168.1.0/24 - LAN network
  • 192.168.1.2/24 - VPN gateway
  • 192.168.9.0/24 - VPN network

Add port forwarding for VPN server on LAN gateway.

uci -q delete firewall.wg
uci set firewall.wg="redirect"
uci set firewall.wg.name="Redirect-WireGuard"
uci set firewall.wg.src="wan"
uci set firewall.wg.src_dport="51820"
uci set firewall.wg.dest="lan"
uci set firewall.wg.dest_ip="192.168.1.2"
uci set firewall.wg.family="ipv4"
uci set firewall.wg.proto="udp"
uci set firewall.wg.target="DNAT"
uci commit firewall
service firewall restart

Add route to VPN network via VPN gateway on LAN gateway.

uci -q delete network.vpn
uci set network.vpn="route"
uci set network.vpn.interface="lan"
uci set network.vpn.target="192.168.9.0/24"
uci set network.vpn.gateway="192.168.1.2"
uci commit network
service network restart

Set up IPv6 tunnel broker or use IPv6 NAT or NPT if necessary.

Disable ISP prefix delegation to prevent IPv6 leaks on VPN client.

Serve DNS for VPN clients on OpenWrt server when using point-to-point topology.

Route DNS over VPN to prevent DNS leaks on VPN client.

Replace peer DNS with public or VPN-specific DNS provider on OpenWrt client.

Modify the VPN connection using NetworkManager on Linux desktop client.

nmcli connection modify id VPN_CON \
ipv4.dns-search ~. ipv4.dns-priority -50 \
ipv6.dns-search ~. ipv6.dns-priority -50

Prevent traffic leaks on OpenWrt client isolating VPN interface in a separate firewall zone.

uci -q delete firewall.vpn
uci set firewall.vpn="zone"
uci set firewall.vpn.name="vpn"
uci set firewall.vpn.input="REJECT"
uci set firewall.vpn.output="ACCEPT"
uci set firewall.vpn.forward="REJECT"
uci set firewall.vpn.masq="1"
uci set firewall.vpn.mtu_fix="1"
uci add_list firewall.vpn.network="vpn"
uci del_list firewall.wan.network="vpn"
uci -q delete firewall.@forwarding[0]
uci set firewall.lan_vpn="forwarding"
uci set firewall.lan_vpn.src="lan"
uci set firewall.lan_vpn.dest="vpn"
uci commit firewall
service firewall restart

Set up multi-client VPN server. Generate client keys and profiles. Configure VPN peers.

# Configuration parameters
VPN_IDS="wgserver wgclient wglaptop wgmobile"
VPN_PKI="."
VPN_IF="vpn"
VPN_PORT="$(uci -q get network.${VPN_IF}.listen_port)"
read -r VPN_ADDR VPN_ADDR6 \
< <(uci -q get network.${VPN_IF}.addresses)
 
# Fetch server address
NET_FQDN="$(uci -q get ddns.@service[0].lookup_host)"
. /lib/functions/network.sh
network_flush_cache
network_find_wan NET_IF
network_get_ipaddr NET_ADDR "${NET_IF}"
if [ -n "${NET_FQDN}" ]
then VPN_SERV="${NET_FQDN}"
else VPN_SERV="${NET_ADDR}"
fi
 
# Generate client keys
umask go=
mkdir -p ${VPN_PKI}
for VPN_ID in ${VPN_IDS#* }
do
wg genkey \
| tee ${VPN_PKI}/${VPN_ID}.key \
| wg pubkey > ${VPN_PKI}/${VPN_ID}.pub
wg genpsk > ${VPN_PKI}/${VPN_ID}.psk
done
 
# Generate client profiles
VPN_SFX="1"
for VPN_ID in ${VPN_IDS#* }
do
let VPN_SFX++
cat << EOF > ${VPN_PKI}/${VPN_ID}.conf
[Interface]
PrivateKey = $(cat ${VPN_PKI}/${VPN_ID}.key)
Address = ${VPN_ADDR%.*}.${VPN_SFX}/24
Address = ${VPN_ADDR6%:*}:${VPN_SFX}/64
DNS = ${VPN_ADDR%/*}
DNS = ${VPN_ADDR6%/*}
[Peer]
PublicKey = $(cat ${VPN_PKI}/${VPN_IDS%% *}.pub)
PresharedKey = $(cat ${VPN_PKI}/${VPN_ID}.psk)
PersistentKeepalive = 25
Endpoint = ${VPN_SERV}:${VPN_PORT}
AllowedIPs = 0.0.0.0/0
AllowedIPs = ::/0
EOF
done
ls ${VPN_PKI}/*.conf
 
# Back up client profiles
cat << EOF >> /etc/sysupgrade.conf
$(pwd ${VPN_PKI})
EOF
 
# Add VPN peers
VPN_SFX="1"
for VPN_ID in ${VPN_IDS#* }
do
let VPN_SFX++
uci -q delete network.${VPN_ID}
uci set network.${VPN_ID}="wireguard_${VPN_IF}"
uci set network.${VPN_ID}.description="${VPN_ID}"
uci set network.${VPN_ID}.private_key="$(cat ${VPN_PKI}/${VPN_ID}.key)"
uci set network.${VPN_ID}.public_key="$(cat ${VPN_PKI}/${VPN_ID}.pub)"
uci set network.${VPN_ID}.preshared_key="$(cat ${VPN_PKI}/${VPN_ID}.psk)"
uci add_list network.${VPN_ID}.allowed_ips="${VPN_ADDR%.*}.${VPN_SFX}/32"
uci add_list network.${VPN_ID}.allowed_ips="${VPN_ADDR6%:*}:${VPN_SFX}/128"
done
uci commit network
service network restart

Perform OpenWrt backup. Extract client profiles from the archive and import them to your clients.

Automated VPN server installation and client profiles generation.

URL="https://openwrt.org/_export/code/docs/guide-user/services/vpn/wireguard/server"
cat << EOF > wireguard-server.sh
$(wget -U "" -O - "${URL}?codeblock=0")
$(wget -U "" -O - "${URL}?codeblock=1")
$(wget -U "" -O - "${URL}?codeblock=2")
$(wget -U "" -O - "${URL}?codeblock=3")
$(wget -U "" -O - "${URL}/../extras?codeblock=15")
EOF
sh wireguard-server.sh
This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies
  • Last modified: 2026/04/04 18:23
  • by s2s2