OpenWrt PassWall2 防火墙规则不生效:先查加载,再查命中与转发
简答:OpenWrt PassWall2 防火墙规则不生效时,先确认实际后端,再分清规则未加载、存在但未命中、命中后连接失败。先保存对应规则输出;nftables 只有目标规则带 counter 才能比较计数,否则改查日志,不能判为零命中。成功判据是测试流量有对应接管证据、交付端口与监听匹配,且同一目标的新连接恢复。
定义:防火墙接管规则不生效,是指预期规则未加载、测试流量未匹配接管条件,或匹配后未正确交付代理核心;它与核心内部的域名分流不是同一层问题。
先做这三步:保留规则,判断卡在哪一层
先不要清空防火墙:确认后端、保存规则,再从发生问题的设备发起一次新连接。没有计数器不等于没有命中;看到接管链也不等于连接已经成功。本站是第三方使用指南站,不代表 PassWall2 项目。
- 在有读取权限的管理会话执行:
grep '^USE_TABLES=' /tmp/etc/passwall2/var。格式示例为USE_TABLES="nftables"或USE_TABLES="iptables",不是本文实测输出。 - 若为 nftables,先执行
nft -a list table inet passwall2;若为 iptables,使用下文与插件一致的命令选择方式。复制完整输出并保留错误信息。 - 固定一台设备、一个目标、一个协议和一个地址族,重新建立连接。目标规则有计数器时比较前后数值;没有计数器时按后文的日志分支继续,不作零命中判断。
| 观察结果 | 当前判断 | 下一步 |
|---|---|---|
| 对应表或接管入口缺失 | 可能未加载,也可能看错后端 | 核对缓存、启用范围与启动日志 |
| 目标规则有计数器,但新连接后不变 | 尚未观察到这条规则匹配测试流量 | 核对来源、接口、协议、端口和提前返回条件 |
| 目标规则没有 counter | 现有输出不足以判断命中 | 读取日志;必要时交由维护者补充诊断 |
| 接管动作计数增加,连接仍失败 | 接管路径有活动,故障可能在后续交付 | 核对监听;TPROXY 再核对策略路由 |
缓存读取位置与格式见 utils.sh:运行目录与缓存函数;列表命令、handle 与 counter 的区别见 nft 上游手册;grep 用法见 BusyBox 命令文档。本文所有外部资料访问日期均为 2026-11-10。
保存现场:先区分故障范围与版本
建议记录 OpenWrt 固件版本、PassWall2 安装包版本、实际核心及版本、后端、TCP 接管方式、IPv6 是否启用,以及主路由或旁路由拓扑。请从当前设备显示的信息记录,不套用其他固件的菜单名称。
- 全部客户端异常:先检查公共接管入口与启动过程。
- 仅路由器本机异常:单独检查 output 路径,不用局域网测试代替。
- 仅一台设备异常:先核对该设备来源地址、接口与访问控制。
- 仅一个域名异常:记录实际解析地址,暂不认定防火墙整体失效。
- 只在升级或重载后异常:保存操作前后日志与规则,避免反复重启覆盖现场。
本文以发布标签 26.11.3-1 所展示的提交 176e27c 为源码基准,固定文件链接使用完整提交哈希;对应关系可在 具体发布页 核对。这不是对你的设备进行过实测的声明,也不代表其他版本完全相同。
操作建议:先导出配置备份,另存将要修改的单个选项原值,并确保能从局域网恢复管理。对外提交资料前遮盖订阅地址、凭据和不必要的公网信息。配置备份不应被当作所有软件包或内核模块变更的完整回滚方案。
确认实际后端:不要只看系统安装了什么
基准源码会结合后端偏好、命令和 dnsmasq 能力选择运行环境,不能仅凭安装了 nft 或 iptables 就确定插件正在使用哪套规则。依据:app.sh:运行环境与依赖检查。
执行首屏的缓存读取命令后,按以下结果处理:
- 读到有效值:再查看相应规则表。缓存只是后端线索,不是加载成功证明。
- 文件不存在:可能尚未生成运行缓存或版本实现不同;保留日志,核对本机脚本,不自行创建文件。
- Permission denied:先解决读取权限,不能据此判断规则缺失。
- 没有匹配行或值为空:没有取得有效后端结论。继续结合启动日志和实际规则检查,不手工填写 USE_TABLES。
该基准在相关 ACL 条件满足、调用后端脚本之后写入后端缓存,见 app.sh:后端启动与缓存写入。因此,缓存缺失不能独立证明防火墙损坏。
nftables 检查卡:先看入口和动作,再决定能否比较计数
执行 nft -a list table inet passwall2。若指定表不存在,再执行 nft -a list ruleset 查看实际规则集,检查是否存在不同实现或是否看错后端。命令依据 nft 上游手册。
基准源码创建的基础链包括:dstnat 使用 prerouting、nat 类型及 dstnat - 1 优先级;mangle_prerouting 使用 prerouting、filter 类型及 mangle - 1;另有本机输出用的 mangle_output 和 nat_output。输出可能把优先级显示为等价数字。依据:nftables.sh:接管动作与基础链定义。
格式示例,不是实测输出:ip protocol tcp counter packets 2 bytes 120 redirect to :12345 # handle 88。这里端口、计数和 handle 均为示意值:看 packets/bytes 判断计数变化,看 redirect to 核对交付端口,不能用 handle 数字判断是否命中。基准脚本的 REDIRECT/TPROXY 动作生成函数包含 counter,但不能因此假定其他版本或每一条跳转规则都有计数器。
| 要看什么 | 符合预期时的线索 | 异常后如何处理 |
|---|---|---|
| 基础链与 hook | 存在与客户端或本机测试对应的入口 | 缺失时核对启动日志与版本,不手写补链 |
| 入口跳转 | 所选方式对应 PSW2_NAT 或 PSW2_MANGLE 等路径 | 沿入口检查,不只搜索链名称 |
| 来源与协议条件 | 规则中的地址、接口、TCP/UDP 和端口覆盖本次测试 | 纠正已证实不一致的一项配置 |
| 接管动作 | 出现对应 redirect 或 tproxy 及实际端口 | 有跳转无接管证据时继续检查后续链及提前 return |
| counter | 目标动作规则有 packets/bytes,可前后比较 | 没有 counter 时不能归类为零命中 |
接管链、入口跳转和策略路由见 nftables.sh:接管路径与路由设置;来源接口、IP 和 MAC 条件见 nftables.sh:ACL 来源条件。
没有 counter 时怎么办?
改用后文的只读日志检查,核对启动、ACL 加载和已有核心日志;日志没有记录某次连接,也不能独立证明它没有经过防火墙。如果系统原本已为测试流量启用 nftrace,可用 nft monitor trace 被动观察,按 Ctrl+C 结束;它本身不修改规则,但只显示已启用 nftrace 的报文。没有输出时不能判定未命中。启用 nftrace 通常需要另行修改规则,本文不提供默认加规则步骤;需要时将脱敏规则和日志交给维护者进一步诊断。依据:nft 手册的 COUNTER、META 与 MONITOR 说明。
iptables 检查卡:与插件选择同一个实现
基准脚本优先选择 iptables-legacy,其次选择 iptables;IPv6 同理,并对 IPv6 nat、mangle 模块作条件判断。依据:iptables.sh:命令选择与 IPv6 条件。
在同一个 shell 会话按顺序执行:
IPT=$(command -v iptables-legacy || command -v iptables)if [ -n "$IPT" ]; then "$IPT" -t nat -L -n -v -x --line-numbers; "$IPT" -t mangle -L -n -v -x --line-numbers; fi
如果找不到命令,先核对安装环境,不把无输出解释为规则为空。列表中的 pkts、bytes 是计数,target 是动作或跳转,num 是行号。参数依据:iptables 手册。
格式示例,不是实测输出:num pkts bytes target prot opt in out source destination;示意数据行 1 2 120 PSW2 tcp -- br-lan * 192.0.2.10 0.0.0.0/0。接口、地址和数字都是示意值,只有本机确实生成相同条件时才有对应意义。入口跳入 PSW2 还不等于最终接管,应继续查看该链内的 REDIRECT、TPROXY 或提前 RETURN。基准实现见 固定提交 iptables.sh。
IPv6 先确认表能读取
先执行 IP6T=$(command -v ip6tables-legacy || command -v ip6tables),再执行 if [ -n "$IP6T" ]; then "$IP6T" -t mangle -L -n -v -x; "$IP6T" -t nat -L -n -v -x; fi。分别保留每张表的正常输出或错误,再判断其中是否有相关规则。列表操作不修改规则内容,但可能触发内核加载相应模块,见 iptables 手册的 TABLES 说明。
IPv6 nat 表不存在,本身不能判定 PassWall2 故障。应结合该固件可用模块、是否启用 IPv6 接管及实际处理方式判断。nftables 分支则在 inet 表内分别核对 IPv4、IPv6 条件,不用一次 IPv4 测试替代 IPv6 验证。
三类结果对应处理:每次只修正一个已确认的问题
一、预期规则未加载:先看启用范围和启动错误
执行 cat /tmp/log/passwall2.log 保存插件日志。路径来自 utils.sh 的 LOG_FILE 定义,cat 用法见 BusyBox 文档。日志文件不存在只能说明未读到该文件,不能代替服务状态检查。
最小处理:核对当前配置是否启用了测试设备对应的客户端接管,是否存在有效 ACL;若日志明确提示缺少依赖,再按具体包名核对当前固件的软件源。不要同时更换后端、接管方式和核心。依赖检查与后端调用条件分别见 运行环境检查 和 ACL 与后端启动条件。
二、有计数器但未观察到命中:核对流量实际入口
最小处理:在测试设备核对当前地址与默认网关,再对照实际生成规则的来源地址、入口接口、协议和端口。假如设备地址已经变化,只修正对应来源条件,不为一台设备扩大整个局域网的接管范围。旁路由场景先确认该连接确实经过此路由器。
继续检查是否先匹配了直连或 RETURN 条件;本机异常则改查 output 路径。两种后端的条件生成请分别核对 nftables ACL 源条件 与 iptables ACL 实现。没有 counter 的规则不适用本小节的零命中判断。
三、接管动作有命中证据:核对监听与策略路由
先读取实际接管端口,再执行 ss -lntup,比较监听地址、端口、TCP/UDP 类型及有权限时可见的进程。命令缺失不等于没有监听;参数依据 ss 手册。若端口没有对应核心监听,先处理核心启动错误,不叠加手写防火墙规则。
TPROXY 继续读取 ip -4 rule show 与 ip -4 route show table all;IPv6 使用 ip -6 rule show 与 ip -6 route show table all。将本机实际标记、策略规则和路由表对应起来。命令依据 ip rule 手册、ip route 手册 和 ip 地址族参数说明。
基准源码使用标记 0x50535732,相关本地路由指向表 999;这只是对照线索,不是让你照抄添加策略。nftables 标记与路由见 固定提交 nftables.sh,iptables 对应实现见 固定提交 iptables.sh。REDIRECT 应优先核对重定向端口与监听,不直接套用 TPROXY 的路由判据。
怎样复测才有意义:固定条件,使用新连接
- 只选一台设备,记录其来源地址、目标及实际目标 IP,明确 TCP 或 UDP、IPv4 或 IPv6。
- 保存测试前规则和日志,不清零计数器;尽量暂停这台设备无关的后台连接。
- 关闭原测试连接,再重新发起请求。
- 保存测试后输出,只比较覆盖本次来源与目标条件的规则;其他设备或提前 RETURN 的计数变化不作为接管成功证据。
- 同时核对连接结果。共享规则计数增加只能提供相关活动线索,不能把所有增量都归因于本次测试。
使用新连接很重要:iptables 的 nat 表在创建新连接时参与处理,不能要求其计数像逐包统计那样随传输持续增长。依据:iptables 手册的 nat 表说明。nftables 的计数器仅在对应 counter 表达式被执行时更新,依据 nft 手册。
如果只有域名访问异常,建议先对照实际解析地址与规则引用的集合,不立即清空全部集合或缓存。需要继续分流时,可阅读 PassWall2 国内域名解析失败排查;需要理解错误上下文时,阅读 PassWall2 日志报错阅读方法。这里将域名异常列为排查分支,不表示已经确认故障来自 DNS。
修改、重载与回滚:保留现场后再重新生成
升级或防火墙重载后才出问题时,建议先比较前后规则,记录安装版本、旧配置是否保留、后端、接管方式和完整错误。没有相同环境和错误证据时,不套用其他用户的清理命令,也不把重复规则一概认定为同一个缺陷。
iptables 基准脚本有生成防火墙包含脚本及恢复相关规则的实现,见 iptables.sh:gen_include 恢复逻辑。仅在重载后异常时,应核对这条恢复路径与本机版本,不反复手工追加 PSW2 跳转。
完成一个有证据支持的配置修正后,若已备份、具备局域网恢复条件且允许连接中断,可执行一次 /etc/init.d/passwall2 restart,然后按相同条件建立新连接复测。基准服务脚本会先停止再启动;reload 也调用 restart,不是无中断热加载,见 固定提交服务脚本。
回滚:若单项修改没有改善,恢复该项原值,再以相同方式重新生成并复测。不要把清空全局规则集、关闭整套防火墙或删除未知链作为默认修复;例如 nft 的 flush ruleset 会清空整个规则集,依据 nft 手册。
建议按故障层级继续阅读:看不懂启动错误时先读日志指南;只有域名异常时转入 DNS 排查;接管、监听和必要策略路由已有对应证据后,再读 PassWall2 连接失败排查,不要继续反复修改防火墙。
常见问题
nft -a 显示了 handle,为什么没有 packets 和 bytes?
根据正文引用的 nft 手册,-a 用于显示 handle,不会自动为规则增加计数器。只有目标规则包含 counter 表达式时才有相应计数。没有计数器时改查日志;若系统原本已启用 nftrace,可被动观察 trace,不能把无输出认定为没有命中。
节点测试正常,为什么客户端仍不走规则?
节点测试不能替代客户端接管验证。建议从发生问题的设备建立新连接,对照其网关、来源条件和实际接管路径,再检查对应端口监听。不要只凭节点测试结果跳过防火墙检查。
nftables 和 iptables 都装了,应该检查哪套规则?
先读取 USE_TABLES 运行线索,再与实际规则交叉验证。正文固定源码包含环境选择与回退逻辑;iptables 分支还优先选择 legacy 实现,因此不能仅根据默认命令或已安装软件判断。
读取运行缓存失败,要手动创建文件吗?
不要手工创建。文件不存在、权限不足和没有匹配字段是不同结果,应分别核对启动流程、读取权限和版本实现。继续保留日志并检查实际规则,不伪造后端值。
IPv6 nat 表不存在,是否说明 PassWall2 安装坏了?
不能直接这样判断。先确认命令、模块及当前接管方式需要的路径,再检查对应 IPv6 规则。正文引用的基准脚本也对 IPv6 nat、mangle 模块作了条件判断。
规则计数增加,为什么仍然连接失败?
先确认增加的是本次测试对应的接管动作,而非其他设备或 RETURN 规则。之后核对交付端口与核心监听;TPROXY 再检查标记和策略路由。计数本身不能证明整条连接成功。
修改配置后用 reload 会不会更安全?
本文固定提交的服务脚本把 reload 转为 restart,不能视为无中断操作。先保存现场和选项原值,仅在具备本地恢复条件时重启一次,再以新连接复测;无改善则恢复该项设置。
相关阅读
参考资料
- 具体发布页:26.11.3-1 与提交标识;访问日期 2026-11-10
- 固定提交 utils.sh:目录、日志路径与缓存格式;访问日期 2026-11-10
- 固定提交 app.sh:后端选择和依赖检查;访问日期 2026-11-10
- 固定提交 app.sh:ACL 条件、后端启动和缓存写入;访问日期 2026-11-10
- 固定提交 nftables.sh:带 counter 的动作生成与基础链;访问日期 2026-11-10
- 固定提交 nftables.sh:接管链、跳转与策略路由;访问日期 2026-11-10
- 固定提交 nftables.sh:ACL 来源接口、地址与 MAC 条件;访问日期 2026-11-10
- 固定提交 nftables.sh 全文:表名、标记与完整处理分支;访问日期 2026-11-10
- 固定提交 iptables.sh:legacy 优先与 IPv6 模块判断;访问日期 2026-11-10
- 固定提交 iptables.sh 全文:PSW2 链、ACL、动作与策略路由;访问日期 2026-11-10
- 固定提交 iptables.sh:防火墙包含脚本及恢复实现;访问日期 2026-11-10
- 固定提交服务脚本:restart 和 reload 行为;访问日期 2026-11-10