This article shows how firewalld priorities rules and zones. The priority of zones is in alphabetical order. So the “block” zone is checked before the “dmz” done. And within a zone, the rules are applied in the order they were added. As we know, rules are in the order they were entered. Of-course, all rules are processed within each zone from top to bottom and then the next zone is checked and the same thing happens there.
So if you want to deny all access from a subnet but allow a single address (or several address) you can but it requires a few extra commands.
Here’s an example of blocking the “10.0.0.0/24” network but allowing “10.0.0.44”.
firewall-cmd --new-zone 000-allow firewall-cmd --add-source 10.0.0.44 --zone=000-allow --permanent firewall-cmd --add-source 10.0.0.0/24 --zone=block --permanent firewall-cmd --add-service ssh --zone=public --permanent firewall-cmd --reload
The first line creates the new zone. Simple. It will not be listed in “firewall-cmd –list-all-zones” until you reload your rules with “firewall-cmd –reload”. This is the zone that we want to add source addresses to that should always be permitted.
The second line adds a new zone called “000-allow” which starts with “0” which comes before the “block” zone. Therefore anything i add to the “000-allow” zone will be processed before the “block” zone.
The third line blocks all packets coming from the “10.0.0.0/24” network because “10.0.0.0/24” is in the “block” zone. But because the “10.0.0.44” address is in the “000-allow” zone, it will have already processed and accepted the packets.
I can add as many addresses as i like (at any time) to the “000-allow” zone and they will apply before the “block” zone. It’s important to remember that by default, new zones will have a target (default rule) of “default” which will accept all packets to any address coming in on that zone. And because we’ve assigned the address “10.0.0.44” to that zone (000-allow), all traffic from that address will be accepted so there’s no reason to add services or ports to the “000-allow” zone.
Suppose we wanted to restrict “10.0.0.44” from everything except “http”. We’d do it by changing the target (default rule) from “default” or “accept” to “block”. Then we’d add the normal “accept” rule for “http”. Like this:
firewall-cmd --set-target=DROP --zone=000-allow --permanent firewall-cmd --add-service http --permanent firewall-cmd --reload
TIP: Notice “DROP” is capitalized.
Changing the target to “DROP” and adding “http” as a service will allow only the web traffic and nothing else.
We’re left with a situation where the network “10.0.0.0/24” is blocked and the IP “10.0.0.44” is permitted to only “ssh”.