Posted on November 24 2021 under networking, security, and linux
Modern RHEL/CentOS/Rocky Linux releases use firewalld to simplify configuration of the host firewall. Firewalld is a tool which allows you to configure rule sets in a zone-based manner, then translates that configuration to nftables.
When using firewall-cmd
the changes are applied immediately but are not saved to disk and will not persist through a reboot. When using firewall-cmd --permanent
this behaviour is reversed: changes are saved to disk but will not apply until the next reboot. You can apply permanent changes immediately by forcing firewalld to reload its configuration with firewall-cmd --reload
. It is therefore generally recommend to always use --permanent
and then finish with a --reload
.
The --check-config
command will check the system configuration for errors. It is recommend to always do this before running a --reload
if changes have been made.
Note: The --reload
command will preserve state information and so is safe to execute on a production system. The --complete-reload
command will reset the kernel netfilter tables, which can be useful during troubleshooting but will break existing connections.
To view the active zones, run firewall-cmd --get-active-zones
. To view the configuration of a zone, run firewall-cmd --zone=<zone> --list-all
.
There are several pre-configured zones:
Traffic can be placed in zones based on interface, source address, and other criteria.
On a fresh install, all interfaces will be placed in the public zone. To temporarily move an interface to a different zone you can run firewall-cmd --zone=<zone> --change-interface=<ifname>
. While this command can be run with --permanent
, NetworkManager also contains a setting for the default zone for an interface and it is best to configure it there to avoid conflicts. This can be done by either editing the ZONE=
setting in /etc/sysconfig/network-scipts/ifcfg-<ifname>
or via one of the various NetworkManager configuration tools such as nmcli
, nmtui
, or nm-connection-editor
. For example, using nmcli
:
nmcli connection modify ens160 connection.zone work
systemctl restart NetworkManager
Traffic can be seperated out into a different zone, and therefore rule set, by source address. A common use-case is to lock down SSH to internal networks only:
firewall-cmd --permanent --zone=work --add-source=10.0.0.0/8
firewall-cmd --permanent --zone=work --add-service=ssh
firewall-cmd --permanent --zone=public --remove-service=ssh
firewall-cmd --check-config
firewall-cmd --reload
Services can be defined with a name, description and one or more ports/protocols in an XML file. Custom services can be placed in /etc/firewalld/services
while the many default services can be found in /usr/lib/firewalld/services
.
To see a list of available services, run firewall-cmd --get-services
.
Example: Allow HTTP and HTTPS traffic
firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
firewall-cmd --check-config
firewall-cmd --reload
Example: Allow SMB shares, which require both 139/tcp and 445/tcp
firewall-cmd --permanent --zone=public --add-service=samba
firewall-cmd --check-config
firewall-cmd --reload
Basic TCP and UDP ports can be used to allow custom traffic:
Example: Allow TCP port 8080 and UDP port 5000
firewall-cmd --permanent --zone=public --add-port=8080/tcp
firewall-cmd --permanent --zone=public --add-port=5000/udp
firewall-cmd --check-config
firewall-cmd --reload
ICMP rules are inverted compared to other rules: all ICMP types are allowed unless explicitly blocked. This behaviour can be changed with the --add-icmp-block-inversion
and --remove-icmp-block-inversion
commands.
To see a list of available ICMP types, run firewall-cmd --get-icmptypes
.
Example: Block echo requests
firewall-cmd --permanent --zone=public --add-icmp-block=echo-request
firewall-cmd --check-config
firewall-cmd --reload
Rules can be configured to allow traffic based on the IP protocol. Protocols can be referred to by name or number. To see a list of available protocols names, run cat /etc/protocols
.
Example: Allow ESP traffic for an IPSec VPN
firewall-cmd --permanent --zone=public --add-protocol=esp
firewall-cmd --check-config
firewall-cmd --reload