How to block and and unblock IP addresses using FirewallD

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 rejects 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

Reference: https://serverfault.com/questions/733896/is-there-a-way-to-flush-a-whole-zones-rich-rules-on-firewalld

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

See Also

https://kb.vander.host/security/unable-to-restart-firewalld-found-left-over-process-1234567-rmmod/

How to check and remove IPs from fail2ban

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'

 

Share this article

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to Top