(May 2019)
firewalld is Linux firewall configuration software that acts as a higher-level wrapper over netfilter tools like iptables and nftables.
This abstraction keeps firewall rules and tools consistent, even as preferred lower-level technologies compete and evolve (i.e., will nftables or bpfilter succeed iptables?).
Changes to the running rules can be applied without disrupting existing flows (assuming NetworkManager is in use).
Arguably, firewalld also offers friendlier tools than, for example, nft
.
RHEL 8 uses firewalld by default, and Debian-based distributions offer it as a package.
The firewalld documentation is good. The following notes largely summarize those docs.
The /usr/lib/firewalld/
directory holds firewalld’s default and fallback XML configuration files.
Don’t modify them in place, because they’ll be overwritten by package upgrades.
Store local changes in /etc/firewalld/
;
files there override the default configuration.
The base config file is /etc/firewalld/firewalld.conf
.
firewalld differentiates between the runtime and permanent configuration. The configuration presently in effect in the kernel is the runtime configuration. A system reboot or restart/reload of the firewalld service restores the permanent configuration from saved config files, discarding any differences from the previous runtime configuration.
Save the current runtime config as the permanent config with:
# firewall-cmd --runtime-to-permanent
firewall-cmd
is the main tool to control firewalld.
See the firewalld-cms(1) man page.
# firewall-cmd --help
# firewall-cmd --state
# firewall-cmd --get-active-zones
# firewall-cmd --get-zone-of-interface=br0
# firewall-cmd --reload
A firewalld zone group together a set of rules/policies (i.e., a “trust level”). That zone can be applied to an interface, connection, or source address. A connection/interface/source belongs to only one zone, but a zone can be applied to multiple connections. By default, firewalld defines these zones, sorted from untrusted to trusted:
A default zone includes any connections not belonging to another zone.
See the firewall.zone(5)
and firewall.zones(5)
manual pages for more information.
firewalld links services to zones.
A service definition includes a list of ports, and sometimes other information, like firewall helper modules (e.g., an FTP connection tracking helper).
See the firewalld.service(5)
man page.
firewalld uses IPSets to group lists of IP or MAC addresses. firewalld can use an IPSet in a black- or whitelist rule, for example.
The direct interface feature allows literal iptable rules to be passed through firewalld (though this defeats some of the purpose).
$ systemctl status firewalld
$ firewall-cmd --state
# firewall-cmd --reload
# firewall-cmd --complete-reload
--complete-reload
kills all current states, whereas --reload
preserves existing flows.
# firewall-cmd --zone=public --add-port=80/tcp
# firewall-cmd --permanent --zone=public --add-port=80/tcp
# firewall-cmd --zone=public --add-service=http
# firewall-cmd --permanent --zone=public --add-service=http
# firewall-cmd --permanent --new-service=myservice
# firewall-cmd --permanent --service=myservice --set-description=description
# firewall-cmd --permanent --service=myservice --set-short=description
# firewall-cmd --permanent --service=myservice --add-port=portid[-portid]/protocol
# firewall-cmd --permanent --service=myservice --add-protocol=protocol
# firewall-cmd --permanent --service=myservice --add-source-port=portid[-portid]/protocol
# firewall-cmd --permanent --service=myservice --add-module=module
# firewall-cmd --permanent --service=myservice --set-destination=ipv:address[/mask]
# firewall-cmd [ --zone=<zone> ] --list-services
# firewall-cmd --get-active-zones
# firewall-cmd --get-zones
# firewall-cmd --get-services
# firewall-cmd --get-icmptypes
# firewall-cmd --list-all-zones
# firewall-cmd --get-zone-of-interface=<interface>
# firewall-cmd [--zone=<zone>] --change-interface=<interface>
# firewall-cmd [--zone=<zone>] --remove-interface=<interface>
# firewall-cmd --permanent [--zone=<zone>] --add-forward-port=port=<port>[-<port>]:proto=<protocol> \
{ :toport=<port>[-<port>] | :toaddr=<address> | :toport=<port>[-<port>]:toaddr=<address> }
# firewall-cmd --permanent [--zone=<zone>] --remove-forward-port=port=<port>[-<port>]:proto=<protocol> \
{ :toport=<port>[-<port>] | :toaddr=<address> | :toport=<port>[-<port>]:toaddr=<address> }
# firewall-cmd --permanent [--zone=<zone>] --query-forward-port=port=<port>[-<port>]:proto=<protocol> \
{ :toport=<port>[-<port>] | :toaddr=<address> | :toport=<port>[-<port>]:toaddr=<address> }<Paste>