I have Asterisk installed on a CentOS 7 server that uses the Firewalld firewall. To prevent brute-force attacks, I am setting up Fail2ban to ban IP addresses that enter incorrect endpoint credentials.
When an IP address submits incorrect credential too many times, Fail2ban adds a rich rule to block the IP address:
firewall-cmd --add-rich-rule="rule family='ipv4' source address='XX.XX.XX.XX' reject type='icmp-port-unreachable'"
The rich rule is added to the firewall correctly, as I can see the rule when executing the command
firewall=cmd --info-zone=public. However, the IP address is not blocked from accessing the server. I have tested this by manually running the firewall-cmd command for one of my own IP addresses, and then attempting to register to Asterisk from a device with that IP; the device is still able to register, even though Firewalld should be blocking it.
If I restart Firewalld, or restart the SIP client, the Firewalld rule then rejects the connection attempt as it should. This makes me suspect that the issue might be related to the stateful inspection of packets, as described in the answer here: IPTables do not block IP with ipset immediately
What is the reason that Firewalld is not rejecting the connection attempts as soon as the rich rule is added? What can be done to correct its behavior?
I have found a similar question here: firewall-cmd reject destination address .
Here is the output of the
firewall-cmd --info-zone=public command after the rich rule has been added:
services: ssh sip
rule family="ipv4" source address="XX.XX.XX.XX" reject type="icmp-port-unreachable"
UPDATE: I believe the problem may be due to the
RELATED setting in iptables.
We pass it the value of ESTABLISHED to allow packets that are part of an existing connection. We pass it the value of RELATED to allow packets that are associated with an established connection. How To Set Up a Firewall Using Iptables on Ubuntu 14.04
UPDATE: The problem seems to lie with the entries in the IP tables state table. Although the UDP connections are not assigned a State, the entries do persist after the client authentication has failed. See iptstate(8) - Linux man page.