缺点1:对于管理客户端流量不直观,Connections 里虽然能看到一个内网 IP 连了一个外网 IP,但还得去 DHCP 分配里查这个内网 IP 的主机名或MAC地址,可能还得上网查一下这个 MAC 地址的 vendor,才能确定这个客户端是谁;对于外网 IP 也没法跟 DNS 查询记录里的域名做关联,很不直观。
Unifi 上设置 WAN1(OpenWrt)为 Primary,WAN2(PPPoE)为 Backup,模式为Failover Only
26/02/15 补充:Unifi 上需要给 WAN1(OpenWrt)手动设置 DNS 服务器为 OpenWrt IP,不能勾选“Auto DNS”,不然Unifi 会偷偷给你塞一个1.1.1.1
Unifi 上设置策略路由:
1. 目标 Region 为 China 的都走 WAN2(不用勾 Kill Switch,没啥用且会跟下面的DNS hijack有奇妙的冲突);
2. 来自 OpenWrt 的流量都走 WAN2(避免循环,勾上Kill Switch)
OpenWrt 上和标准的路由+代理设置基本相同,WAN 为 DHCP,连接 Unifi 内网。然后要将 WAN 和 WAN6 接口高级设置中的“自动获取 DNS 服务器”禁用,并填入运营商的 DNS 地址,避免循环
效果:正常情况下,客户端的 DNS 请求先到 Unifi 的 DNS 服务器上(对于 DPI 功能有帮助),然后走 WAN1 -> OpenWrt 的无污染 DNS,解析得到国外地址继续走 OpenWrt 做代理(OpenWrt 再通过 Unifi LAN -> PPPoE 连接代理服务器),国内地址直接走 PPPoE 发出。一旦 OpenWrt 挂掉,Unifi 检测到 WAN1 不通,会自动把全部路由和 DNS 都切换到 PPPoE,实现自动降级直连
(可选)此时 Unifi 上可以再设置一个 DNS hijack,让不遵守 DHCP 下发的 DNS 服务器的设备的所有 UDP 53 端口流量都强制发到 Unifi DNS 服务器:增加 DNAT 规则,匹配来源 IP 非 OpenWrt,目标 IP 非 Unifi,目标 UDP 53,将目标 IP 改写为 Unifi 的 IP
IPv6 与 WireGuard Server 问题
按上述方案配置后,你会发现两个问题:
IPv6 不通:哪怕客户端已经具有了来自 PPPoE 的 v6 地址,但 v6 网络就是不通。这里来到了 Unifi 最逆天的地方了:除非主 WAN 断开,不然在任何情况下都试图让 IPv6 走主 WAN,哪怕主 WAN 都没配 IPv6,导致网络不通。
Unifi 上运行的 WireGuard Server 不通:哪怕 WireGuard Server 上设置了监听的是 WAN2 (PPPoE),只要主 WAN 还在,所有回包都会走主 WAN,导致外界的客户端连不上。最新的Unifi OS 5.0.12 + Network 10.1.84版本已经修复此问题
==> 对于Unifi OS 5.0.12 + Network 10.1.84或更新的版本(2026年2月):
#!/bin/sh
# ================= Configuration =================
# backup WAN Interface (real Internet, e.g. PPPoE to ISP)
IFACE="ppp1"
# Routing Table ID for backup WAN (Usually 202 for WAN2)
TABLE="202"
# WireGuard Server Listen Port
WG_PORT="16384"
# Log Tag for syslog
LOG_TAG="UniFi_Network_Fixer"
# =================================================
# Function to clean up rules on exit or restart
cleanup() {
# Remove IPv6 default route
ip -6 route del default dev "$IFACE" metric 1 2>/dev/null
# Remove Policy Routing rule based on Source Port
ip rule del sport "$WG_PORT" lookup "$TABLE" 2>/dev/null
# Remove Force-SNAT rule from NAT table
iptables -t nat -D POSTROUTING -o "$IFACE" -p udp --sport "$WG_PORT" -j MASQUERADE 2>/dev/null
}
# Run cleanup on start to ensure a clean slate
cleanup
logger -t "$LOG_TAG" "Starting network fix script..."
while true; do
# Check if the interface exists
if ip link show "$IFACE" > /dev/null 2>&1; then
# -----------------------------------------------------
# Task 1: Fix IPv6 Direct Access
# Problem: Unifi doesn't add a default IPv6 route for Secondary WAN.
# Fix: Manually add a default route to Main Table via ppp1.
# -----------------------------------------------------
HAS_V6_ROUTE=$(ip -6 route show default dev "$IFACE" metric 1)
if [ -z "$HAS_V6_ROUTE" ]; then
ip -6 route add default dev "$IFACE" metric 1
logger -t "$LOG_TAG" "IPv6: Added default route via $IFACE"
fi
# -----------------------------------------------------
# Task 2: Fix WireGuard VPN Server on Secondary WAN
# Problem: Local UDP traffic uses Primary WAN gateway & source IP.
# Fix A: Policy Routing based on Source Port (Directs traffic to WAN2 Table)
# -----------------------------------------------------
if ! ip rule show | grep -q "sport $WG_PORT lookup $TABLE"; then
# Priority 98 ensures it runs before Unifi's default rules
ip rule add sport "$WG_PORT" lookup "$TABLE" priority 98
ip route flush cache
logger -t "$LOG_TAG" "VPN: Added Policy Routing for Source Port $WG_PORT"
fi
# -----------------------------------------------------
# Fix B: Force SNAT (Masquerade)
# Problem: Source IP might be internal (e.g., 192.168.x.x) even if routed correctly.
# Fix: Force NAT on egress to ensure Source IP matches the Public IP.
# -----------------------------------------------------
if ! iptables -t nat -C POSTROUTING -o "$IFACE" -p udp --sport "$WG_PORT" -j MASQUERADE 2>/dev/null; then
# Insert at top (1) to override any conflicting rules
iptables -t nat -I POSTROUTING 1 -o "$IFACE" -p udp --sport "$WG_PORT" -j MASQUERADE
logger -t "$LOG_TAG" "VPN: Added Force-SNAT rule for port $WG_PORT"
fi
fi
# Check every 30 seconds to handle re-dials or IP changes
sleep 30
done