Fence with sign “Private: No public right of way”

Tutorial: Configuring zones bound by source IPs in FirewallD

Some network services should only be exposed to other computers on the same trusted network. Here is how you set that up with trusted zones in FirewallD for centOS, Fedora, and RHEL.

Note: I’ll demonstrates usage of both the classic firewall-cmd command as well as the newer firewallctl command line interfaces. You can compare the syntax of the two and use the one you prefer. You can also apply the concepts discussed in this tutorial from the firewall-config GUI program. Variable values will be quoted in all examples, although it’s not strictly required to quote these as used in the example commands.

You can use the predefined zones, get a complete list of the default zones by running the command firewall-cmd --list-all-zones, or create a new zone with the command firewallctl new --permanent zone --name "myownzone" or firewall-cmd --permanent --new-zone="myownzone" (avoid special characters and spaces when naming for simplicity). For this article, I’ll use the predefined zones home and public to represent a trusted and an untrusted network.


FirewallD uses zones to manage networks. You can bind a zone to a network interface or a set of source IP addresses. You can have multiple active zones, and when no zone is applicable to an incoming connection, the default zone (public) is used. Having too many active zones can impact network performance, but for many cases you’ll only need one trusted an an untrusted network.

I’ll now go through how to configure a trusted and untrusted zone step-by-step, and then demonstrate how you can add services to the two zones.

First off, add your IPv4 and IPv6 subnet(s) to your trusted zone (home). Rules in the home zone will be applied to any source IPs from these subnets.

firewallctl zone "home" --permanent add source "198.51.100.0/24"
firewallctl zone "home" --permanent add source "2001:0DB8::/32"
firewallctl reload

firewall-cmd --permanent --zone="home" --add-source="198.51.100.0/24"
firewall-cmd --permanent --zone="home" --add-source="2001:0DB8::/32"
firewall-cmd --reload

You can then verify that the zones are correctly associated with the source IP/subnets you specified by querying for information about the currently active zones:

firewallctl info zones --active

firewall-cmd --get-active-zones

You should see your source IPs listed under the desired zones.

If you try to assign the same source IPs to different zones, you’ll run into a Error: ZONE_CONFLICT error. It’s undesirable to assign the same source IPs to different zones: a network can’t be both trusted and untrusted at the same time. Instead, you’ll want to configure more granular zones with varying levels of trust for each IP address range.


Now that you’ve configured your trusted zones and bound them to your IP subnets, you’ll want to configure different service availability for your different network zones. Start by listing the services that are already associated with your zones:

firewallctl zone "home" --permanent list services
firewallctl zone "public" --permanent list services

firewall-cmd --permanent --zone="home" --list-services
firewall-cmd --permanent --zone="public" --list-services

To manage services, all you have to do is to specify which zone they belong to. For example, assuming that the SSH service is available on the public untrusted zone, and you want to make it accessible only to hosts coming from the home trusted zone:

firewallctl zone "home" --permanent add service "ssh"
firewallctl zone "public" --permanent remove service "ssh"
firewallctl reload

firewall-cmd --permanent --zone="home" --add-service="ssh"
firewall-cmd --permanent --zone="public" --remove-service="ssh"
firewall-cmd --reload

—and that is all there is too it. Configuring zones in the firewall-config GUI program can be a bit fiddly so I recommend sticking with one of the command line tools.