OpenWrt (fw4) 网络服务避坑与排查指南
核心场景: 在路由器或下级设备(NAS/LXC)上部署 Lucky/Nginx 等服务,使用 IPv6 公网访问。典型故障: 内网正常,外网连接“转圈 -> 超时 Close”,或“用着用着断流”,Web UI 防火墙显示“已接受”但实际不通。
在我的场景下,只有GL.iNet的设备会出现这种问题。设备是BE3600,是最新版本。
本教程是笔者在部署lucky的反代服务时,路由器的防火墙死活不开,导致内网穿透断断续续后,排查后的总结,希望可以帮到你。
一、 核心矛盾:新旧防火墙的“夺权”之战
这是导致你“明明开了端口却不通”的根本原因。
1. 兼容性灾难
-
背景: OpenWrt 21.02+ 底层已全面切换为 nftables (fw4) 。
-
现状: GL.iNet 等厂商为了兼容旧代码(流量统计、云管平台、QoS),依然大量使用 iptables 指令。
-
冲突点: 系统中同时存在
fw4表(原生)和filter表(iptables兼容层)。- 优先级陷阱: 兼容层的 DROP/REJECT 规则往往被内核排在更前面。
- 欺骗性: 你在 Web UI (LuCI) 配置的规则写入了
fw4表,显示为“接受”。但数据包在进入fw4之前,就已经被 GL.iNet 的后台进程在filter表里杀掉了。
2. 避坑结论
在 GL.iNet 设备上,永远不要完全信任 Web UI 的防火墙状态。如果 Web 设置无效,必须使用 nft 命令 直接操作内核表进行“暴力插队”。
二、 最佳架构建议 (架构避坑)
原则:让路由器回归“转发”,让服务器回归“计算”。
一开始,我是使用路由器跑的lucky,因为这样很方便,网关做反代也很符合直觉,但是后面排查问题非常困难,所以我做了分离。当然,如果你只能使用路由器,单路由器的架构下,使用我这一套设置后,也不会出现防火墙放行异常的情况。
-
不要在路由器上跑业务:
- ❌ 错误做法: 直接在路由器上跑 Lucky、WebDAV、Docker。
- 后果: 受到
gl_tertf(流量统计进程) 干扰,受限于联发科网卡驱动的 GRO/GSO Bug,排查难度极高。
-
使用 LXC/独立服务器:
- ✅ 正确做法: 在 NAS/PVE 上开 LXC 容器跑 Lucky。
- 优势: 独立的 TCP/IP 协议栈,独立的公网 IPv6,不受路由器应用层干扰,端口不冲突。
三、 排查顺序 (SOP)
当遇到“外网连不上”时,请严格按此顺序操作,切勿盲目改配置。
第一步:连通性物理检查 (Ping)
目的: 确认路由器是否认识目标设备。
-
操作: SSH 进路由器,
ping -6 [目标设备IPv6]。 -
判断:
- 如果不通:NDP 邻居表问题(PVE网桥设置或设备未上线)。
- 如果通了但 TCP 连不上:防火墙问题(进入下一步)。
第二步:上帝视角 (Tcpdump)
目的: 确认包死在哪里。
-
操作:
- 在目标设备 (LXC) 上:
tcpdump -i eth0 port [7666] -n -vv - 手机外网访问。
- 在目标设备 (LXC) 上:
-
判断:
- LXC 里没动静: 包被路由器拦截了(下一步)。
- LXC 里有包但没回音: 目标设备内部防火墙(PVE Firewall)或路由表缺失。
- 路由器抓包显示
Flags [R.]: 路由器主动拒绝了连接(实锤防火墙冲突)。
四、 终极解决方案 (代码库)
防火墙暴力插队 (核心修复)
使用 nft insert 命令直接操作内核表,绕过 GL.iNet 的所有逻辑。
脚本路径:/etc/firewall.user
脚本内容:
|
|
正确注册自定义脚本 (UCI 配置)
在 fw4 时代,必须告诉系统“这个脚本是兼容的”,否则会被忽略。
执行命令:
|
|
清洗格式 (Windows 换行符)
如果是从 Windows 复制的代码,必须清理 \r 符号,否则 nft 命令会报错 unexpected junk。
执行命令:
|
|
生效
|
|
记得直接检查端口监听
|
|
如果 没问题的话输出应该是这样的:
|
|
五、 关键记忆点
- UDP 必须开: 为了 HTTP/3 (QUIC) 在弱网下的体验,防火墙规则务必同时放行 TCP 和 UDP。
- DDNS 选网卡: 在 LXC 里跑 Lucky,DDNS 获取方式必须选“通过网卡获取”,不要选“通过接口”。
- 内网走 v4,外网走 v6: 既然搬到了 LXC,内网 DNS 解析直接指向 LXC 的静态内网 IPv4,速度最快且无回环问题。
- 不要相信lucky和luci的web设置开关: 很多时候,你在这上面设置了放行,实际上根本没有写进防火墙里面。当然,在这种复杂的新旧版本共存的路由器里面才会出现这种情况。如果是纯净的设备,大可以相信web设置。
一句话总结: GL.iNet 路由器的 Web 防火墙是“君子协定”,底层的 nft insert 才是“尚方宝剑”。遇到灵异事件,直接用 nft 插队!
避坑检查清单 (Checklist)
-
不要只信 Web UI:在魔改固件上,Web 设置的“接受”可能是假的,底层可能有更高优先级的“拒绝”。
-
抓包是唯一真理:
tcpdump -i any ip6 and port 7666- 如果看到
In [S]紧接着Out [R.](Reset),说明是被路由器防火墙主动拒绝了。
-
优先使用
nft insert:在 OpenWrt 21.02+ 上,用iptables命令可能无效,必须用nft操作inet fw4表。 -
UDP 也要放行:为了支持 HTTP/3 (QUIC) 协议,提升弱网体验,防火墙规则要同时涵盖 TCP 和 UDP。
-
LXC 网络:确保 LXC 容器内有默认的 IPv6 路由 (
ip -6 route),否则有包进来也发不回去。