AlmaLinux 10: --direct is deprecated, move to policies
Test scope
Section titled “Test scope”An AlmaLinux 10.2 VM with firewalld 2.4.0, where three things were checked in one session:
- read the deprecation notice in
man firewalld.direct; - add one direct rule and locate its chain;
- achieve the same allow with a policy and compare.
Screenshot: public/evidence/firewalld/alma-direct-vs-policy.png.
The man page is explicit
Section titled “The man page is explicit”$ man firewalld.direct | head -14DEPRECATED The direct interface has been deprecated. It will be removed in a future release. It is superseded by policies, see firewalld.policies(5).This is not “discouraged” — it is scheduled for removal, and the named replacement is policies.
Where a direct rule lands
Section titled “Where a direct rule lands”$ firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 \ -p tcp --dport 9999 -j ACCEPTsuccess$ firewall-cmd --reload$ firewall-cmd --direct --get-all-rulesipv4 filter INPUT 0 -p tcp --dport 9999 -j ACCEPTIn nft it becomes a rule inside a chain literally named INPUT:
$ nft list ruleset | grep -B4 "dport 9999" | grep chain chain INPUT {That chain belongs to no zone. Direct rules therefore bypass zone semantics: no default policy, no logging, no rich-rule conditions — only raw iptables syntax and ordering.
A minimal policy
Section titled “A minimal policy”# 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=labpolicylabpolicy (active) target: ACCEPT ingress-zones: public egress-zones: HOST ports: 9997/tcpIt gets its own chain:
$ nft list ruleset | grep -B3 "dport 9997" | grep chain chain filter_IN_policy_labpolicy_allow {Policies say “from which zone, to which zone, allow what” — precisely the semantics direct rules lack.

Choosing between the three
Section titled “Choosing between the three”| Mechanism | Scope | Status | Use for |
|---|---|---|---|
--direct | no zone, nft chain INPUT | deprecated | legacy only |
| rich rule | inside one zone | supported | source-based rules, logging, rate limits |
| policy | zone-to-zone or zone-to-HOST | supported, recommended | host-wide policy, forwarding, containers |
Migration mapping
Section titled “Migration mapping”| direct | policy |
|---|---|
--direct --add-rule ipv4 filter INPUT 0 -p tcp --dport 9999 -j ACCEPT | --policy X --add-port 9997/tcp --set-target ACCEPT |
-s 10.0.0.0/24 -j ACCEPT | --add-source 10.0.0.0/24 |
-j DROP | --set-target DROP |
-m limit --limit 10/m | rich rule limit value="10/m" |
Common traps
Section titled “Common traps”--add-ingress-zone anyfails: measuredINVALID_ZONE: Policy 'labpolicy': 'any' not among existing zones; use a real zone such aspublic;--permanentwithout reload: nothing appears in nft and the policy may stay inactive;- Overly broad targets:
--set-target ACCEPTallows everything in that zone pair and can override the zone’s default deny; - Assuming reload wipes direct rules: permanent direct rules survive, which is exactly why legacy hosts stay messy.
Practice: migrate one rule
Section titled “Practice: migrate one rule”sudo firewall-cmd --direct --get-all-rulessudo firewall-cmd --permanent --new-policy lab9997sudo firewall-cmd --permanent --policy lab9997 --add-ingress-zone publicsudo firewall-cmd --permanent --policy lab9997 --add-egress-zone HOSTsudo firewall-cmd --permanent --policy lab9997 --add-port 9997/tcpsudo firewall-cmd --permanent --policy lab9997 --set-target ACCEPTsudo firewall-cmd --reloadsudo firewall-cmd --info-policy=lab9997Checks:
--info-policyshows the intended ingress, egress and ports;nft list ruleset | grep 9997finds the allow;- Removing the original direct rule changes nothing;
- Clean up with
--delete-policy=lab9997.
常见问题
Does --direct still work?
Yes on EL10, firewalld still implements it, but the man page states it will be removed; do not use it for new configuration.
How do policies relate to zones?
Zones describe interface trust levels; policies describe what is allowed between a zone pair (or a zone and HOST). They complement each other.
Which one for container forwarding?
Policies: ingress/egress zones plus a target match forwarding and podman networking semantics exactly.
Next steps
Section titled “Next steps”- nftables backend: /en/firewall-backend-nftables/
- Rich rules: /en/firewalld-rich-rules/
- Zones: /en/firewalld-zones/