How to Configure Firewall with FirewallD

Firewalld is a firewall management tool which acts as a front-end for the Linux kernel's netfilter framework. Its is powerful zone based firewall which monitor network traffic and apply a set of defined rules to control incoming/outgoing traffic.

Firewalld is written in Python and is part of systemd. It supports both IPv4 and IPv6 networks.

The main benefit are changes can be done without service restarts and with D-Bus interface configurations can be managed easily.

In this tutorial we learn how to configure Firewalld on Linux and its basic concepts.

Basic Concepts

Firewalld consist two layers named as core and D-Bus layer. The core layer handles configuration and backends. The D-Bus layer is responsible for altering and creating the firewall configuration.

Firewalld supports zones and services. Zone are predefined set of rules that govern what kind of traffic should be allowed to the server based on the trust level of the network interfaces attached to server. This implies that you can assign network interface to a zone. Services enables to configure ports, modules and destination addresses.

firewall-cmd is the command line tool used to manage runtime and permanent configurations.

Predefined Firewalld zones

The default zones are kept in the directory named /usr/lib/firewalld/zones/. Here are the some of predefined zones that Firewalld provides according to various trust levels - from trusted to the untrusted.

Trusted: This zone accepts all connections and trusts all the computers on the network.

Public: Employed in untrusted public areas. There is minimal trust on other computerss, but still selected inbound connections can be allowed.

drop: All inbound or incoming traffic is dropped. Only outbound traffic is allowed.

External: Implemented on external networks when your system acts as a router with NAT masquerading turned on. Only the selected inbound connections are allowed.

Internal: Implemented only on internal networks with your system acting as a router with NAT masquerading enabled. Other PCs are trusted and only a select few inbound connections are granted access.

block: The block zone rejects all incoming connections with an icmp-host-prohibited message for IPv4 and icmp6-adm-prohibited for IPv6n. Here, only the outgoing connections are allowed.

dmz: Used for systems or PCs on a demilitarized zone ( DMZ) with limited access to the rest of the systems on your computer network. By default it only allows SSH traffic.

work: The work zone is Implemented for work systems or PCs. There's a general level of trust for all other computers on the network and only selected inbound connections are allowed.

home: The home zone is used by home systems, and just like the work zone, all PCs are generally trusted, and only selected incoming connections are allowed.

Firewall runtime and permanent settings

The actual running configuration is the runtime configuration. It is transient and does not survive a reboot. Upon a server restart, Firewalld loads the permanent configuration, which later transforms into runtime configuration.

When changes are made to the Firewalld configuration, they are directly applied to the runtime configuration. To persist the changes, invoke the --permanent option.

Installing and enabling Firewalld

Firewalld is available by default on Red Hat, CentOS, Fedora, Suse Linux. On Debian/Ubuntu it is available in the package repository.

Redhat/CentOS

If firewalld is found not installed, install it by running the following command:

$ sudo yum install firewalld

Debian/Ubuntu

$ sudo apt install firewalld

Once installed, can verify the status:

$ sudo systemctl status firewalld

The output will indicate active (running) if Firewalld is up and running.

Alternatively, can confirm the running state by:

$ sudo firewall-cmd state

Once installed, start and enable Firewalld by running the following commands:

$ sudo systemctl start firewalld

Enable Firewalld on system boot, type:

$ sudo systemctl enable firewalld

To temporarily stop Firewalld, type:

$ sudo systemctl stop firewalld

To disable Firewalld from starting on boot, type:

$ sudo systemctl disable firewalld

Handling Firewalld zones

Lets check how to handle Firewalld zones.

1. By default, the public zone is the default Firewalld zone. To confirm this, execute the command:

$ sudo firewall-cmd --get-default-zone

Output:

public

2. To get an overview of all the zones, run the command:

$ sudo firewall-cmd --get-zones

This will list all the zones.

Output:

block dmz drop external home internal public trusted work

3. Network interfaces, by default, are usually attached to the default zone. To verify the zones in use by your network interfaces, run the following command.

$ sudo firewall-cmd --get-active-zones

In this case, I have one active network interfaces - enp0s3 - which is assigned to the default zone.

List firewalld zones assigned to an interface
List firewalld zones assigned to an interface

4. To display all the configuration of a zone,

To view the configuration of public zone, type:

$ sudo firewall-cmd --zone=public --list-all

To display overview of default zone, type:

$ sudo firewall-cmd --list-all

5. To list the configuration of all the Firewalld zones, type:

$ sudo firewall-cmd  --list-all-zones

Change the default zone

The default zone assigned to all network interfaces is public. You can set it to a different zone.

6. To change default zone to another zone, type:

$ sudo firewall-cmd --set-default-zone=trusted

Here, we have changed default zone to trusted zone.

Change the zone assigned to an interface

To change zone of a network interface to another use the --zone option.

7. To change the zone of the interface enp0s3 to trusted, type:

$ sudo firewall-cmd --zone=home --change-interface=enp0s3

Firewalld services

Firewalld service files are found in the /usr/lib/firewalld/services path in xml file format. There are hundreds of them and use ls command to list.

$ ls /usr/lib/firewalld/services

For example the MongoDB service file would like:

$ sudo vim /usr/lib/firewalld/services/mongodb.xml
MongoDB xml service file
MongoDB xml service file

By default, dhcp-client and ssh services are allowed on the firewall. From the output, notice that https has also been allowed.

To create a new Firewalld service, simply copy an existing service file and give a new service name . Then define that xml file.

One of the most widely used functionalities of the firewall is opening ports and allowing through to the server. Firewalld has predefined services.

8. To display all services, type:

$ sudo firewall-cmd --get-services

9. Allow inbound traffic

To allow inbound traffic for mssql service, type:

$ sudo firewall-cmd --zone=public --add-service=mssql

10. To verify the services added:

$ sudo firewall-cmd --zone=public --list-services

Output:

dhcpv6-client mssql ssh

11. To persist the change even after a reboot, invoke the --permanent option as follows.

$ sudo firewall-cmd --zone=public --add-service=https --permanent

12. To make the changes come into effect, reload the firewalld

$ sudo firewall-cmd --reload

13. To remove a service from the firewall, use the --remove option

$ sudo firewall-cmd --zone=public --remove-service=https --permanent
Remove a service from Firewalld configuration
Remove a service from Firewalld configuration

The above command remove the HTTPS services permanently from the public zone.

14. To open the port on the firewalld

For instance, the Xrdp service , which allows a user to remotely connect to the desktop of a remote system, is associated with TCP port 3389.

To open the port in public zone, type:

$ sudo firewall-cmd --zone=public --add-port=3389/tcp
Allow a port across Firewalld configuration
Open a port

Don't forget to reload Firewalld for the changes to come into effect.

Port forwarding with Firewalld

15. To enable masquerading for the public zone

To forward traffic from one port to the next or an address, first turn on or enable masquerading for the preferred zone by invoking the --add-masquerade option.

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

16. Forwarding traffic from one port to another on the same server

To configure Firewalld in such a way that incoming traffic reaching a certain port is redirected to another port on the same server.

To forward traffic reaching port 80 to port 6000 on the public zone, type:

$ sudo firewall-cmd --zone=public--add-forward-port=port=80:proto=tcp:toport=6000

17. Forwarding traffic to a different port on another server

Alternatively, traffic passing from one port can be redirected to a different port located on a different server.

To pass traffic through port 80 is redirected to port 8080 on another server whose IP address is 192.168.10.10, type:

$ sudo firewall-cmd --zone=external --add-forward-port=port=80:proto=tcp:toport=8080:toaddr=192.168.10.10

Set Rules to manage incoming traffic

To allow traffic incoming traffic from specific source use --add-source option.

To allow all incoming traffic from 192.168.10.0/24 in the trusted zone, type:

$ sudo firewall-cmd  --zone=trusted --add-source=192.168.10.0/24 --permanent

Create a new zone

You can create your own zones and add ruleset. Most cases the predefined zones are sufficient. Lets create a new zone for a web server and allow specific services/interface.

Create a new zone named webzone:

$ sudo firewall-cmd --permanent --new-zone=webzone

Verify by listing the permanent zones, type:

$ sudo firewall-cmd --permanent --get-zones

Output:

block dmz drop external home internal public trusted webzone work

To get effective into active configuration, type:

$ sudo firewall-cmd --reload

To open ssh, http, https service and assign interface on webzone, run the following commands:

$ sudo firewall-cmd --zone=webzone --add-service=ssh
$ sudo firewall-cmd --zone=webzone --add-service=http
$ sudo firewall-cmd --zone=webzone --add-service=https
$ sudo firewall-cmd --zone=webzone --add-interface=eth0

To display the configuration of webzone, type:

$ sudo firewall-cmd --zone=webzone --list-all

Output:

webzone
target: default
icmp-block-inversion: no
interfaces: eth0
sources:
services: http https ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:

Rich rules

Rich rule helps to set more complex firewall rules.

For instance, to enable access for source address ip address and specific port, type:

$ sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="23.92.31.51/32" port port=21 protocol="tcp" accept'

Summary

In this tutorial we learned how to configure Firewalld on Linux and its basic concepts.

If you have any feedback and suggestion please comment below.

Leave a Comment