A few ways to configure Linux firewalld

The method for configuring Linux servers' firewalls changed with RHEL 7 and other new distributions. Learn how to set up firewalld, and what to avoid.

Initially, firewalld looks difficult to use, but it really isn't. Services and zones make it easy to put the pieces together and configure Linux firewalls.

Although it also works on the netfilter code in the Linux kernel, firewalld is totally incompatible with the old way to configure Linux firewalls. Red Hat Enterprise Linux 7 and other current distributions rely on this new method.

All examples of commands in this article are based on RHEL 7.

Firewalld works with zones

First, verify that firewalld is running. Use the command systemctl status firewalld (Listing 1).

Listing 1. This sequence shows that firewalld is active and running. Some lines were ellipsized; use -l when you try it to show them in full.

[root@rhelserver ~]# systemctl status firewalld

firewalld.service - firewalld - dynamic firewall daemon

   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled)

   Active: active (running) since Thu 2014-05-22 07:48:08 EDT; 14min ago

 Main PID: 867 (firewalld)

   CGroup: /system.slice/firewalld.service

           └─867 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid

May 22 07:48:08 rhelserver.example.com systemd[1]: Started firewalld - dynami...

Everything in firewalld relates to one or more zones.

After installation, a RHEL 7 server is normally in the public zone, but you may want to add it to another zone to easily configure firewall access. The command firewall-cmd --get-default-zone shows which zone you're in, and firewall-cmd --get-zones shows the available zones. For detailed information about the configuration of a specific zone, you can use firewall-cmd --zone=zonename --list-all (Listing 2).

Listing 2. These commands show the zone or zones in which you're setting up Linux firewalls.

root@rhelserver ~]# firewall-cmd --get-default-zone


 [root@rhelserver ~]# firewall-cmd --get-zones

block dmz drop external home internal public trusted work

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

public (default, active)

  interfaces: ens33


  services: dhcpv6-client sander ssh


  masquerade: no



  rich rules:

Changing the current zone isn't difficult: Use firewall-cmd --set-default-zone=home, for example, to change the default zone assignment from public to home.

Services and other building blocks

There are a few basic building blocks in the zones -- services are the most important. Firewalld uses its own set of services that are configured using XML files in the directories /usr/lib/firewalld/services (for the system default services) and /etc/firewalld/services for services that you, the administrator, create. To configure services, create an XML file based on the example from Listing 3.

Listing 3. An example of a configuration of firewalld services.

[root@rhelserver services]# cat ftp.xml

<?xml version="1.0" encoding="utf-8"?>



  <description>FTP is a protocol used for remote file transfer. If you plan to make your FTP server publicly available, enable this option. You need the vsftpd package installed for this option to be useful.</description>

  <port protocol="tcp" port="21"/>

  <module name="nf_conntrack_ftp"/>


Each service definition needs a short name, a description, a port section that specifies the protocol and port to be used, and a module name.

Listing 4. This example of a configuration file will create a firewalld service.

[root@rhelserver services]# cat sander.xml

<?xml version="1.0" encoding="utf-8"?>



  <description>Sander is a random service to show how service configuration works.</description>

  <port port="666" protocol="tcp"/>


Once you have the right service file, use these commands to manipulate it.

The command firewall-cmd --list-services shows a list of all services that were found on your server. To add a service, use firewall-cmd --add-service yourservice to put it into the default zone, or add --zone=zonename to choose a specific zone.

Here's how it works:

1. The command firewall-cmd --zone=public --list-all shows the current configuration of the public zone.

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

public (default, active)

  interfaces: ens33


  services: dhcpv6-client ssh


  masquerade: no



  rich rules:

2. The command firewall-cmd --zone=public --add-service=ftp adds the FTP service to the public zone in the Linux firewall.

3. Verify that the FTP service was added successfully by repeating step 1. You will see it in the list of services.

4. Restart your server and repeat step 1. You will see that the FTP service has disappeared. In firewalld, nothing is permanent unless you use the option --permanent.

5. To add FTP to the public zone and make it a permanent setting, use firewall-cmd  --permanent --zone=public --add-service=ftp. It will now survive a reboot.

6. Type firewall-cmd --reload to apply all rules and reload the firewall.

It is extremely important when working with firewalld to use the --permanent option to make settings permanent.

Breaking the rules

Services are the preferred way of configuring firewalld, easily providing a global overview of what your firewall is doing. But if you don't want to make your own service file in /etc/firewalld/service, you can add ports without them.

To assign a specific port to a specific zone, use a command like firewall-cmd --permanent --zone=dmz --add-port=22/tcp, then use firewall-cmd --zone=dmz --list-all to verify that the port was added successfully. While this is an uncomplicated way to add a port, going through services makes it easier to distribute similar rules across different hosts. Without services, files are hard to distribute, and rules in a configuration file are not that easy.

For even more control, you can -- but shouldn't -- use a direct rule. Here's why:

1. Type firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -p tcp --dport 80 -j ACCEPT.

2. Now type firewall-cdm --list-all to show the configuration for your default zone. Nothing was added that relates to port 80.

[root@rhelserver ~]# firewall-cmd --list-all

public (default, active)

  interfaces: ens33


  services: dhcpv6-client ftp ssh


  masquerade: no



  rich rules:

Nothing appears about the HTTP port you added because direct rules are writing to the iptables interface, not to firewalld.

3. To show direct rules, use firewall-cmd --direct --get-all-rules. Or use the deprecated command iptables -L instead.

Instead of direct rules, use rich rules, which are written to firewalld instead of iptables (Listing 5).

Listing 5. An example of a rich rule in Linux firewalld.

firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="" service name="tftp" log prefix="tftp" level="info" limit value="1/m" accept"

New administration features in Linux

Boot options with GRUB2

What systemd means for you

Firewalld rich rules offer a maximum amount of flexibility that is similar to what is possible on an iptables firewall.

Many things are accomplished and applied all in Listing 5's one rule. The specification of IP family, source address and services name may be obvious, but note how the rule handles logging: A specific log prefix is defined, as well as a log level info and a limit value of one message per minute. max.

The Linux administrator can apply filters that look at more than just ports, so rich rules are particularly useful to filter on IP addresses (Listing 6).

Listing 6. This rich rule applies a filter on IP addresses for the Linux firewall.

firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" \

    source address="" service name="http" accept"

Analyzing zones

The firewall-cmd command is one of many methods to configure firewalld. Alternatively, you can edit the zone configuration file directly. This doesn't give you any feedback on wrong syntax, but it's a clean and straightforward configuration file that is easy to modify and distribute across multiple servers.

Listing 7. You can configure firewalld by editing the zone configuration file.

<?xml version="1.0" encoding="utf-8"?>



  <description>For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>

  <service name="dhcpv6-client"/>

  <service name="ssh"/>

  <rule family="ipv4">

    <source address=""/>

    <service name="tftp"/>

    <log prefix="tftp" level="info">

      <limit value="1/m"/>





The example in Listing 7 includes all that was added in the previous examples, written directly to the zone configuration file, with the exception of direct rules. Direct rules have their own configuration file:

[root@rhelserver firewalld]# cat direct.xml

<?xml version="1.0" encoding="utf-8"?>


  <rule priority="0" table="filter" ipv="ipv4" chain="INPUT">-p tcp --dport 80 -j ACCEPT</rule>


Dig Deeper on Data center ops, monitoring and management

Cloud Computing
and ESG