前言
近期在配置 Lucky 内置的 STUN 内网穿透功能时,我遇到了穿透始终无法成功的问题。排查后发现根源在于 OpenClash 启用的 Fake‑IP 模式对 STUN 造成了干扰。本文给出基于 nftables 的有效绕行方案,帮助你快速恢复 STUN。
环境要求
- 系统:基于 nftables 的固件(如 ImmortalWrt / OpenWrt 22.03+)。
- 已启用 OpenClash,模式为 Fake‑IP。
- Lucky(含 STUN 内网穿透模块)。
操作步骤
- 进入 OpenClash → 插件设置 → 开发者选项。
- 在“防火墙自定义规则”粘贴以下脚本并保存应用:
#!/bin/sh
. /usr/share/openclash/log.sh
. /lib/functions.sh
LOG_OUT "Tip: Start Add Integrated Bypass Rules..."
sleep 5
if nft list ruleset | grep -q "chain openclash_mangle"; then
# 针对所有内网设备,强制 3478 端口不走代理
nft insert rule inet fw4 openclash tcp dport 3478 counter return
nft insert rule inet fw4 openclash_output tcp dport 3478 counter return
nft insert rule inet fw4 openclash_mangle udp dport 3478 counter return
nft insert rule inet fw4 openclash_mangle_output udp dport 3478 counter return
# IPv6 STUN 绕过
nft insert rule inet fw4 openclash_mangle_v6 udp dport 3478 counter return 2>/dev/null
nft insert rule inet fw4 openclash_mangle_output_v6 udp dport 3478 counter return 2>/dev/null
LOG_OUT "OpenClash: Port 3478 bypass applied."
fi
exit 0
为什么要绕行 3478?
STUN 默认使用 UDP 3478 端口。Fake‑IP/透明代理会对未知流量进行劫持,导致 STUN 握手失败或回环。将 3478 在 openclash 与 mangle 链上 return,可确保报文直连内外网服务器;同时补充 IPv6 以避免双栈不一致。
验证步骤
- 在 Lucky 查看 STUN 状态是否转为
Connected。 - 抓包确认 3478 报文不再进入 Clash 进程。
- 如仍失败,重启 OpenClash 与防火墙(或整机)后重试。
注意事项与回滚
- 若你自定义了端口,记得将 3478 替换为实际 STUN 端口。
- 如需回滚,删除上述
nft insert rule相关行或在相同链位点delete rule。 - 某些老旧固件(iptables)需改写为 iptables 语法,或升级到支持 nftables 的版本。