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.