DEV Community

Cover image for Setting Up Firewall Policies using Firewalld
Sanskriti Harmukh for Vultr

Posted on with Aashish Chaurasiya Originally published at docs.vultr.com

Setting Up Firewall Policies using Firewalld

Firewalld is a dynamic firewall application that provides a flexible way of setting up network filtering policies on a server by extending the kernel-based iptables functionality. It provides flexible configuration options, including zone-based firewall management policies that represent a specific level of trust depending on your server's network connections, to protect the system from unauthorized access. This guide walks through setting up firewall policies using Firewalld and configuring sample rules to filter network requests on a Linux server. By the end, you'll have Firewalld installed, zones and rules configured, and panic mode ready as a last-resort lockdown.


Prerequisites

Before you begin:

  • A Rocky Linux (or other RHEL-based) server to use as the workstation.
  • Access to the server using SSH as a non-root user with sudo privileges.
  • Update the server:

    $ sudo dnf update
    

1. Install Firewalld

Firewalld is available as a default system package on most Red Hat-based server distributions such as CentOS, Rocky Linux, and AlmaLinux. When unavailable, follow the steps below to install and enable Firewalld to set up firewall filtering rules on the server.

1. Install Firewalld:

$ sudo dnf install firewalld
Enter fullscreen mode Exit fullscreen mode

2. Enable the Firewalld application to start at boot time:

$ sudo systemctl enable firewalld
Enter fullscreen mode Exit fullscreen mode

3. Start Firewalld:

$ sudo systemctl start firewalld
Enter fullscreen mode Exit fullscreen mode

4. Verify that the Firewalld service is active and running:

$ sudo firewall-cmd --state
Enter fullscreen mode Exit fullscreen mode

5. Save all runtime changes to the permanent Firewalld configuration:

$ sudo firewall-cmd --runtime-to-permanent
Enter fullscreen mode Exit fullscreen mode

2. Set Up Firewalld Zones

Firewalld zones represent the level of trust for network connections associated with a specific network interface. Each zone includes a different security level and policies that govern the traffic flow on the associated interface. By default, Firewalld runs with the following zones:

  • public: Applies to public-facing interfaces connected to external networks such as the Internet.
  • home: Applies to network interfaces associated with home networks or small office environments.
  • work: Works with corporate or organization network interfaces with better security over the home zone.
  • internal: Works with private interfaces connected to networks such as a VPC.
  • external: Applies to external untrusted networks. It's similar to the public zone but applies a higher security level by blocking incoming connection requests while accepting outgoing network connections.
  • dmz: Works with network interfaces connected to demilitarized zones partly connected to the Internet and filtered by a firewall.
  • block: Blocks all incoming and outgoing network traffic. It's useful when troubleshooting server network interfaces or networking errors.

1. View all available Firewalld zones:

$ sudo firewall-cmd --get-zones
Enter fullscreen mode Exit fullscreen mode

Output:

block dmz drop external home internal nm-shared public trusted work
Enter fullscreen mode Exit fullscreen mode

2. View the default Firewalld zone:

$ sudo firewall-cmd --get-default-zone
Enter fullscreen mode Exit fullscreen mode

Output:

public
Enter fullscreen mode Exit fullscreen mode

3. View the active Firewalld zone and the associated server network interfaces:

$ sudo firewall-cmd --get-active-zones
Enter fullscreen mode Exit fullscreen mode

Output:

public
  interfaces: enp1s0
Enter fullscreen mode Exit fullscreen mode

4. View the Firewalld zone assigned to a specific network interface. For example, view the enp8s0 network interface zone:

$ sudo firewall-cmd --get-zone-of-interface=enp8s0
Enter fullscreen mode Exit fullscreen mode

5. Change an interface from one zone to another. For example, change the enp1s0 interface to the external zone:

$ sudo firewall-cmd --zone=home --change-interface=eth0
Enter fullscreen mode Exit fullscreen mode

Output:

success
Enter fullscreen mode Exit fullscreen mode

Switching interfaces between zones sets different firewall rules and policies on the network interface for troubleshooting or testing purposes on the server.

6. View the active zones again to verify that two Firewalld zones are active due to the new interface assignment:

$ sudo firewall-cmd --get-active-zones
Enter fullscreen mode Exit fullscreen mode

Output:

home
  interfaces: enp8s0
public
  interfaces: enp1s0
Enter fullscreen mode Exit fullscreen mode

7. View all firewall rules associated with the active zone. By default, public:

$ sudo firewall-cmd --list-all
Enter fullscreen mode Exit fullscreen mode

Output:

public (active)
  target: default
  icmp-block-inversion: no
  interfaces: enp1s0 enp8s0
  sources: 
  services: cockpit dhcpv6-client ssh
  ports: 
  protocols: 
  forward: yes
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 
Enter fullscreen mode Exit fullscreen mode

8. Change the active zone depending on your server networking environment. For example, change the Firewalld zone to external:

$ sudo firewall-cmd --change-zone=public
Enter fullscreen mode Exit fullscreen mode

3. Set Up Firewall Policies using Firewalld

Firewalld accepts network ports, system services, and service names across multiple zones depending on your server interfaces. Every Firewalld zone, for example public, applies the set policies and rules to the associated interfaces. Follow the steps below to set up firewall policies using Firewalld on the server.

To delete Firewalld rules, replace the --add option with --remove to delete the rule. For example, delete the FTP port 21 policy in the public zone:

$ sudo firewall-cmd --zone=public --permanent --remove-port=22/tcp
Enter fullscreen mode Exit fullscreen mode

Allow Network Ports

1. Add a new Firewalld rule that allows the SSH TCP port 22 through the public zone:

$ sudo firewall-cmd --zone=public --permanent --add-port=22/tcp
Enter fullscreen mode Exit fullscreen mode

The above rule allows SSH access to the server using port 22 through the public zone. The rule is also permanently saved in the firewall table using the --permanent option.

2. Allow another service port, 80, through the firewall:

$ sudo firewall-cmd --zone=public --permanent --add-port=80/tcp
Enter fullscreen mode Exit fullscreen mode

3. View the active Firewalld zone ports to verify the new rules:

$ sudo firewall-cmd --zone=public --list-ports
Enter fullscreen mode Exit fullscreen mode

Output:

22/tcp 80/tcp
Enter fullscreen mode Exit fullscreen mode

4. Allow a range of ports through the public Firewalld zone. For example, port 4990 to 4999 depending on your internal hosts:

$ sudo firewall-cmd --zone=public --permanent --add-port=4990-4999/udp
Enter fullscreen mode Exit fullscreen mode

Allow System Services

1. View the list of available Firewalld services on your server:

$ sudo firewall-cmd --get-services
Enter fullscreen mode Exit fullscreen mode

Output:

RH-Satellite-6 RH-Satellite-6-capsule afp amanda-client amanda-k5-client amqp amqps apcupsd audit ausweisapp2 bacula bacula-client bb bgp bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc bittorrent-lsd ceph ceph-mon cfengine checkmk-agent cockpit collectd condor-collector cratedb ctdb dhcp dhcpv6 dhcpv6-client distcc dns dns-over-tls docker-registry docker-swarm dropbox-lansync elasticsearch etcd-client etcd-server finger foreman foreman-proxy freeipa-4 freeipa-ldap freeipa-ldaps freeipa-replication freeipa-trust ftp galera ganglia-client ganglia-master git gpsd grafana gre high-availability http http3 https ident imap imaps ipfs ipp ipp-client ipsec irc ircs iscsi-target isns jenkins kadmin kdeconnect kerberos kibana klogin kpasswd kprop kshell kube-api kube-apiserver kube-control-plane kube-control-plane-secure kube-controller-manager kube-controller-manager-secure kube-nodeport-services kube-scheduler kube-scheduler-secure kube-worker kubelet kubelet-readonly kubelet-worker ldap ldaps libvirt libvirt-tls lightning-network llmnr llmnr-tcp llmnr-udp managesieve matrix mdns memcache minidlna mongodb mosh mountd mqtt mqtt-tls ms-wbt mssql murmur mysql nbd netbios-ns netdata-dashboard nfs nfs3 nmea-0183 nrpe ntp nut openvpn ovirt-imageio ovirt-storageconsole ovirt-vmconsole plex pmcd pmproxy pmwebapi pmwebapis pop3 pop3s postgresql privoxy prometheus prometheus-node-exporter proxy-dhcp ps3netsrv ptp pulseaudio puppetmaster quassel radius rdp redis redis-sentinel rpc-bind rquotad rsh rsyncd rtsp salt-master samba samba-client samba-dc sane sip sips slp smtp smtp-submission smtps snmp snmptls snmptls-trap snmptrap spideroak-lansync spotify-sync squid ssdp ssh steam-streaming svdrp svn syncthing syncthing-gui synergy syslog syslog-tls telnet tentacle tftp tile38 tinc tor-socks transmission-client upnp-client vdsm vnc-server wbem-http wbem-https wireguard ws-discovery ws-discovery-client ws-discovery-tcp ws-discovery-udp wsman wsmans xdmcp xmpp-bosh xmpp-client xmpp-local xmpp-server zabbix-agent zabbix-server zerotier
Enter fullscreen mode Exit fullscreen mode

2. Allow a service such as HTTPS for access through the public zone table:

$ sudo firewall-cmd --zone=public --add-service=https --permanent
Enter fullscreen mode Exit fullscreen mode

3. Allow another service, such as FTP, through the public zone:

$ sudo firewall-cmd --zone=public --add-service=ftp --permanent
Enter fullscreen mode Exit fullscreen mode

4. Reload Firewalld to apply the new service changes:

$ sudo firewall-cmd --reload
Enter fullscreen mode Exit fullscreen mode

Output:

cockpit dhcpv6-client ftp http https ssh
Enter fullscreen mode Exit fullscreen mode

Enable Forwarding and IP Address Rules

1. Allow incoming traffic to the SSH port 22 from your public server IP address 192.0.2.100:

$ sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.0.2.100" port protocol="tcp" port="80" accept'
Enter fullscreen mode Exit fullscreen mode

2. Forward traffic from one port to another. For example, forward traffic from the internal port 8080 to the destination port 8900 through all IP addresses:

$ sudo firewall-cmd --zone=public --add-forward-port=port=80:proto=tcp:toport=8080:toaddr=0.0.0.0 --permanent
Enter fullscreen mode Exit fullscreen mode

The above rule forwards all incoming requests on port 8080 to 8900 to securely expose a specific resource on different ports.

3. Reload Firewalld to save the zone changes:

$ sudo firewall-cmd --reload
Enter fullscreen mode Exit fullscreen mode

4. Create Custom Firewalld Zones

1. Create a new Firewalld zone with a custom name, such as example-zone:

$ sudo firewall-cmd --permanent --new-zone=example-zone
Enter fullscreen mode Exit fullscreen mode

2. Reload Firewalld to save changes:

$ sudo firewall-cmd --reload
Enter fullscreen mode Exit fullscreen mode

3. View the Firewalld zones and verify that the new custom zone is available:

$ sudo firewall-cmd --permanent --get-zones
Enter fullscreen mode Exit fullscreen mode

Output:

block dmz drop example-zone external home internal nm-shared public trusted work
Enter fullscreen mode Exit fullscreen mode

5. Firewalld Panic Mode

Firewalld panic mode blocks all incoming and outgoing network connections on the server to protect the system in case of security threats. When enabled, the server blocks all connections, including your active SSH session. Follow the steps below to enable panic mode and troubleshoot the system in case of external threats or network failures.

1. View the Firewalld panic mode status:

$ sudo firewall-cmd --query-panic
Enter fullscreen mode Exit fullscreen mode

Output:

no
Enter fullscreen mode Exit fullscreen mode

2. Enable panic mode to block all network connections on the server:

$ sudo firewall-cmd --panic-on
Enter fullscreen mode Exit fullscreen mode

3. View the Firewalld panic mode status and verify that it's active:

$ sudo firewall-cmd --query-panic
Enter fullscreen mode Exit fullscreen mode

Output:

yes
Enter fullscreen mode Exit fullscreen mode

In case Firewalld blocks your SSH session, use your cloud provider's web console to start a new, out-of-band terminal session to the server.

Next Steps

  • Audit your zone assignments with firewall-cmd --get-active-zones before opening any new ports in production.
  • Replace broad rich rules with tighter source-address scoping once you've confirmed which hosts actually need access.
  • Script firewall-cmd --panic-off into your incident runbook so panic mode doesn't leave the server unreachable longer than intended.
  • Explore /etc/firewalld directly if you need to version-control your zone and service definitions.

For the full guide with additional tips, visit the original article on Vultr Docs.

Top comments (0)