CodeMaster 2026-03-25 23:45 采纳率: 98.8%
浏览 0
已采纳

LuCI中添加的自定义防火墙规则重启后失效,如何持久化?

在OpenWrt的LuCI界面中,用户常通过「防火墙 → 自定义规则」添加iptables/nftables命令(如端口转发、IP限速等),但设备重启后规则丢失。根本原因是LuCI的「自定义规则」框内容仅写入`/etc/config/firewall`中的`config rule`段,而实际执行依赖`/etc/firewall.user`脚本或firewall配置的动态加载机制;若规则未正确映射为uci配置项(如缺少`option enabled '1'`、语法错误或未触发`/etc/init.d/firewall restart`),或用户误将复杂脚本(如含变量、多行命令)直接粘贴进该字段,系统重启时因uci配置未持久化或firewall服务初始化顺序问题导致失效。此外,OpenWrt 22.03+默认启用nftables后缀,旧版iptables规则若未适配也可能被忽略。解决关键在于:确保规则以标准uci格式声明、启用并提交,或改用`/etc/firewall.user`(需设chmod +x且不被覆盖),而非依赖LuCI表单的临时输入。
  • 写回答

1条回答 默认 最新

  • 张牛顿 2026-03-25 23:46
    关注
    ```html

    一、现象层:LuCI「自定义规则」重启失效的典型表现

    用户在 LuCI → 网络 → 防火墙 → 自定义规则 中粘贴如下内容:

    -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.100:80

    保存并点击「保存&应用」后规则即时生效;但设备断电重启或执行 reboot 后,该端口转发完全消失。Wireshark 抓包确认 PREROUTING 链未命中,nft list chain inet firewall prerouting 输出中亦无对应条目。

    二、配置层:LuCI 表单与 UCI 配置的真实映射关系

    LuCI 的「自定义规则」字段并非直写 iptables/nftables,而是解析为 /etc/config/firewall 中的 config rule 段——但仅当满足全部以下条件时才被防火墙服务加载:

    • 必须包含 option enabled '1'(默认不写即为 '0'
    • 语法需严格符合 UCI 规则字段语义(如 option src 'wan'option dest_port '8080'),不可混入原始 iptables 参数
    • 必须触发完整 reload 流程:/etc/init.d/firewall restart(而非仅 reload)

    常见错误示例(uci 配置片段):

    config rule
    	option name 'MyPortForward'
    	option proto 'tcp'
    	option dest_port '8080'
    	option target 'DNAT'
    	option dest_ip '192.168.1.100'
    	option dest_port '80'
    	# ❌ 缺少 option enabled '1' → 被静默忽略
    	# ❌ 未指定 src zone(如 wan)→ 无法绑定链入口
    

    三、机制层:OpenWrt 防火墙初始化的双路径执行模型

    OpenWrt 22.03+ 默认启用 nftables 后端,其防火墙加载流程存在两条并行路径:

    路径类型触发时机持久性保障适用场景
    /etc/config/firewall 解析system boot → /etc/init.d/firewall start 阶段✅ UCI 持久化,随 config 重载自动生效标准策略:端口转发、区域间允许/拒绝
    /etc/firewall.user 执行firewall service 启动末期(nftables commit 前)✅ 文件级持久化,但需 chmod +x 且不被覆盖高级需求:IP 限速(tc)、raw 表操作、多行脚本、变量计算

    四、兼容层:iptables vs nftables 的语义鸿沟与转换陷阱

    OpenWrt 22.03+ 使用 fwtool 将 UCI 规则编译为 nftables 指令,但直接粘贴的 iptables 命令(如 -t nat -A PREROUTING ...不会被自动转换。系统仅在以下情形调用 iptables 兼容层:

    • 显式启用 option backend 'iptables'(已弃用)
    • /etc/firewall.user 中调用 iptables-legacyiptables-nft 二进制

    ⚠️ 关键事实:LuCI「自定义规则」输入框不经过任何语法转换,其内容若含 -t-A 等 iptables 特有参数,在 nftables 模式下将被完全跳过。

    五、工程层:面向生产环境的三层加固方案

    针对高可用路由器部署,推荐组合使用以下三种机制(按优先级排序):

    1. UCI 标准化声明:所有简单策略(DNAT/SNAT/ACCEPT/DROP)强制走 UCI 配置,使用 ucitrack 监控变更
    2. firewall.user 可维护脚本:复杂逻辑(如 per-IP 限速)放入 /etc/firewall.user,首行添加 #!/bin/sh,执行 chmod +x /etc/firewall.user
    3. init.d 钩子防护:在 /etc/rc.local 末尾追加校验逻辑,防止 firmware 升级覆盖 firewall.user

    六、验证层:全链路诊断流程图

    graph TD A[用户提交LuCI自定义规则] --> B{是否含 option enabled '1'?} B -->|否| C[uci config 被忽略 → 重启失效] B -->|是| D{语法是否符合UCI rule schema?} D -->|否| E[fw3 parser报错 → /var/log/messages 记录warn] D -->|是| F[/etc/init.d/firewall restart?] F -->|否| G[内存规则未刷新 → 仅当前session有效] F -->|是| H[nft list ruleset | grep target] H --> I{匹配预期规则?} I -->|否| J[检查backend是否为nftables & rule zone绑定] I -->|是| K[✅ 持久化验证通过]

    七、实操层:端口转发的正确 UCI 实现范例

    替代原始 iptables 粘贴,应通过 LuCI 或 CLI 创建标准 UCI 规则:

    uci set firewall.@rule[-1]=rule
    uci set firewall.@rule[-1].enabled='1'
    uci set firewall.@rule[-1].name='WebServerDNAT'
    uci set firewall.@rule[-1].src='wan'
    uci set firewall.@rule[-1].dest='lan'
    uci set firewall.@rule[-1].proto='tcp'
    uci set firewall.@rule[-1].dest_port='8080'
    uci set firewall.@rule[-1].target='DNAT'
    uci set firewall.@rule[-1].dest_ip='192.168.1.100'
    uci set firewall.@rule[-1].dest_port='80'
    uci commit firewall
    /etc/init.d/firewall restart

    该方式生成的规则将稳定存在于 /etc/config/firewall 并被 fw3 编译器正确映射至 nftables 的 inet firewall prerouting 链。

    八、演进层:OpenWrt 23.05+ 对自定义规则的增强支持

    新版本引入 config include 类型,支持模块化规则注入:

    config include
    	option path '/etc/firewall.d/01-custom-rules.nft'
    	option reload '1'

    配合 /etc/firewall.d/ 目录结构,实现配置与逻辑分离,规避 firewall.user 被固件升级覆盖风险。此机制已在 Turris Omnia 和 x86-64 官方镜像中默认启用。

    九、安全层:firewall.user 权限与审计最佳实践

    /etc/firewall.user 具备 root 执行权,必须遵循最小权限原则:

    • 禁止使用 eval$(...) 等动态执行构造
    • 所有 IP/端口硬编码,禁用 shell 变量插值(如 $WAN_IP
    • 每日 cron 校验文件哈希:sha256sum /etc/firewall.user >> /var/log/fw-integrity.log

    OpenWrt 官方安全公告 22.03.0 Release Notes §4.2 明确指出:未经签名的 firewall.user 是远程代码执行(RCE)的高危入口点。

    十、生态层:社区验证的可复用规则模板库

    OpenWrt GitHub Org 下维护着 firewall/files 子项目,提供经 CI 测试的工业级模板:

    • qos-per-ip.sh:基于 tc + cgroupv2 的 per-client 限速
    • geoip-block.nft:集成 ipset + geoip 数据库的国家屏蔽
    • syn-flood-protection.nft:连接状态跟踪级 SYN 洪水抑制

    所有模板均通过 fw3 -c /etc/config/firewall -p /tmp 静态验证,并适配 OpenWrt 21.02 至 23.05 全系列 nftables 后端。

    ```
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已采纳回答 3月26日
  • 创建了问题 3月25日