Table of Contents
What is FirewallD?
FirewallD (Firewall Daemon) is a nice alternative to iptables
but still uses iptables
behind the scenes. Yet it’s much simpler and easier to understand and configure. If you’re running Virtualmin on either Ubuntu or CentOS, your system will be configured to use FirewallD by default. For an alternative that’s even easier, check out ufw
.
Here are some common actions that you may perform using FirewallD.
Block an IP Address Using FirewallD
To block an IP address using FirewallD, do the following:
firewall-cmd --add-rich-rule="rule family=ipv4 source address=A.B.C.D reject" --permanent
This will create an entry to permanently ban the IP address. To make it effective, unfortunately you have to reload the firewalld commands:
firewall-cmd --reload
Since the firewall-cmd
syntax is awkward and reloading even more awkward (compared to UFW), here is a short bash script to get you out of a bind. It takes the first parameter and reject
s the address
.
cat block.sh #!/bin/bash # Usage: sh block.sh IP_ADDRESS firewall-cmd --add-rich-rule="rule family=ipv4 source address=$1 reject" --permanent firewall-cmd --reload
FirewallD often works in conjunction with Fail2ban. When you’re mitigating an active attack on a server, be sure to observe /var/log/fail2ban.log
for repeat entries already banned
. If you’re getting a lot of these it’s very clear that Fail2ban isn’t working properly with FirewallD. We don’t have an exact fix but most of the time it seems doing firewall-cmd --reload
works. Just keep on monitoring the file though and keep on using the above script, in my cases this solves the problem.
To check if a FirewallD rule is there
firewall-cmd --list-all
How to remove a Rich Text Rule
service firewalld start firewall-cmd --remove-rich-rule='rule family=ipv4 source address=10.x.x.x reject' --permanent service firewalld restart
How to remove all Rich Text Rules
Edit the file /etc/firewalld/zones/public.xml
How to whitelist an IP address
First determine the zone. Public is often used. If you’re unsure, do firewall-cmd --list-all
`
# firewall-cmd --get-zones FirewallD is not running root@host:~# service firewalld start root@host:~# firewall-cmd --get-zones block dmz drop external home internal public trusted work
Output to make sure it’s public:
# firewall-cmd --list-all public target: default icmp-block-inversion: no interfaces: sources: services: dhcpv6-client dns dns-over-tls ftp http https imap imaps mdns pop3 pop3s smtp smtp-submission smtps ssh ports: 20/tcp 2222/tcp 10000-10100/tcp 20000/tcp 49152-65535/tcp protocols: forward: yes masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: rule family="ipv4" source address="a.b.c.d" reject rule family="ipv4" source address="e.f.g.h" reject
Whitelist the IP address:
root@host:~# firewall-cmd --zone=public --add-source=i.j.k.l --permanent success root@host:~# firewall-cmd --reload success
If you firewall-cmd –list-all you will see it in sources:
# firewall-cmd --list-all public (active) ... sources: i.j.k.l services: ...
Creating Restricted Zones
When you want to quickly ban everyone from HTTP and HTTPS do this:
firewall-cmd --permanent --new-zone=restricted firewall-cmd --permanent --zone=restricted --add-source=a.b.c.d/32 firewall-cmd --permanent --zone=restricted --add-service=http firewall-cmd --permanent --zone=restricted --add-service=https firewall-cmd --permanent --zone=restricted --add-port=10000-10100/tcp firewall-cmd --permanent --zone=public --remove-service=http firewall-cmd --permanent --zone=public --remove-service=https firewall-cmd --reload
Note the caveat, you will have to open all ports for your IP(s).
Troubleshooting with Fail2ban
We’ve created this troubleshooting section for folks using FirewallD and Fail2ban. These two tools often work together – Fail2ban scans log files for breach attempts, then sends them off to FirewallD to be blocked.
Excessive “already banned” messages
Periodically review /var/log/fail2ban.log
. If you see excessive “already banned” messages in the log file, that means FirewallD hasn’t successfully implemented the rule that was sent via Fail2ban. Our remedy is to restart either fail2ban or firewalld. This is not ideal but at least it will get you about moving on with your day.
service fail2ban restart service firewalld restart
When restarting the services, keep observing the fail2ban.log
file using tail
to see if the messages are subsiding. One theory is that fail2ban and firewalld has trouble keeping up with log file rotation. In our opinion it’s just firewalld that’s buggy, but in spite of it’s flaws you’ll still need it. We haven’t observed the same issues with UFW.
Removing rich text rule not working when using Fail2ban
In some situation rules might have been dynamically added by Fail2ban, in which case you can’t just remove them with --remove-rich-rule
as the system doesn’t consider them permanent. In that case, use the command below:
fail2ban-client set sshd unbanip a.b.c.d
Block and Unblocking SSH on non-default Ports
If you’ve changed your default SSH port to something other than 22, Firewalld and Fail2ban might not be able to properly detect the change. You’ll notice multiple already banned
events in the Fail2ban log file. To get this working, you have to tell FirewallD that SSH is on a non-standard port. As of 24 September 2021 we haven’t found a reliable way of doing this, but if you have any tips please leave us a comment below.
For more in-depth information, follow the references.
References
- https://www.liquidweb.com/kb/an-introduction-to-firewalld/
- https://www.tecmint.com/install-configure-firewalld-in-centos-ubuntu/
- https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-using-firewalld-on-centos-7
- http://www.linuxeveryday.com/2016/12/block-unblock-ip-address-firewalld
See Also
https://kb.vander.host/security/unable-to-restart-firewalld-found-left-over-process-1234567-rmmod/
Fail2Ban FirewallD related Errors
Below are two examples of errors output after restarting a FirewallD installation whereby FirewallD doesn’t seems to work properly afterwards with the fail2ban Postfix SASL jail. Our remedy was to restart firewalld a few times.
In the first instance, no actual error is returned but the system is indicating that something is wrong:
2022-06-11 11:52:05,635 fail2ban.utils [2822046]: ERROR 7f66dbe75170 -- exec: ipset create f2b-postfix-sasl hash:ip timeout 600 firewall-cmd --direct --add-rule ipv4 filter INPUT_direct 0 -p tcp -m multiport --dports smtp,465,submission,imap,imaps,pop3,pop3s -m set --match-set f2b-postfix-sasl src -j REJECT --reject-with icmp-port-unreachable 2022-06-11 11:52:05,636 fail2ban.utils [2822046]: ERROR 7f66dbe75170 -- stderr: "Error: COMMAND_FAILED: '/usr/sbin/iptables-restore -w -n' failed: iptables-restore: line 2 failed" 2022-06-11 11:52:05,636 fail2ban.utils [2822046]: ERROR 7f66dbe75170 -- stderr: '' 2022-06-11 11:52:05,637 fail2ban.utils [2822046]: ERROR 7f66dbe75170 -- returned 13 2022-06-11 11:52:05,637 fail2ban.actions [2822046]: ERROR Failed to execute ban jail 'postfix-sasl' action 'firewallcmd-ipset' info 'ActionInfo({'ip': '87.246.7.230', 'family': 'inet4', 'fid': <function Actions.ActionInfo.<lambda> at 0x7f66db2dfc10>, 'raw-ticket': <function Actions.ActionInfo.<lambda> at 0x7f66db2e0310>})': Error starting action Jail('postfix-sasl')/firewallcmd-ipset: 'Script error'
In the second instance, the error return is related a set that already exists. In this instance there is a good possibility that the jail is not working.
2022-06-11 11:52:06,678 fail2ban.utils [2822046]: ERROR 7f66dbe75170 -- exec: ipset create f2b-postfix-sasl hash:ip timeout 600 firewall-cmd --direct --add-rule ipv4 filter INPUT_direct 0 -p tcp -m multiport --dports smtp,465,submission,imap,imaps,pop3,pop3s -m set --match-set f2b-postfix-sasl src -j REJECT --reject-with icmp-port-unreachable 2022-06-11 11:52:06,679 fail2ban.utils [2822046]: ERROR 7f66dbe75170 -- stderr: 'ipset v7.5: Set cannot be created: set with the same name already exists' 2022-06-11 11:52:06,679 fail2ban.utils [2822046]: ERROR 7f66dbe75170 -- stderr: "Error: COMMAND_FAILED: '/usr/sbin/iptables-restore -w -n' failed: iptables-restore: line 2 failed" 2022-06-11 11:52:06,679 fail2ban.utils [2822046]: ERROR 7f66dbe75170 -- stderr: '' 2022-06-11 11:52:06,679 fail2ban.utils [2822046]: ERROR 7f66dbe75170 -- returned 13 2022-06-11 11:52:06,679 fail2ban.actions [2822046]: ERROR Failed to execute ban jail 'postfix-sasl' action 'firewallcmd-ipset' info 'ActionInfo({'ip': '5.34.207.118', 'family': 'inet4', 'fid': <function Actions.ActionInfo.<lambda> at 0x7f66db2dfc10>, 'raw-ticket': <function Actions.ActionInfo.<lambda> at 0x7f66db2e0310>})': Error starting action Jail('postfix-sasl')/firewallcmd-ipset: 'Script error'