Rich Rules of Firewalld on CentOS / RHEL8

Everything Linux, A.I, IT News, DataOps, Open Source and more delivered right to you.
"The best Linux newsletter on the web"

Rich-Rules – As of now we have discussed about regular zones and services syntax that firewalld offers, Administrators have more options for playing with firewall rules: Direct rules and Rich rules.

Direct rules

By using Direct Rules you are allowed to insert hand-coded {ip.ip6,eb}tables rules into the zones managed by firewalld. While powerfull, and exposing features of the kernel netfilter subsystem not exposed through other means.

These rules can be hard to manage. We will not discuss about it in this article. But Documentation is available in the firewall-cmd() and man pages.

Rich Rules:

Firewalld rich rules gives you an expressive language to writing a rule. In which you can create a custom firewall rule. That can’t be possible with basic firewalld syntax.

For example– to only allow connections to a service from a single IP address, instead of all IP addresses routed through a zone.

Rich rules can be used to express basic allow/deny rules, but can also be used to configure logging, both to syslog and auditd, as well as port forwards, masquerading, and rate limiting.

The basic syntax of a rich rule can be expressed by the following block:

[ source] 
[ destination ] 
service l port l protocol l icmp - block l masquerade l forward - port 
[ log] 
[ audit ] 
[ accept l reject l drop] 


For the full available syntax for rich rules, consult the firewalld.richlanguage(5) man page.

Ordering of rule

When you add multiple rules to a zone (or the firewall in general), then the ordering of rules can play a big role on how firewall behaves.

The basic ordering of rules inside a zone is the same for all zones:

1. Any port forwarding and masq uerading rules set for that zone.

2. Any logging rules set for that zone.

3. Any allow rules set for that zone.

4. Any deny rules set for that zone.

Direct rules are an exception. Most direct rules will be parsed before any other processing is done by firewalld, but the direct rule syntax allows an administrator to insert any rule they want anywhere in any zone.

Use of timeout in testing and debugging

To make testing and debugging easier, almost all rules can be add to the runtime configuration with a timeout.

A timeout is added to a runtime rule by adding the option: timeout=TIMEINSECONDS> to the end of the firewall-cmd that enables the rule.

Rich Rules Options

There are four options that firewall-cmd has to work with rich rules. All of these options can be used in combination with the regular – – permanent or – – zone= options.

– – add-rich-rule='<RULE>’Add to the specified zone, or the default zone if no zone
is specified.
– – remove-rich-rule='<RULE>’Remove to the specified zone, or the default zone
if no zone is specified.
– – query-rich-rule='<RULE>’Query if <RULE> has been added to the specified zone,
or the default zone if no zone is specified. Returns 0 if the rule is present. otherwise 1.
– list – rich – rulesOutputs all rich rules for the specified zone, or the default zone if no zone is specified.

Any configured rich rules are also showing in the output from firewall-cmd – – list-all and firewall-cmd – – list – all – zones.

Rich rules examples

Some examples of rich rules:

[ root@localhost -]# firewall-cmd --permanent --zone=example --add-rich-rule='rule family=ipv4 source address= reject' 

Reject all traffic from the IP address in the example zone.

When you are using source or destination with an address option, the family= option of rule must be set to either ipv4 or ipv6.

[root@serverX -]# firewall-cmd --add-rich-rule= 'rule service name=ssh limit value=2/m accept' 

Allow two new connections to ssh per minute in the default zone.
Note that this change is only make with the runtime configuration.

Drop all incoming IPsec esp protocol packets from anywhere in the default zone.


The difference between reject and drop lies in the fact that a reject will send back an ICMP packet detailing that, and why, a connection was rejecting. A drop just drops the packet and does nothing else. Normally an administrator will want to use reject for friendly and neutral networks, and drop only for hostile networks.

[root@localhost -]# firewall-cmd --permanent --zone=work --add-rich-rule= ' rule family=ipv4 source address= port port=6500-6507 protocol=tcp accept '

Accept all TCP packets on ports 6500, up to and including port 6507, in the work zone for the subnet.

Logging with rich rules

When debugging, or monitoring, a firewall, it can be useful to have a log of accepted or rejected connections. firewalld can accomplish this in two ways: by logging to syslog, or by sending messages to the kernel audit subsystem, managed by auditd.

In both cases, logging can be rate limited. Rate limiting ensures that system log files do not fill up with messages at a rate such that the system can not keep up, or fills all its disk space.

1. The syntax for logging to syslog using rich rules is:
 log [prefix="<PREFIX TEXT>" [ level=<LOGLEVEL>] [limit value="<RATE/DURATION>"] 

Where is one of emerg, alert, crit, error, warning, notice, info, or debug. can be one of s for seconds, m for minutes, h for hours, or d for days. For example, limit value=3/m will limit the log messages to a maximum of three per minute.

2. The basic syntax for logging to the audit subsystem is:
audit [limit value="<RATE/DURATION>"] 

Logging Examples

Accept new connections to http from the work zone, log new connections to syslog at the notice level, and with a maximum of three message per minute.

[root@localhost -]# firewall-cmd --permanent --zone=work --add-rich-rule= 'rule service name="http" log prefix="http" level="notice" limit value="3/m" accept 

New IPv6 connections from the subnet 2001 : db8 : : /64 in the default zone to SSH are rejected for the next five minutes, and rejected connections are logged to the audit system with a maximum of one message per hour.

[ root@localhost -]# firewall-cmd --add-rich-rule='rule family=ipv6 source address= "2001:db0::/64" service name="ssh" audit limit value="l/h" reject' --timeout=300 

In this article we have discussed about Rich Rules, use of rich rules, logging and auditing with rich rules. Hope you enjoyed this article.

Please write comment and suggestions below. Thank you.

Everything Linux, A.I, IT News, DataOps, Open Source and more delivered right to you.
"The best Linux newsletter on the web"
Unix/Linux Guru and FOSS supporter


Please enter your comment!
Please enter your name here

Latest articles

Join us on Facebook