What is Firewalld?

Firewalld is a firewall management solution for many Linux distributions including, Ubuntu, Debian, CentOS, RHEL and Fedora. It acts as a frontend for the iptables filtering system provided by the Linux kernel. It is protocol independent that means it supports IPv4, IPv6, ethernet bridges and IP sets.

Basic Concept of Firewalld

FirewallD uses zones and services instead of iptables chain and rules. Zones are a set of rules that specify what traffic should be allowed depending on the level of trust you have in a network your computers connected to. Network interfaces assigned a zone to dictate a behavior that the firewall should allow.

The firewalld is managed using the firewall-cmd command-line tool. It provides an interface to manage runtime and permanent configuration.

Firewalld Zones

There are 9 pre-defined zones in the Firewalld depending on the level of trust in ascending order.
A brief explanation of each zone are explained below:

  • Drop : This zone has the least level of trust and used to drop all incoming traffic without sending any acknowledgment to the sender.
  • Block : This zone is very similar to the Drop zone, the incoming traffic is rejected and the sender gets a message.
  • Public : Allows traffic from certain public networks.
  • External : This zone is used when your system acts as a gateway or router.
  • Internal : The set of rules that apply to the computers in your private internal network.
  • DMZ : This zone is an isolated patch of computers in your internal network that may not access other internal resources.
  • Work : This zone is used for work machines. The trust level is high.
  • Home : Most computers in this zone trust each other. The trust level is higher than work.
  • Trusted : This zone has the highest trust level. All computers in the network are trusted.

Step 1 – Installing Firewalld

By default, Firewalld is pre-installed on most of the operating systems. But some of the minimal OS installation doesn’t included fiIf not installed, you can install it with the following command:

sudo yum install firewalld        # CentOS/RHEL 8/7/6 
sudo dnf install firewalld        # Fedora and CentOS/RHEL 8 
sudo apt install firewalld        # Ubuntu and Debian  

After installing firewalld, you will need to start and enable it to start after system reboot.

sudo systemctl start firewalld
sudo systemctl enable firewalld

Run the following command to verify the status of firewalld

systemctl status firewalld
[OR] 
firewall-cmd --state

Step 2 – Working with Zones and Services

By default, public is the default zone in firewalld and all network interfaces are configured with public zone. You can list the default zone with the following command:

firewall-cmd --get-default-zone

Output:

public

Next, run the following command to get a list of active zones:

firewall-cmd --get-active-zones

You should get the following output:

public
  interfaces: eth0 eth1

To get a list of all available zones run the following command:

firewall-cmd --get-zones

You should get the following output:

block dmz drop external home internal public trusted work

You can list all services associated with a public zone with the following command:

firewall-cmd --list-all

You should get the following output:

public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0 eth1
  sources: 
  services: cockpit dhcpv6-client ssh
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

To change the default zone from public to work run the following command:

firewall-cmd --set-default-zone=work

You can now verify your default zone with the following command:

firewall-cmd --get-default-zone

Output:

work

You can get a list of all available services in your system with the following command:

firewall-cmd --get-services

You should get the following output:

RH-Satellite-6 amanda-client amanda-k5-client amqp amqps apcupsd audit bacula bacula-client bb bgp bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc bittorrent-lsd ceph ceph-mon cfengine cockpit condor-collector ctdb dhcp dhcpv6 dhcpv6-client distcc dns dns-over-tls docker-registry docker-swarm dropbox-lansync elasticsearch etcd-client etcd-server finger freeipa-4 freeipa-ldap freeipa-ldaps freeipa-replication freeipa-trust ftp ganglia-client ganglia-master git grafana gre high-availability http https imap imaps ipp ipp-client ipsec irc ircs iscsi-target isns jenkins kadmin kdeconnect kerberos kibana klogin kpasswd kprop kshell ldap ldaps libvirt libvirt-tls lightning-network llmnr managesieve matrix mdns memcache minidlna mongodb mosh mountd mqtt mqtt-tls ms-wbt mssql murmur mysql nfs nfs3 nmea-0183 nrpe ntp nut openvpn ovirt-imageio ovirt-storageconsole ovirt-vmconsole plex pmcd pmproxy pmwebapi pmwebapis pop3 pop3s postgresql privoxy prometheus proxy-dhcp ptp pulseaudio puppetmaster quassel radius rdp redis redis-sentinel rpc-bind rsh rsyncd rtsp salt-master samba samba-client samba-dc sane sip sips slp smtp smtp-submission smtps snmp snmptrap spideroak-lansync spotify-sync squid ssdp ssh steam-streaming svdrp svn syncthing syncthing-gui synergy syslog syslog-tls telnet tentacle tftp tftp-client tile38 tinc tor-socks transmission-client upnp-client vdsm vnc-server wbem-http wbem-https wsman wsmans xdmcp xmpp-bosh xmpp-client xmpp-local xmpp-server zabbix-agent zabbix-server

Step 3 – Allow and Deny Services in Firewalld

You can allow and deny incoming traffic based on predefined services in firewalld.

For example, to allow all incoming traffic for http service in Public zone run the following command:

firewall-cmd --zone=public --add-service=http

Output:

success

To allow incoming traffic for ftp service in Public zone run the following command:

firewall-cmd --zone=public --add-service=ftp

Output:

success

The above command will add http and ftp service temporary and it is not persistent on reboots. You will need to use the --permanent option to make them permanent as shown below:

firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=ftp

Next, run the following command to implement the changes:

firewall-cmd --reload

You can now get a list of added services with the following command:

firewall-cmd --permanent --zone=public --list-services

You should see the following output:

cockpit dhcpv6-client ftp http ssh

You can also check the detail information about Public zone with the following command:

firewall-cmd --info-zone public

Output:

public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0 eth1
  sources: 
  services: cockpit dhcpv6-client ftp http ssh
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

If you want to remove/deny the above services from the firewalld, use the --remove-service option:

firewall-cmd --permanent --zone=public --remove-service=http
firewall-cmd --permanent --zone=public --remove-service=ftp

Next, run the following command to apply the changes:

firewall-cmd --reload

Step 4 – Allow and Deny Ports in Firewalld

You can also allow and deny incoming traffic based on the port in firewalld.

For example, allow all incoming traffic on port 8080 and 443, run the following command:

firewall-cmd --permanent --zone=public --add-port=443/tcp
firewall-cmd --permanent --zone=public --add-port=8080/tcp

Next, run the following command to apply the changes:

firewall-cmd --reload

Next, verify the added ports with the following command:

firewall-cmd --permanent --zone=public --list-ports

Output:

443/tcp 8080/tcp

Similarly remove/deny the above ports from the firewalld, use the –remove-port option:

firewall-cmd --permanent --zone=public --remove-port=443/tcp
firewall-cmd --permanent --zone=public --remove-port=8080/tcp

Next, run the following command to apply the changes:

firewall-cmd --reload

Step 5 – Port Forwarding with Firewalld

Port forwarding is the process that redirects request from IP/port combination and redirect it to a different IP and/or port. This technique allows remote machines to connect to a specific service within a private network.

Before configuring port forwarding, you need to activate masquerade in the desired zone. You can activate it using the --add-masquerade option:

firewall-cmd --zone=public --add-masquerade

Next, to forwards traffic from port 80 to port 8080 on the same server run the following command:

firewall-cmd --permanent --zone=public --add-forward-port=port=80:proto=tcp:toport=8080

If you want to forwards traffic from local port 80 to port 8080 on a remote server with IP address 192.168.1.200 run the following command:

firewall-cmd --permanent --zone=public --add-forward-port=port=80:proto=tcp:toport=8080:toaddr=192.168.1.200

Next, run the following command to apply the changes:

firewall-cmd --reload

If you want to remove the above rules, replace –add with –remove as shown below:

firewall-cmd --permanent --zone=public --remove-forward-port=port=80:proto=tcp:toport=8080:toaddr=192.168.1.200
firewall-cmd --permanent --zone=public --remove-forward-port=port=80:proto=tcp:toport=8080

Conclusion

In the above guide, you learned the basic concept of Firewalld and how to implement it on the Linux operating system. I hope you can now limit unnecessary incoming traffic with firewalld.