Last active
May 10, 2025 14:17
-
-
Save tsjk/65e48537d715fa2bba069ddfafbeffd6 to your computer and use it in GitHub Desktop.
Fix of WireGuard routing confusion on OpenWRT
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# Intermittently, the routing of WireGuard datagrams seem to become confused, leading to temporarily hung connections. | |
# This script aims to remedy this - assuming that the OpenWRT system is a | |
# WireGuard peer that uses the port(s) listed in WG_PORTS. E.g. (/etc/config/network): | |
# config interface 'wg0' | |
# option proto 'wireguard' | |
# option listen_port '51820' | |
# ... | |
# | |
# This script can be included in /etc/firewall by e.g (assuming it is placed at /etc/wireguard/openwrt-wg0-firewall.sh): | |
# config include 'wireguard' | |
# option path '/etc/wireguard/openwrt-wg0-firewall.sh' | |
# option reload '1' | |
WAN_DEVICE=`ifstatus wan 2> /dev/null | jsonfilter -e '@["device"]'` | |
WAN_IP_ADDRESS=`ifstatus wan 2> /dev/null | jsonfilter -e '@["ipv4-address"][0].address'` | |
WAN_GATEWAY=`ifstatus wan 2> /dev/null | jsonfilter -e '@["route"][0].nexthop'` | |
WG_PORTS="51820" | |
rm_wg_mark_rules() { | |
t="mangle"; c="OUTPUT" | |
x=`iptables -t ${t} -n -v --line-numbers -L ${c} | awk '/\/\* wg0:'"${1}"' \*\// { print $1 }' | head -n 1` | |
while echo "${x}" | grep -q -E '^[1-9][0-9]*$'; do | |
iptables -t ${t} -D ${c} ${x} > /dev/null 2>&1 | |
x=`iptables -t ${t} -n -v --line-numbers -L ${c} | awk '/\/\* wg0:'"${1}"' \*\// { print $1 }' | head -n 1`; done | |
} | |
add_wg_mark_rules() { | |
echo "${1}" | grep -q -E '^[1-9][0-9]*$' || return 1 | |
t="mangle"; c="OUTPUT" | |
iptables -t ${t} -I ${c} 1 -m udp -p udp --sport ${1} -m set ! --match-set iana_ipv4_special_registry dst \ | |
-m comment --comment "wg0:${1}" -j MARK --set-mark 0x1000000/0x1000000 | |
} | |
rm_wg_rules() { | |
t="nat"; c="PREROUTING" | |
x=`iptables -t ${t} -n -v --line-numbers -L ${c} | awk '/\/\* wg0:'"${1}"' \*\// { print $1 }' | head -n 1` | |
while echo "${x}" | grep -q -E '^[1-9][0-9]*$'; do | |
iptables -t ${t} -D ${c} ${x} > /dev/null 2>&1 | |
x=`iptables -t ${t} -n -v --line-numbers -L ${c} | awk '/\/\* wg0:'"${1}"' \*\// { print $1 }' | head -n 1`; done | |
} | |
add_wg_rules() { | |
echo "${1}" | grep -q -E '^[1-9][0-9]*$' || return 1 | |
t="nat"; c="PREROUTING" | |
iptables -t ${t} -I ${c} 1 -i ${WAN_DEVICE} -d ${WAN_IP_ADDRESS} -p udp --dport ${1} \ | |
-m comment --comment "wg0:${1}" -j ACCEPT > /dev/null 2>&1 | |
} | |
if [ -s /etc/iana-ipv4-special-registry.txt ]; then | |
if ipset -L iana_ipv4_special_registry > /dev/null 2>&1; then | |
ipset -F iana_ipv4_special_registry | |
else | |
ipset -N iana_ipv4_special_registry nethash | |
fi | |
# curl -s 'https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.txt' | \ | |
# grep -Po '(?<=^ )[0-9]+(\.[0-9]+){3}/[0-9]+(?=\s)' | iprange --optimize > /etc/iana-ipv4-special-registry.txt | |
cat /etc/iana-ipv4-special-registry.txt | while read -r REPLY; do ipset -A iana_ipv4_special_registry ${REPLY}; done | |
fi | |
if [ -n "${WAN_GATEWAY}" ] && ipset -L iana_ipv4_special_registry > /dev/null 2>&1; then | |
ip route flush table 101 > /dev/null 2>&1; ip route add default via ${WAN_GATEWAY} table 101 | |
ip rule del fwmark 0x1000000 table 101 prio 11 > /dev/null 2>&1; ip rule add fwmark 0x1000000 table 101 prio 11 | |
rm_wg_mark_rules | |
for p in ${WG_PORTS}; do | |
add_wg_mark_rules ${p} | |
done | |
fi | |
# This is not strictly necessary for remedying the hung connection problem, but helps | |
# if DMZ is set on the router and one wants to exclude WireGuard traffic from hitting the DMZ box. | |
if [ -n "${WAN_DEVICE}" -a -n "${WAN_IP_ADDRESS}" ]; then | |
rm_wg_rules ${p} | |
for p in ${WG_PORTS}; do | |
add_wg_rules ${p} | |
done | |
conntrack -F > /dev/null 2>&1 | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment