Blocking IP addresses using Firewalld rhel 7.0

Latest response

Is there a way to block a specific ip address in firewalld ?

I know it can be done in iptables, however I would like to use the firewalld service.


I'm getting up to speed myself, so - please keep that in mind ;-)

From what I can gather, this activity is considered a "rich-rule"

firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='' reject"

Check here (Under "Actions"):

Thanks very much it seems simple enough.


Hello, see also Configuring Complex Firewall Rules with the "Rich Language" Syntax in the Red Hat Enterprise Linux Security Guide.

Just to add a side question.... Can you add the ip or range to the "blocked" or "drop" firewalld zone? No because interfaces are not active on those zones.

Great info, thanks for sharing!

I just added the following to the drop zone and it worked without any issue:

firewall-cmd --zone=drop --add-source=x.x.x.x/xx

replace x.x.x.x with the IP and you can add the subnet under /xx

Could you please let me know, How we can allow specific IP address's for SSH and Mysql? No one can access SSH and Mysql except allowed IP.

you could also use /etc/hosts.allow to only allow access via a certain IP list/hostnames eq

# System Administration
sshd:                   10.10. 10.12. 10.1.61. 10.25.

Thank's Jonathan, for a quick reply. I have done this using IPTABLES. I have also used hosts. allow and hosts.deny for the same but hosts. allow/hosts. deny doesn't restrict MySQL traffic. As we aware Firewalld service has been introduced and I want to use Firewalld service as IPTABLES does. I also want to know for the knowledge purpose.

it would be greatly appreciated if you could provide an answer for the same.

you should be able to add the mysql service(port 3306) to the firewall then allow only certain ip addresses access

# firewall-cmd --zone=public --add-service=mysql --permanent
# firewall-cmd --add-rich-rule 'rule family="ipv4" source address="your_IP_or_IP_Range" service name="mysql" accept' --permanent
firewall-cmd --add-rich-rule 'rule family="ipv4" source address="" service name="ssh" accept' --permanent

[root@localhost ~]# firewall-cmd --zone=public --list-all

public (active)

target: default

icmp-block-inversion: no

interfaces: eno16777736


services: dhcpv6-client ssh mysql



masquerade: no




rich rules: rule family="ipv4" source address="" service name="ssh" accept

I tried the same rule for SSH but it's not working. I am able to access SSH from other IPs. I think for SSH I need to use hosts.allow. If you have any idea to allow specific IP address for SSH in firewalld. Please share.

Thank you so much for paying attention towards this.


Looking at the output of your command, ssh is in both the services: section, and the rich rules section. I think the services section will allow ssh to be accepted everywhere the public zone applies.

If you want ssh to only be accepted from, remove ssh from the services:

firewall-cmd --remove-service=ssh --permanent



I find that adding an IP to the drop zone works just fine, despite the numerous warnings above stating otherwise. Try it for yourself:

firewall-cmd --zone=drop --add-source=10.x.x.x

Perhaps in more complex situations with multiple interfaces it is not recommended?

What is still elusive to me is how to block an existing connection. I set up a ping from one server to another. After adding the above rule (or a rich rule - it behaves the same), the pings continue to be allowed, presumably because they are an existing connection. See this for more info:

So the only way to stop an existing TCP session would seem to have the originator pause the 'attack' so firewalld can block it, or reboot your server?

What is still elusive to me is how to block an existing connection.

The existing connection is in conntrack, so matches the RELATED,ESTABLISHED rule rather than the later port or IP-based allow/deny rules.

One way is to find the connection in conntrack and delete it:

Another way is to match the connection as a direct rule somewhere very early in netfilter such as raw PREROUTING and drop it there. Once the connection times out of conntrack then you can remove that rule.

Both of these will still leave the local socket open as far as the application and kernel are concerned. If you need to end a TCP session like that, you can add a direct rule to match the connection in filter OUTPUT and jump to the -j REJECT --reject-with tcp-reset which will cause the firewall to send a TCP Reset back to the local application, terminating the local session.

Firewalld will check the source address in the following order:

if [source address assigned to a zone] 
      the rules for that zone apply.
elif [network interface assigned to a zone] 
      the rules for that zone apply. 
      the default zone rules apply.