Service
Install and enable Firewalld
$ apt-get install firewalld firewall-cmd
$ systemctl enable firewalld
$ systemctl start firewalld
Check if firewalld is active
$ firewall-cmd --state
running
Make current rules persistent
$ firewall-cmd --runtime-to-permanent
$ firewall-cmd --reload
Reload the firewall
$ firewall-cmd --reload
Interfaces
Get zone of interface
$ firewall-cmd --get-zone-of-interface tun0
external
Remove an interface from a zone
$ firewall-cmd --zone=external \
--remove-interface tun0
Add an interface to a zone
$ firewall-cmd --zone=internal \
--add-interface tun0
Zones
Get zone names
$ firewall-cmd --get-zones
FedoraServer FedoraWorkstation block dmz drop external home internal public trusted work
Get default zone
$ firewall-cmd --get-default-zone
public
Change the default zone
$ firewall-cmd --set-default-zone external
Adding a service to a zone
$ firewall-cmd --zone=home \
--add-service ssh
Adding a source IP to a zone
$ firewall-cmd --zone=home \
--add-source 203.0.113.224/27
Adding a source MAC to a zone
$ firewall-cmd --zone=trusted \
--add-source 5a:c2:5c:02:f3:e9
Get active zones
$ firewall-cmd --get-active-zones
external
interfaces: ens3
home
sources: 203.0.113.224/27
internal
interfaces: tun0
Describe all zones and rules
$ firewall-cmd --list-all-zones
external (active)
target: default
icmp-block-inversion: no
interfaces: ens3
sources:
services: openvpn
ports:
protocols:
masquerade: yes
forward-ports:
source-ports:
icmp-blocks:
rich rules:
home (active)
target: default
icmp-block-inversion: no
interfaces:
sources: 203.0.113.224/27
services: cockpit ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
internal (active)
target: default
icmp-block-inversion: no
interfaces: tun0
sources:
services: http https ssh cockpit dns
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
Using the drop and trusted zone
Firewalld includes a special zone known as trusted
that will unconditionally allow traffic.
“Trusted” sources or interfaces can be added to this zone.
$ firewall-cmd --zone trusted \
--add-source 172.28.29.30 \
$ firewall-cmd --zone trusted \
--add-interface virbr3
Firewalld also includes a drop
zone which can be used to unconditionally drop traffic from specific interfaces or source addresses
$ firewall-cmd --zone drop \
--add-source 169.254.0.0/16
Clear services from zones
Firewalld is preinstalled with a default configuration for every zone. For example, the home zone includes services such as samba and mDNS. I prefer starting with a clean slate. The command below will clear every service from every zone. Be careful not to lock yourself out!
for zone in $(firewall-cmd --get-zones); do firewall-cmd \
--list-services --zone=$zone | xargs -n1 firewall-cmd \
--zone=$zone --remove-service; done
Rich rules
Allow any traffic from source address
This rule allows any traffic with a source address of 10.20.30.40.
This rule only applies to sources/interfaces in the internal
zone
$ firewall-cmd --zone=internal \
--add-rich-rule 'rule
family=ipv4
source address=10.20.30.40
accept'
Allow service from source address
This rule allows SSH if the source address is 192.0.2.111
This rule only applies to sources/interfaces in the external
zone
$ firewall-cmd --zone=external \
--add-rich-rule 'rule
family=ipv4
service name=ssh
source address=192.0.2.111
accept'
Allow traffic to destination address and port
This rule allows traffic to port 1194/udp if the destination address is 198.51.100.123.
This rule applies to the default zone
$ firewall-cmd --add-rich-rule 'rule
family=ipv4
protocol=udp port=1194
destination address=198.51.100.123
accept'
Allow a service with rate-limit
$ firewall-cmd --add-rich-rule='rule
service name=ssh
limit value=10/m
Accept a service and log (with ratelimit)
$ firewall-cmd --add-rich-rule='rule
family=ipv4
service name=ssh
log prefix=ssh
level=info
limit value=3/m
accept
IPset
Define a new ipset
$ firewall-cmd --permanent \
--new-ipset china
--type hash:net
Add an ipset from XML file
$ firewall-cmd --permanent \
--new-ipset-from-file=china.netset.xml \
--name=china \
Add ipset entries from file
$ firewall-cmd --permanent \
--ipset china \
--add-entries-from-file ip2location_country_cn.netset
Block sources by ipset
$ firewall-cmd --permanent \
--zone=drop \
--source ipset:china
Find the XML file containing ipset
$ firewall-cmd --permanent --path-ipset china
/etc/firewalld/ipsets/china.xml
Miscellaneous
Time-limited rules
Using the timeout option, it is possible to set a maximum lifetime of a rule; the rules below will be automatically deleted after 60s
$ firewall-cmd --timeout 60 \
--add-service https
$ firewall-cmd --timeout 60 \
--add-rich-rule 'rule family=ipv4
source address=10.122.4.20
accept'
Adding traditional iptables rules
$ firewall-cmd --permanent \
--direct \
--add-rule ipv4 filter FORWARD 1 -i tun+ -d 10.0.0.0/8 -j DROP
Configure NAT masquerading
$ firewall-cmd --zone=external \
--add-masquerade
Configure port forwarding
$ firewall-cmd --zone=external \
--add-forward-port 'port=8080:proto=tcp:toport=80:toaddr=10.10.10.10'