跳转到内容
搜索 Rocky Linux 文档

    浏览当前文档目录

    Rocky 10:direct 规则为什么该换成 policy

    Rocky Linux 10.2 虚拟机 + firewalld 2.4.0。同一次会话里做三件事:读 man 的废弃段落、加一条 direct 规则、用 policy 做等价放行,然后对比 nft 里的落点。

    截图:public/evidence/firewalld/rocky-direct-vs-policy.png。

    $ man firewalld.direct
    DEPRECATED
    The direct interface has been deprecated. It will be removed in a
    future release. It is superseded by policies, see
    firewalld.policies(5).

    「will be removed」+「superseded by policies」两句,基本决定了新配置不该再写 --direct。

    $ firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 \
    -p tcp --dport 9999 -j ACCEPT
    success
    $ firewall-cmd --reload
    $ nft list ruleset | grep -B4 "dport 9999" | grep chain
    chain INPUT {

    direct 规则进的是 chain INPUT——一条没有 zone 归属的链。后果有三:

    1. zone 的默认策略、日志、rich rule 条件都用不上;
    2. 规则顺序完全靠 priority 数字手工安排,容易压住别的规则;
    3. 排查时 firewall-cmd --list-all 看不到它,只出现在 --direct --get-all-rules 里。
    # firewall-cmd --permanent --new-policy labpolicy
    # firewall-cmd --permanent --policy labpolicy --add-ingress-zone public
    # firewall-cmd --permanent --policy labpolicy --add-egress-zone HOST
    # firewall-cmd --permanent --policy labpolicy --add-port 9997/tcp
    # firewall-cmd --permanent --policy labpolicy --set-target ACCEPT
    # firewall-cmd --reload
    $ firewall-cmd --info-policy=labpolicy
    target: ACCEPT
    ingress-zones: public
    egress-zones: HOST
    ports: 9997/tcp
    $ nft list ruleset | grep -B3 "dport 9997" | grep chain
    chain filter_IN_policy_labpolicy_allow {

    policy 有独立的链(filter_IN_policy_<name>_allow),与 zone 规则互不覆盖,语义也写进了配置本身:谁进来(ingress)、去哪(egress)、做什么(target)。

    Rocky Linux 10.2:direct → chain INPUT,policy → 独立 policy 链

    • 单机开个端口:优先 firewall-cmd --add-port(zone 内);
    • 需要源地址/日志/限速:rich rule;
    • 与转发、容器、整体策略相关:policy;
    • --direct:只用于兼容既有脚本,不作为新方案。
    1. ingress zone 不能用 any:实测报 INVALID_ZONE: 'any' not among existing zones,必须写真实 zone(如 public);
    2. policy 的 target 要慎用 ACCEPT:整段放行会盖过 zone 的默认拒绝,先确认意图;
    3. --permanent 与 runtime 要同步:只改 runtime,reload 后立刻丢失。
    • --list-all 里找不到某条放行 → 它可能在 direct 或 policy 里,分别用 --direct --get-all-rules、--list-policies 查;
    • 删除 direct 规则必须逐字一致,写错不报错(见 rich rule 那篇的同类问题);
    • policy 建了但 disable: yes 或未生效,--info-policy 会显示状态,别只看 nft 有没有链。
    Terminal window
    sudo firewall-cmd --list-policies
    sudo firewall-cmd --permanent --new-policy lab9997
    sudo firewall-cmd --permanent --policy lab9997 --add-ingress-zone public
    sudo firewall-cmd --permanent --policy lab9997 --add-egress-zone HOST
    sudo firewall-cmd --permanent --policy lab9997 --add-port 9997/tcp
    sudo firewall-cmd --permanent --policy lab9997 --set-target ACCEPT
    sudo firewall-cmd --reload
    sudo firewall-cmd --info-policy=lab9997

    检查:

    1. 策略状态为 active,ingress/egress 与预期一致;
    2. nft list ruleset | grep 9997 能匹配到放行;
    3. 移除原 direct 规则后行为不变;
    4. 收尾删除策略。

    常见问题

    policy 会不会和 zone 规则冲突?

    不会互相覆盖:它们在 nft 里是不同的链,按 hook 顺序执行;冲突一般来自 target 设得太宽。

    direct 的优先级参数还要保留吗?

    不需要。policy 通过 zone 对与 target 表达意图,不再依赖手工优先级数字。

    旧系统里的 direct.xml 怎么办?

    先导出 --direct --get-all-rules,逐条映射成 policy 或 rich rule,验证后清空 direct.xml。