Firewall Management (firewalld)
Skill Level: Fundamental
1. Overview
The firewalld daemon provides a dynamically managed network security layer that tightly controls what connections (ports and services) are able to communicate via the system’s network interfaces.
Features of firewalld include:
-
support for IPv4 and IPv6
-
support for ethernet bridges
-
support for network “zones” which assigns level of trust to a network / connections / interfaces
-
separation of runtime and permanent configuration options
-
an interface for external services to manage firewall rules directly
2. Getting Started
For these exercises, you will be using the host node1
as user root
.
From host bastion
, ssh to node1
.
ssh node1
Use sudo
to elevate your privileges.
[[ "$UID" == 0 ]] || sudo -i
Verify that you are on the right host for these exercises.
workshop-firewalld-checkhost.sh
You are now ready to proceed with these exercises.
3. Core Concepts
The RHEL 10 firewall consists of:
-
firewalld : daemon/service
-
firewall-cmd : command line management utility
-
firewall-config : a GUI based management utility
For this workshop, we are only going to be using firewall-cmd.
3.1. Configuration
The configuration files for firewalld are stored in two places:
-
/usr/lib/firewalld - distributed system default configs
-
/etc/firewalld - user customizations / override configs
Configurations stored in /usr/lib/firewalld are NOT meant for customization. They WILL be overwritten and replaced from time to time as Red Hat releases new packages or updates for the operating system.
User customizations for firewalld belong in /etc/firewalld. These configuration files take precedence over the system default configs.
3.2. Services
Firewalld implements the concept of a service. A service includes:
-
a common name
-
a port or range of ports
-
a protocol
-
a netfilter helper module
-
a destination address (or range) for IPv4 and/or IPv6.
There are nearly 50 built-in services shipped with firewalld. You can also create your own service configs from scratch or customize the default files (covered in "Intermediate Firewall Management"). Let’s take a quick look at the default configuration for ssh & http to start.
cat /usr/lib/firewalld/services/ssh.xml
<?xml version="1.0" encoding="utf-8"?> <service> <short>SSH</short> <description>Secure Shell (SSH) is a protocol for logging into and executing commands on remote machines. It provides secure encrypted communications. If you plan on accessing your machine remotely via SSH over a firewalled interface, enable this option. You need the openssh-server package installed for this option to be useful.</description> <port protocol="tcp" port="22"/> </service>
cat /usr/lib/firewalld/services/http.xml
<?xml version="1.0" encoding="utf-8"?> <service> <short>WWW (HTTP)</short> <description>HTTP is the protocol used to serve Web pages. If you plan to make your Web server publicly available, enable this option. This option is not required for viewing pages locally or developing Web pages.</description> <port protocol="tcp" port="80"/> </service>
4. Determine State
Firewalld maintains two states of the firewall configuration: runtime and permanent. When you make changes to the configuration it is important to consider what is currently running and what will persist past the next reboot. |
Determine current state of the firewalld service.
firewall-cmd --state
running
Get a list of currently configured and active "zones".
firewall-cmd --get-active-zones
public interfaces: enp0s3
You may have one or more zones depending on the host and its configuration:
-
public
zone on interfaceenp0s3
-
libvirt
zone on interfacevirbr0
In this sample output, the virtual bridge libvirt is created and managed by libvirtd. It is possible that your system will not have the libvirt zone. For our purposes, we are only interested in the public zone and the interface enp0s3 .
|
We had this information from the previous command, but to be more specific let’s just list the physical interfaces associated with the public zone.
firewall-cmd --zone=public --list-interfaces
enp0s3
Get a list of services configured on the public zone.
firewall-cmd --zone=public --list-services
cockpit dhcpv6-client ssh
We see the web console, the dhcp client and of course the ssh service.
Now let’s get some specific data points on the web console service (cockpit).
firewall-cmd --info-service=cockpit
cockpit ports: 9090/tcp protocols: source-ports: modules: destination: includes: helpers:
Nothing too exciting, but we can note that the web console is configured on port 9090.
Finally, let’s just list everything about the public zone.
firewall-cmd --zone=public --list-all
public (active) target: default icmp-block-inversion: no interfaces: enp0s3 sources: services: cockpit dhcpv6-client http ssh ports: protocols: forward: yes masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
5. Managing Default Services
Default Services are those that are pre-defined by configuration files in either /etc/firewalld or /usr/lib/firewalld. This would include any configs delivered by Red Hat as part of the operating system or those added by a system administrator.
Here we will take a moment to enable the http and https service ports.
5.1. Add a Service
firewall-cmd --add-service={http,https}
firewall-cmd --zone=public --list-all
public (active) target: default icmp-block-inversion: no interfaces: {enp0s3} sources: services: cockpit dhcpv6-client http https ssh ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
Remember how we mentioned above about the two configuration states: runtime and permanent? Notice below how the permanent state does NOT include http or https.
firewall-cmd --zone=public --list-all --permanent
public target: default icmp-block-inversion: no interfaces: sources: services: cockpit dhcpv6-client ssh ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
A quick way to make them permanent is to save the current runtime state to permanent.
firewall-cmd --runtime-to-permanent
You could have also run the same configuration command a second time and
passed the --permanent flag as follows firewall-cmd --permanent --add-service={http,https} .
It’s annoying but necessary to run configuration commands twice to manage both states and
maintain consistency.
|
firewall-cmd --zone=public --list-all --permanent
public target: default icmp-block-inversion: no interfaces: sources: services: cockpit dhcpv6-client http https ssh ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
5.2. Remove a Default Service
Now let us disable a service port not needed for our workshop environment, namely dhcp6-client.
firewall-cmd --remove-service=dhcpv6-client
firewall-cmd --runtime-to-permanent
Take a look at the active services now and you should find dhcp6-client absent.
firewall-cmd --list-services
cockpit http https ssh
And since we also ran a --runtime-to-permanent, both the runtime and permanent configs were updated.
firewall-cmd --list-services --permanent
cockpit http https ssh
6. Conclusion
That concludes this unit on firewalld.
Time to finish this unit and return the shell to its home position.
workshop-finish-exercise.sh