A firewall is an essential part of network defense for any network-aware device. It works by filtering incoming and outgoing network traffic according to defined rules. Firewalld is a dynamic daemon for managing firewall with network zones support.

Introduction

This tutorial will show you how to set up a firewalld on a Centos 7 system. I won’t explain the basics of using firewalls since there are a lot of great articles already written about this topic.

Firewalld comes as a replacement for iptables in new Linux distributions. It’s recommended to use firewalld instead of iptables in view of that iptables may be deprecated in the future moreover there are some software applications that depend on firewalld, for example Fail2Ban.

Step 1 — Installing firewalld

You may have firewalld preinstalled, just type the following command to check this.

1
systemctl status firewalld

In case you don’t have firewalld installed on your system, install it using this simple yum command :

1
yum install firewalld -y

Also, verify whether you have iptables enabled.

1
systemctl status iptables

If the iptables service is installed you need to disable and mask it before using firewalld.

1
2
systemctl disable iptables
systemctl mask iptables

Finally, enable the firewalld service to start at boot.

1
systemctl enable firewalld

Furthermore, firewalld comes with a command-line tool called firewall-cmd, that is used for configuration and control of the firewall. It will be used extensively later in this article.

1
firewall-cmd --state

Step 2 — Firewalld zones

Firewalld defines a new term – zone. A network or firewall zone contains a set of rules that can be used to separate different networks based on the level of trust. For instance, you can assign a network interface to a zone and later reassign it to another one.

Default zones

Firewalld has several default zones :

  • Drop – All incoming network packets are dropped with no reply except outgoing connections.
  • Block – All incoming network connections are rejected with an icmp-host-prohibited message. Communication is only possible for network connections initiated within this system.
  • External – Only chosen incoming network connections are accepted. Can be used especially with routers. NAT Masquerading is enabled.
  • DMZ – For devices in your demilitarized zone that are publicly-accessible but have limited access to your internal network. Only explicitly allowed incoming connections are accepted.
  • Work – Most of network devices in a work area are trusted. Only selected incoming connections are accepted.
  • Home – For home environments. The most computers are fairly trustworthy. Only specific incoming connections are accepted.
  • Internal – For use on internal networks and therefore you can mostly trust the other computers on the networks to not harm your computer. Only selected incoming connections are accepted.
  • Trusted – All network connections are accepted.

You can obtain the list of available zones using the following command :

1
firewall-cmd --get-services

There is no magic in the zones. Let’s find out where they are defined, how a zone file looks like.

There are two main directories that contain zone configuration files

  • /usr/lib/firewalld/zones – This directory contains predefined zones described above that are used as default declarations of the zones or can be also applied as a fallback.
  • /etc/firewalld/zones – This directory holds user defined zones. By default it contains the public zone file. Files in this directory will overload the default configuration files.

A zone file

A zone file contains rules defined in the XML format. Let’s see the content of the /etc/firewalld/zones/public.xml zone file.

1
2
3
4
5
6
7
8
[root@crosp zones]# cat /etc/firewalld/zones/public.xml
<?xml version="1.0" encoding="utf-8"?>
<zone>
  <short>Public</short>
  <description>For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
  <service name="dhcpv6-client"/>
  <service name="ssh"/>
</zone>

If you haven’t manually added or removed any rules this file will be identical to the file /usr/lib/firewalld/zones/public.xml

The XML above is quite self-descriptive. I think you’ve already guessed what does the service tag represent.

A service file

A service file contains the information of a service such as ports, protocols and addresses. I will not go into depth describing services, for more details you can visit the Services Official Documentation Page.

As an example open the default service file /usr/lib/firewalld/services/ssh.xml

1
2
3
4
5
6
7
[root@crosp zones]# cat /usr/lib/firewalld/services/ssh.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>SSH</short>
  <description>Secure Shell (SSH) is a protocol for logging into and executing commands on remote machines. It provides secure encrypted communications. If you plan on accessing your machine remotely via SSH over a firewalled interface, enable this option. You need the openssh-server package installed for this option to be useful.</description>
  <port protocol="tcp" port="22"/>
</service>

You can get the list of available services using the firewall-cmd tool:

1
firewall-cmd --get-services

Step 3 — Creating a custom zone

Before creating a custom zone I would suggest to familiarize yourself with the information about defined zones using the following command:

1
firewall-cmd --list-all-zones

In the output you can find the properties you can define using a zone file.

Finally, let’s create our custom zone. You can do this in two ways: manually creating a zone file or using the command line tool. I will use the latter option in order explain how everything works under the hood. Execute the following command:

1
firewall-cmd --permanent --new-zone=customzone

And now you can verify what is going under the hood. You should find the zone file in the /etc/firewalld/zones/ directory, in this case it is customzone.xml as well as you can do this using the firewall-cmd tool by typing:

1
firewall-cmd --permanent --get-zones

You should see the similar output.

1
2
[root@crosp zones]# firewall-cmd --permanent --get-zones
block customzone dmz drop external home internal public trusted work

Editing a zone file

As stated above you have two choices of managing firewalld. For configuring our custom zone I will use manual approach for the sake of understanding what is going internally while you are using the command line tool.

Before making any changes to the zone file, please make sure that by default you have allowed inbound ICMP packets by using the ping command.

1
2
3
MacBookCROSP:~ crosp$ ping <your_server_domain_or_ip>
PING <your_server_domain_or_ip> (<your_server_ip>): 56 data bytes
64 bytes from <your_server_domain_or_ip>: icmp_seq=0 ttl=51 time=42.044 ms

Now open open the custom zone file /etc/firewalld/zones/customzone.xml and modify it as follows.

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="utf-8"?>
<zone target="DROP">
  <short>Custom Zone Configuration</short>
  <description>All incomming connections are blocked by default. Only specific services are allowed.</description>
  <service name="http"/>
  <service name="ssh"/>
  <service name="https"/>
</zone>

The first attribute that requires attention is target=”DROP”. Here is the explanation from the Zone Official Documentation Page.

target="ACCEPT|%%REJECT%%|DROP"

Can be used to accept, reject or drop every packet that doesn’t match any rule (port, service, etc.). The ACCEPT target is used in trusted zone to accept every packet not matching any rule. The %%REJECT%% target is used in block zone to reject (with default firewalld reject type) every packet not matching any rule. The DROP target is used in drop zone to drop every packet not matching any rule. If the target is not specified, every packet not matching any rule will be rejected.

In our case we have set this attribute to target=”DROP” resulting in blocking absolutely all incoming network connections. And finally we allow connections for specific services, in this case HTTP, HTTPS and SSH, all other network packets will be dropped.

Enabling a zone

First of all reload the firewall’s configuration to get the latest changes by typing:

1
firewall-cmd --reload

Now you are ready to enable and use the custom zone file. If you want to use the created zone by default, execute the following command:

1
firewall-cmd --set-default-zone=customzone

After that you can verify that your zone is used as the default:

1
2
[root@crosp zones]# firewall-cmd --get-default-zone
customzone

Ensure that your network interface is assigned to the new zone now:

1
2
[root@crosp zones]# firewall-cmd --get-zone-of-interface=<interface>
customzone

Otherwise you can change an interface zone with the help of following command:

1
firewall-cmd --zone=customzoen--change-interface=<interface>

If you are interested what’s going on under the hood then open your interface configuration file /etc/sysconfig/network-scripts/ifcfg-<interface>. And you will see the following line in the file.

1
ZONE=customzone

Testing a custom zone

Now when you have your custom zone set up check if it works as expected.

1
2
3
4
MacBookCROSP:~ crosp$ ping <your_server_domain_or_ip>
PING <your_server_domain_or_ip> (<your_server_ip>): 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1

And eventually check the allowed services.

1
2
3
4
5
6
7
MacBookCROSP:~ crosp$ curl <your_server_domain_or_ip>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
	<head>
		<title>Test Page for the Apache HTTP Server on CentOS</title>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

Conclusion

In this tutorial I’ve described how to create a custom zone file. Everything done manually could be done with the help of the firewall-cmd tool. Besides that firewalld has much more capabilities than just setting up zones like rich-language, direct interface and others. So it is worth to acquire more knowledge in order to make your system even more protected. If you have any questions please feel free to leave comments below.