This tutorial explains Firewalld Rich Rules in Linux step by step with practical examples. Learn how to query, list, add and remove rich rules in firewalld zone temporarily and permanently including rich rules ordering, rich rule timeout option and rich rules command (with argument and option) in easy language.
Firewalld Rich Rules Command
Following command is used to manage the rich rules
firewall-cmd [Option] [Rule]
Here firewall-cmd is the main command.
The Option is the type of operation which we want to perform on rule. Following table lists some common operations.
Option | Description |
--add-rich-rule='[RichRule]' | Add specified [RichRule] rule to default zone. To add rule in other zone, provide its name as argument with --zone option. To add rule permanently use --permanent option. |
--query-rich-rule='[RichRule]' | Figure out whether the specified rule is added in default zone or not. To query in other zone, provide its name with --zone option. |
--remove-rich-rule='[RichRule]' | Remove specified [RichRule] rule from default zone. To remove rule from other zone, provide its name as argument with --zone option. To remove rule permanently use --permanent option. |
--list-rich-rules | List all rules from default zone. To list rules from other zone, provide its name as argument with --zone option. |
The Rule is rich rule. Rich rule uses following syntax:-
Rule [source] [destination] {service|port|protocol|icmp-block|masquerade|forward-port} [log] [audit] [accept|reject|drop]
This tutorial is the third part of our article "How to configure Firewall in Linux Step by Step". You can read other parts of this tutorial here.
Firewalld Basic concepts Explained with Examples
This is the first part of article. This part explains basic concepts of firewalld service such as zones, services, ports and rich language including how to disable iptables service in detail with examples.
How to Configure Firewalld in Linux
This is the second part of article. This part explains how to configure firewall in Linux step by step with examples including firewall-cmd command and its options for zones, services and ports management.
Rich Rule ordering
While working with rich rules, we may create conflicting rules. For example to allow only one host from specific network usually we create following rules
- Rule A :- Deny all hosts from network
- Rule B :- Allow particular host from network
Since particular host also belongs to specific network, both rules will apply on it. From first rule it will get deny permission while from second rule it will get allow permission.
So which permission will finally apply on particular host?
Before we figure out the answer, lets understand few important rules which firewalld always follows while processing incoming packets.
- Only incoming packets are processed.
- Packets are always processed in top to down direction.
- Once a packet matches with rule, associate action (allow or deny) will be taken immediately for that packet.
- Packet will not be available for further processing.
Okay let's come back on our question. Packets arriving from particular host match with deny rule first and once the deny rule is matched, packet will be destroyed immediately. So even host has a allowed permission in second rule, packets from it will be never allowed. Proper ordering to allow a single host from network would be following :-
- Rule A :- Allow particular host network
- Rule B :- Deny all hosts from network
Thus the ordering of rules play important role in firewall. Firewalld uses following ordering :-
- Direct rules
- Port forwarding and masquerading rules
- Logging rules
- Allow rules
- Deny rules
Firewalld Rich Rules Examples
For demonstration purpose we will use following RHCE LAB. I will configure rich rules on Server system and test them from remaining systems.
To learn how to setup above RHCE Practice LAB please see this tutorial. RHCE Practice Lab Setup
Rich Rules exercise
- Allow Telnet connection only from 192.168.1.101/24. Limit this connection one per minute. Drop Telnet connection from remaining hosts.
- Allow SSH connection from network 192.168.1.0/24. Log each access with "SSH Access" prefix.
- Allow FTP connection only from 192.168.1.2/24. Reject FTP connections from remaining systems.
- Reject ping requests from all hosts with error message.
For this tutorial I assume that:-
- Telnet, SSH and FTP services are running on Server system
- The iptables service is disabled and masked
- Firewalld service is running
- There is no rich rule in default zone
We can check the status of services with following commands
systemctl status sshd systemctl status vsftpd systemctl status telnet.soket
To view the name of default zone we can use following command
firewall-cmd --get-default-zone
To view the current configuration of default zone we can use following command
firewall-cmd --list-all
As above output shows
- The name of default zone is rhcelab
- Default interface eno16777736 is associated with default zone.
- LAB network (192.168.1.0/24) is also associated with default zone.
- No services are allowed.
- No ports are opened.
- No host is configured to deny the ICMP request.
- No rich rule is configured.
Since all services and ports are blocked at this time, we should not be able to access the server with any given service (Telnet, SSH and FTP) from testing computers. At the same time ping request from all testing computers should be successful, as no host is listed in blocked list currently. Following figure verify the same from client computer (named-ipa).
Fine so far, now let's create rules for our requirements.
How to add Rich Rules
Our first requirement says "Allow Telnet connection only from 192.168.1.101/24. Limit this connection one per minute. Drop Telnet connection from remaining hosts.".
Following command will add necessary rule for this requirement
firewall-cmd --add-rich-rule='rule family=ipv4 source address=192.168.1.101/32 service name=telnet limit value=1/m accept'
Let's understand this command step by step
Command / Option/ Argument | Descriptions |
firewall-cmd | main command |
--add-rich-rule | This option tells main command that we want to perform add operation |
rule | The rule keyword represents the starting point of rule. Rules start with single quote followed by a rule keyword and end with a single quote ( ‘rule…………'). |
-s 192.168.1.101/32 | This is a filter condition which says apply the rule if packet is coming from source 192.168.1.101/24. Don't confuse with /32. It is not a subnet mask. It is a wildcard mask. In rich rules we use wildcard mask instead of subnet mask. To specify a particular host /32 wildcard mask is used. |
service name=telnet | This is also a filter condition which says apply the rule if packet is coming for telnet service |
limit value=1/m | Allow only one connection in a minute |
accept | Allow the packet if filter conditions are match. |
In easy language above command says "Let the packet pass if it is coming for telnet service from host 192.168.1.101/24".
Here I have question for you "Is this rule sufficient for first requirement? Or do we need to add one more rule which deny all hosts from network 192.168.1.0/24."
If only rich rules are going to filter the traffic then as I explained above ( in rich rule ordering section) we need one more rule to meet with first requirement.
- First rule :- Allow host 192.168.1.101/24
- Second rule :- Deny network 192.168.1.0/24
This kind of configuration is used in iptables service where rules are only the way to filter the incoming traffic.
The iptables service is the another firewall management tool like firewalld. Before RHEL 7.0 iptables was only the tool available to manage the firewall. To learn more about iptables service please see this tutorial. How to configure iptables in Linux step by step
But in firewalld service usually we use rules only to do what essential tools (Zones, Services and Ports) can't do.
As we seen in previous section all incoming traffics are filtered by default zone and default zone is configured to deny all services and ports for all hosts. We also tested the same from client computer (named-ipa). With this setup we don't need the second rule ( deny network rule) for all three services.
Okay now create rules for remaining requirements.
Following command will create rich rule for second requirement which says "Allow SSH connection from network 192.168.1.0/24. Log each access with "SSH Access" prefix"
firewall-cmd --add-rich-rule='rule family=ipv4 source address=192.168.1.0/24 service name=ssh log prefix="SSH Access" level="notice" accept'
Following command will create rich rule for third requirement (Allow FTP connection only from 192.168.1.2/24. Reject FTP connections from remaining systems.).
firewall-cmd --add-rich-rule='rule family=ipv4 source address=192.168.1.2/32 port port=21 protocol=tcp accept'
Following command will create rich rule for last requirement (Reject ping requests from all hosts with error message. ).
firewall-cmd --add-rich-rule='rule protocol value=icmp reject'
Following figure illustrates above process step by step
Listing Rich Rules
Following commands are used to list the rules
firewall-cmd --list-rich-rules firewall-cmd --list-all
First command will list only rich rules while second command will list all configuration setting including rich rules from default zone. To list rules from other zone we need to provide zone name with --zone option.
Testing Rich Rules
We have additional three systems in LAB specially setup for testing purpose. Let's test our rich rules configuration from these systems step by step.
Testing from 192.168.1.101/24 (named -win)
We have allowed telnet service from this computer while denying the rest.
Testing from 192.168.1.100/24 (named client)
For this system we allowed ssh service while denying the rest. Let's test them one by one
Testing from 192168.1.2/24 (named - ipa)
For this system we allowed ftp service and ssh service while denying the rest.
How to remove Rich Rules
To remove a rich rule --remove-rich-rule option is used. Except the operation option, same command will be used to remove the rule which we used to add the rule. For example we used following command for our last requirement (Reject ping requests from all hosts with error message. ).
firewall-cmd --add-rich-rule='rule protocol value=icmp reject'
To remove this rule replace --add-rich-rule option with --remove-rich-rule.
firewall-cmd --remove-rich-rule='rule protocol value=icmp reject'
Following figure illustrates the remove operation step by step

Rich rules timeout option
For testing and debugging purpose we can use --timeout option which will remove the rule automatically after the specified time. For examples Following rule will be automatically removed after 60 seconds
firewall-cmd --add-rich-rule='rule protocol value="icmp" reject' --timeout=60
Running configuration Vs Startup configuration
Firewalld service uses two types of configuration; running configuration and startup configuration. Startup configuration is stored in configuration files. Running configuration is stored in memory. When firewalld service starts, it reads startup configuration from configuration files and load it in memory where it is known as running configuration. Unless you make any change in running configuration it is same as the startup configuration.
Any change made in running configuration will not be available at next time when the service is reloaded. Any change made in startup configuration will not be available in current configuration, it will be available at next time when the service is reloaded.
By default firewalld service works with running configuration. So any firewall-cmd command which we execute will work in running configuration. If we want to execute the command in startup configuration, we need to add --permanent option.
In other words when we execute firewall-cmd command, firewalld service checks supplied options with command. If it finds --permanent option then it will execute the command in startup configuration. If it does not find --permanent option then it will execute the command in running configuration.
Rules added with --permanent option can only be removed with --permanent option. Rules added without --permanent option can only be removed without --permanent option.
Let's understand it with some examples
In previous section we removed one rule from running configuration, let's add it again, but this time add in startup configuration.
firewall-cmd --add-rich-rule='rule protocol value="icmp" reject' --permanent
If we list the rules with following command, will above rule will be available in list?
firewall-cmd --list-rich-rules
No because it will be added in configuration only after the reload.
Let's reload the configuration with following command
firewall-cmd --reload
Now list the rules again
firewall-cmd --list-rich-rules
This time above rule will be listed but other three rules will be removed.
Can you figure out what happened with three rules ?
Before reload, command was listing the rules which were added during the practice. Since these rules were added only in running configuration, they were vanished when the configuration was reloaded.
Now let's remove the listing rule
firewall-cmd --add-rich-rule='rule protocol value="icmp" reject'
To verify the remove operation, list the rules again
firewall-cmd --list-rich-rules
Output will confirm that rule is removed.
Now reload the firewall again
firewall-cmd --reload
list the rules again
firewall-cmd --list-rich-rules
The removed rule will appear again. Can you figure out the reason?
Because we added this rule with --permanent option while we removed this option without --permanent option. Without --permanent option rule will be removed only from running configuration. So when we reloaded the configuration, the rule loaded in running configuration from startup configuration again.
Now remove this rule again with --permanent option
firewall-cmd --add-rich-rule='rule protocol value="icmp" reject' --permanent
Reload the configuration
firewall-cmd --reload
Verify the remove operation
firewall-cmd --list-rich-rules
This time rule will be removed.
Following figure illustrates above process step by step
Reset default zone
In second part of this tutorial we created a zone named rhcelab and set it as default zone for practice. Let's delete it and set the public zone back as default zone.
Key points
- Any change made with --permanent option will not be applied in running configuration. They will be active only after the next time firewalld service is restarted or reloaded.
- Any change made without --permanent option will be applied only in running configuration. They will not be available after the next time firewalld service is restarted or reloaded.
- Incoming packets are always matched in top to bottom direction.
- Once an incoming packet matches with any rule in zone it will not be processed further. The only exception of this rule is logging rule.
- If packet doesn't meet with any rule, it will be denied. As all zones have a default denied rule in the end. The only exception of this rule is the trusted zone which has default allow rule in the end.