Featured image of post 🛡️ GL.iNet / OpenWrt (fw4) 网络服务避坑与排查指南

🛡️ GL.iNet / OpenWrt (fw4) 网络服务避坑与排查指南

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,因为这样很方便,网关做反代也很符合直觉,但是后面排查问题非常困难,所以我做了分离。当然,如果你只能使用路由器,单路由器的架构下,使用我这一套设置后,也不会出现防火墙放行异常的情况。

  1. 不要在路由器上跑业务:

    • 错误做法: 直接在路由器上跑 Lucky、WebDAV、Docker。
    • 后果: 受到 gl_tertf (流量统计进程) 干扰,受限于联发科网卡驱动的 GRO/GSO Bug,排查难度极高。
  2. 使用 LXC/独立服务器:

    • 正确做法: 在 NAS/PVE 上开 LXC 容器跑 Lucky。
    • 优势: 独立的 TCP/IP 协议栈,独立的公网 IPv6,不受路由器应用层干扰,端口不冲突。

三、 排查顺序 (SOP)

当遇到“外网连不上”时,请严格按此顺序操作,切勿盲目改配置。

第一步:连通性物理检查 (Ping)

目的: 确认路由器是否认识目标设备。

  • 操作: SSH 进路由器,ping -6 [目标设备IPv6]

  • 判断:

    • 如果不通:NDP 邻居表问题(PVE网桥设置或设备未上线)。
    • 如果通了但 TCP 连不上:防火墙问题(进入下一步)。

第二步:上帝视角 (Tcpdump)

目的: 确认包死在哪里。

  • 操作:

    1. 在目标设备 (LXC) 上: tcpdump -i eth0 port [7666] -n -vv
    2. 手机外网访问
  • 判断:

    • LXC 里没动静: 包被路由器拦截了(下一步)。
    • LXC 里有包但没回音: 目标设备内部防火墙(PVE Firewall)或路由表缺失。
    • 路由器抓包显示 Flags [R.] 路由器主动拒绝了连接(实锤防火墙冲突)。

四、 终极解决方案 (代码库)

防火墙暴力插队 (核心修复)

使用 nft insert 命令直接操作内核表,绕过 GL.iNet 的所有逻辑。

脚本路径/etc/firewall.user

脚本内容

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#!/bin/sh
# 强制插队放行 Lucky 端口 (TCP + UDP)
# insert index 0 确保规则在最前面执行

# 1. 转发链 (Forward): 允许外网访问 LXC
nft insert rule inet fw4 forward tcp dport 7666 counter accept #这里的7666是一个示意端口,改成你自己需要放行的端口即可,可以使用",""-"来实现多个端口放行。
nft insert rule inet fw4 forward udp dport 7666 counter accept

# 2. 入站链 (Input): 防止路由器误判为本机流量而拦截
nft insert rule inet fw4 input tcp dport 7666 counter accept
nft insert rule inet fw4 input udp dport 7666 counter accept

正确注册自定义脚本 (UCI 配置)

在 fw4 时代,必须告诉系统“这个脚本是兼容的”,否则会被忽略。

执行命令

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 1. 添加脚本路径
uci add firewall include
uci set firewall.@include[-1].path='/etc/firewall.user'
uci set firewall.@include[-1].type='script'
uci set firewall.@include[-1].enabled='1'

# 2. 【关键】标记兼容性,否则不执行
uci set firewall.@include[-1].fw4_compatible='1'

# 3. 清理可能导致报错的旧选项
uci delete firewall.@include[-1].name

# 4. 提交
uci commit firewall

清洗格式 (Windows 换行符)

如果是从 Windows 复制的代码,必须清理 \r 符号,否则 nft 命令会报错 unexpected junk

执行命令

1
2
sed -i 's/\r$//' /etc/firewall.user
chmod +x /etc/firewall.user

生效

1
/etc/init.d/firewall reload

记得直接检查端口监听

1
2
nft list chain inet fw4 forward | grep 7666
netstat -an | grep 7666#查看当前连接状态

如果 没问题的话输出应该是这样的:

1
2
3
4
5
6
root@GL-BE3600:~# nft list chain inet fw4 forward | grep 7666
                udp dport 7666 counter packets 0 bytes 0 accept
                tcp dport 7666 counter packets 0 bytes 0 accept
root@GL-BE3600:~# nft list chain inet fw4 forward | grep 7666
                udp dport 7666 counter packets 0 bytes 0 accept
                tcp dport 7666 counter packets 1394 bytes 108306 accept

五、 关键记忆点

  1. UDP 必须开: 为了 HTTP/3 (QUIC) 在弱网下的体验,防火墙规则务必同时放行 TCP 和 UDP。
  2. DDNS 选网卡: 在 LXC 里跑 Lucky,DDNS 获取方式必须选“通过网卡获取”,不要选“通过接口”。
  3. 内网走 v4,外网走 v6: 既然搬到了 LXC,内网 DNS 解析直接指向 LXC 的静态内网 IPv4,速度最快且无回环问题。
  4. 不要相信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),否则有包进来也发不回去。

使用 Hugo 构建
主题 StackJimmy 设计