FirewallD in a nutshell 101

With FirewallD, some Linux distributions introduce a new default firewall differing heavily from previous interfaces. This post focusses the basic concept and some practical examples.

A major difference is that the firewall now supports changes in realtime without dropping active connections. FirewallD integrates seamlessly into D-Bus which makes it easier for applications and services to retrieve and control firewall configurations. In additional to that, there are plenty of pre-configured zones and services which enable faster configurations.

Using the --timeout parameter it is possible to limit firewall rules from a time perspective. As an example, it is possible to create a rule that enables a service for an installation temporarily. A feature named lockdown mode can be used in order only to permit some applications to control the firewall (using D-Bus). In addition to predecessors, FirewallD integrates into Puppet and also offers a XML export for sharing firewall configurations (to be honest, I'd prefer JSON or YAML).

FirewallD is available for plenty of platforms, for example:

  • RHEL 7 and distributions based on it (CentOS, Scientific Linux)
  • Fedora 18 and newer
  • SUSE Linux Enterprise Server 15
  • optionally for Ubuntu 14.04, Debian 8, openSUSE 42.2 and newer

Basically, there is also a graphical configuration utility named firewall-config, but I will focus on the command-line utility firewall-cmd in this post.

Zones

From a FirewallD perspective, a zone is a level which defines permitted services and ports and other behaviors (such as default actions for forbidden access). There are plenty of pre-configured zones that can often be used without customizing it.

To see a list of available zones, enter the following command:

1# firewall-cmd --get-zones
2block dmz drop external home internal public trusted work

Some of the available zones have comparable behaviors - see the following comparison:

Zone Default action Characteristics Enabled services
block REJECT Only answers of outgoing requests allowed no
drop DROP Only outgoing traffic allowed
dmz keine Only enabled exceptions allowed ssh
external
public ssh, dhcpv6-client
home ssh, mdns, samba-client, dhcpv6-client
internal
work ssh, dhcpv6-client
trusted ACCEPT All traffic allowed all

From a kernel perspective, there is huge difference between REJECT and DROP. When using REJECT, the receiver will be informed that the port is not accessible. DROP on the other hand simply results in a timeout and is used in public networks (e.g. DMZ) to impede port scanning.

Enabled zones can be listed like that:

1# firewall-cmd --get-active-zones
2public
3  interfaces: ens33

Alternatively, you can also list the zone of a particular network interface:

1# firewall-cmd --get-zone-of-interface=ens33
2public

Every zone has attributes such as enabled services and ports:

 1# firewall-cmd --info-zone home
 2home (active)
 3  target: default
 4  icmp-block-inversion: no
 5  interfaces: ens33
 6  sources:
 7  services: ssh mdns samba-client dhcpv6-client
 8  ports:
 9  protocols:
10  masquerade: no
11  forward-ports:
12  source-ports:
13  icmp-blocks:
14  rich rules:

Changing the zone is possible with one command:

1# firewall-cmd --set-default-zone=home
2success

Runtime and Permanent

Basically, FirewallD supports two modes: runtime and permanent. When starting the firewall, the permanent configuration is retrieved from the file system. Pre-defined templates can be found in the /usr/lib/firewalld folder - customized templates and configurations are stored under /etc/firewalld. By default, every firewall change is made in runtime made. To change this, use the --permanent parameter.

In other words, if you plan to change the configuration in runtime and permanant mode, you will need to execute the command twice:

1# firewall-cmd --set-default-zone=home
2# firewall-cmd --set-default-zone=home --permanent

Alternatively, you can alter the permanent configuration and reload the firewall - e.g. using the following command:

1# firewall-cmd --reload

This command loads the rules into the kernel but keeps possible status information. The advantage is that opened connections are not interrupted.

Alternatively there is another parameter:

1# firewall-cmd --complete-reload

As a result, also firewall kernel modules (netfilter) are completely reloaded. This will drop active connections - it is advised only to use this if the first option is not working properly.

Services

FirewallD offers a wide range of predefined services - explore the list:

1# firewall-cmd --get-services
2RH-Satellite-6 amanda-client amanda-k5-client ...

Additional information for service definitions are shown by using the --info-service parameter:

1# firewall-cmd --info-service RH-Satellite-6
2RH-Satellite-6
3  ports: 80/tcp 443/tcp 5646-5647/tcp 5671/tcp 8140/tcp 8080/tcp 9090/tcp
4  protocols:
5  source-ports:
6  modules:
7  destination:

To add a service to a zone, utilize the --add-service parameter:

1# firewall-cmd --zone=home --add-service=ssh

Of course, there is also an opposite parameter:

1# firewall-cmd --zone=public --remove-service=http

Ports

Beside services, also particular ports can be opened - for example like that:

1# firewall-cmd --zone=home --add-port=6667/tcp

After changing the configuration, ports can be listed with the --list-ports parameter:

1# firewall-cmd --zone=home --list-ports
26667/tcp

Again, here is also an opposite parameter for removing the port:

1# firewall-cmd --zone=home --remove-port=6667/tcp --permanent

Conclusion

Using Enterprise Linux, managing firewall rules is way easier with FirewallD than it has been with system-config-firewall-tui. Another advantage is the possibility to change firewall rules without dropping active connections. Templates can be distributed in a more readable way - anyhow, I'm still looking forward to YAML and JSON support.

The second part of this post series will focus on customized services, zones and NIC mappings.

Translations: