Red Hat FirewallD question
When ever I add the following rule to my configuration "rule family="ipv4" source address="0.0.0.0/0" reject" all connections to my server are rejected even the ones I have already opened/allowed. The rule order doesn't matter and the zone doesn't matter. Here is an example.
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0
sources:
services: dhcpv6-client
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
rule family="ipv4" source address="0.0.0.0/0" service name="ssh" accept
rule family="ipv4" source address="0.0.0.0/0" reject
I know in this rule, the final reject is not needed, but just wanted to show an example. As soon as I add that last reject rule to any configuration, all connections are rejected/blocked to the server. I even reordered them. So rule order and zone doesn't seem to make a difference.
In the above example, shouldn't it see the accept for SSH and then stop processing and never get to the reject after that.
Thanks
Responses
This happens because the firewalld input chain processes deny rules before allow rules.
I added the two rich rules as you said, then dumped the config with iptables-save:
# regular firewalld input chains
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -j INPUT_direct
-A INPUT -j INPUT_ZONES_SOURCE
-A INPUT -j INPUT_ZONES
-A INPUT_ZONES -i eth0 -j IN_public
-A INPUT_ZONES -j IN_public
# here we can see deny rules are processed first
-A IN_public -j IN_public_log
-A IN_public -j IN_public_deny
-A IN_public -j IN_public_allow
-A IN_public -j ACCEPT
# ssh service allowed in using rich rule syntax
-A IN_public_allow -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
# implicit reject using rich rule syntax
-A IN_public_deny -j REJECT --reject-with icmp-port-unreachable
I agree this is counter-intuitive. I'll log a bug against firewalld and get development's opinion.
Our firewalld maintainer (who is also the primary upstream maintainer) has some ideas. We're currently thinking to add a separate iptables/nftables chain for rich rules, and allow rich rules to be ordered like direct rules are. The specifics of that may change over time. Currently it's an early discussion.
However, such a modification would influence other behaviour changes (such as ICMP blocking) and would break existing configs, so is not a change we can make within the scope of RHEL 7. It's a change suitable for a later major RHEL release, and a later firewalld release where users are aware the rich rule specification changes.
For now, please operate with the knowledge of how firewalld and the iptables chains currently work.
If you wish to have a deny-all after an allow, then you can use direct rules (which do allow ordering) or you can use the zone's default behaviour as described on the firewall-cmd manpage under --set-target.
Thank you for raising this very good question, I'll also capture this info in a knowledgebase solution.
Welcome! Check out the Getting Started with Red Hat page for quick tours and guides for common tasks.
