Managing Your Firewall on Centos 7 with Firewalld

Alibaba Cloud
11 min readMar 14, 2019

--

By Alain Francois, Alibaba Cloud Tech Share Author. Tech Share is Alibaba Cloud’s incentive program to encourage the sharing of technical knowledge and best practices within the cloud community.

Most systems are currently connected to the Internet, which expose them to outsiders users who may try to gain unauthorized access directly by setting up illegal connections, intercepting remote communications or by pretending to be a valid user. There are some ways of protecting against such attacks, such as firewalls, encryption, and authentication procedures.

A firewall is a layer of protection configured based on pre-defined rules between a private and a public network to segregate traffic. Inbound and outbound data packets are intercepted and inspected by the firewall, allowing only non-threatening packets to pass through. There are two powerful firewalls in Linux systems which are firewalld and iptables. The Linux kernel implements firewalling via the netfilter framework to inspect each packet. To configure which packets are allowed and which are not, firewalld is the default solution on RedHat based systems such as Centos 7

Understanding How Firewalld Works

Centos administrators can manage their environment by setting the packets rules with firewalld. FirewallD for Firewall Daemon was developed as a complete new solution for managing Linux firewalls through systemd using the firewalld.service unit file where the runtime configuration is read from /etc/sysconfig/firewalld.

The firewalld service stores the firewall rules in XML file format at two different locations: the system-defined rules in the /usr/lib/firewalld directory and the user-defined rules in /etc/firewalld. Normally, instead of loading rules offline from file, you add them directly to the FirewallD daemon. The files at the former location can be used as templates for adding or modifying new rules. We simply need to copy the required file to the /etc/firewalld/services directory and make necessary updates. The firewalld service reads the files located in /etc/firewalld and applies the rules defined in them.

You need to make sure that the firewalld service is running, if not start it and enable it for boot start

# systemctl start firewalld && systemctl enable
Created symlink from /etc/systemd/system/multi-user.target.wants/firewalld.service to /usr/lib/systemd/system/firewalld.service.

Then check its state

# firewall-cmd --state
running

Firewalld gives more flexibility with its concept of network zones and service names. The firewall-cmd command is the powerful command line tool that is used to create, modify, manage, and remove rules that allow or deny traffic by service or port through the firewalld service.

The Purpose of Zones in Firewalld

The first point is the firewalld zones that define the level of trust for different kinds of network connections and can be divided in two types: mutable where the modification to its definition is allowed and immutable where its definition cannot be changed. Every packet that comes into the system is analyzed for its source address, and based on that source address, firewalld analyzes to see if the packet belongs to a specific zone. Each zone can have several connection, but a connection can belong only to one zone.

The use of zones is particularly important on servers with multiple interfaces because it allows administrators to easily assign a specific set of rules. The custom zone configuration files are located in /etc/firewalld/zones and there is a default zone set in the /etc/firewalld.conf configuration file which is predefined as public zone. Firewalld works with some default zones defined as below:

  • trusted immutable: allow all network connections
  • drop immutable: all incoming packets are dropped and there is no reply but ongoing packets are accepted
  • block immutable: all incoming packets are rejected with ICMP host-prohibited messages to the sender
  • public mutable: it’s the default zone for all the newly created network interface. It represents a public area for untrusted network where only limited connections are accepted. It means to don’t trust the other computers
  • external mutable: for external networks with NAT masquerading enabled where only selected incoming packets are accepted, protecting a local network.
  • dmz mutable: for computers in a demilitarized zone publicly accessible, here only selected incoming packets are accepted. The computer have limited access to the internal network.
  • home mutable: for trusted home networks with only selected incoming packets accepted. Most computers on the same network are trusted
  • work mutable: for trusted work networks with only selected incoming connections accepted.
  • internal mutable: for internal networks with a restriction on incoming connections.

The zone files are stored in the /usr/lib/firewalld/zones/ or /etc/firewalld/zonesdirectories saved with .xml extensions

# ls /usr/lib/firewalld/zones/
block.xml drop.xml home.xml public.xml work.xml
dmz.xml external.xml internal.xml trusted.xml

You can have a look on the content of a zone

# cat /usr/lib/firewalld/zones/dmz.xml 
<?xml version="1.0" encoding="utf-8"?>
<zone>
<short>DMZ</short>
<description>For computers in your demilitarized zone that are publicly-accessible with limited access to your internal network. Only selected incoming connections are accepted.</description>
<service name="ssh"/>
</zone>

For a given zone you can configure services, ports, masquerading, port forwarding, and ICMP filter.

Manage the Zones with firewall-cmd

You manage the zones with the firewall-cmd command by using some parameters:

  • — get-zones: displays all the zones in your environment
  • — get-default-zone: shows the actual default zone
  • — list-all: lists the configuration (services) of the default zone only
  • — list-all-zones: lists the configuration (services) of all the zones presents at once
  • — get-active-zones: shows all the actives zones. You can have more than one zone.

and you can list the zones with the --get-zones parameter

# firewall-cmd --get-zones
block dmz drop external home internal public trusted work

You can check the default zone with the --get-default-zone

# firewall-cmd --get-default-zone
public

Each zone has a specific configuration that you can also check as with the default zone like below

# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33 ens34
sources:
services: dhcpv6-client ssh
ports: 3389/tcp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:

You can see that the default zone is also the active zone. With that, we can imagine that we can check the active zone. It’s possible with the --get-active-zones

# firewall-cmd --get-active-zones
public
interfaces: ens33 ens34

You can list the configurations of all the zones

# firewall-cmd --list-all-zones
block
target: %%REJECT%%
icmp-block-inversion: no
interfaces:
sources:
services:
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:


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


drop
target: DROP
icmp-block-inversion: no
interfaces:
sources:
services:
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:


external
target: default
icmp-block-inversion: no
interfaces:
sources:
services: ssh
ports:
protocols:
masquerade: yes
forward-ports:
source-ports:
icmp-blocks:
rich rules:


home
target: default
icmp-block-inversion: no
interfaces:
sources:
services: ssh mdns samba-client dhcpv6-client
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:


internal
target: default
icmp-block-inversion: no
interfaces:
sources:
services: ssh mdns samba-client dhcpv6-client
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:


public (active)
target: default
icmp-block-inversion: no
interfaces: ens33 ens34
sources:
services: dhcpv6-client ssh
ports: 3389/tcp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:


trusted
target: ACCEPT
icmp-block-inversion: no
interfaces:
sources:
services:
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:


work
target: default
icmp-block-inversion: no
interfaces:
sources:
services: ssh dhcpv6-client
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:

You can choose a specific zone to see its configurations with the --zone= parameter

# firewall-cmd --zone=dmz --list-all
dmz
target: default
icmp-block-inversion: no
interfaces:
sources:
services: ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:

Edit a Zone

You can decide to change the default zone to set another one

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

You can see that the change took effect. You can check it with the --get-default-zone

# firewall-cmd --get-default-zone
work

A zone can be assigned to a server interface. It means that if a server has multiples interfaces, you can associate a zone on each interface to implement your network strategy. This can be done by the combination of --zone= and --change-interface= parameters

# firewall-cmd --zone=external --change-interface=ens34
success

By assigning a new zone to an interface, that zone is automatically activated

# firewall-cmd --get-active-zones
work
interfaces: ens33
external
interfaces: ens34

You can also check if a specific interface belongs to a zone with the --query-interface=parameter as below

# firewall-cmd --zone=work --query-interface=ens34
no

You can see that the interface ens34 is not configured for the work zone.

It is possible to add, remove, and query zones for masquerading with the --masqueradeoption

# firewall-cmd --zone=work --add-masquerade
success

And you can check the result

# firewall-cmd --zone=work --list-all | grep masq
masquerade: yes

You remove the masquerade with the --remove-masquerade option.

Firewalld Services

The second point is firewalld service which is not the same as a service in systemd. Some default services are defined in firewalld allowing administrators to easily accept or deny access to
specific ports on a server. A service can be seen as network protocols or ports as well as a list of firewall helper modules automatically loaded if a service is enabled. If you want to run a service such as a Web server, an FTP server, or SSH encrypted connections, you must specify them in the firewalld services during the configuration.

There is a configuration file behind each service explaining which UDP or TCP ports are involved, and if so required, which kernel modules must be loaded. The use of predefined services makes it easier for the user to enable and disable access to a service. The services are stored in the /usr/lib/firewalld/services or etc/firewalld/services

# ls /usr/lib/firewalld/services
amanda-client.xml kadmin.xml puppetmaster.xml
amanda-k5-client.xml kerberos.xml quassel.xml
......
......
https.xml pmwebapi.xml transmission-client.xml
http.xml pop3s.xml vdsm.xml
imaps.xml pop3.xml vnc-server.xml
imap.xml postgresql.xml wbem-https.xml
ipp-client.xml privoxy.xml xmpp-bosh.xml
ipp.xml proxy-dhcp.xml xmpp-client.xml
ipsec.xml ptp.xml xmpp-local.xml
iscsi-target.xml pulseaudio.xml xmpp-server.xml

You can check the content of the content of a service

# cat /usr/lib/firewalld/services/https.xml 
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>Secure WWW (HTTPS)</short>
<description>HTTPS is a modified HTTP used to serve Web pages when security is important. Examples are sites that require logins like stores or web mail. This option is not required for viewing pages locally or developing Web pages. You need the httpd package installed for this option to be useful.</description>
<port protocol="tcp" port="443"/>
</service>

Manage Services with Firewalld

The services are still managed with the firewall-cmd command followed by the --get-services parameter which shows a list of names used by firewalld to identify some network services:

# firewall-cmd --get-services
RH-Satellite-6 amanda-client amanda-k5-client bacula bacula-client bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc ceph ceph-mon cfengine condor-collector ctdb dhcp dhcpv6 dhcpv6-client dns docker-registry
....

You can list only the services currently in use in the default zone

# firewall-cmd --list-services
ssh dhcpv6-client

It’s possible to list only the open ports of a zone. The result will be empty if there is no port

# firewall-cmd --zone=internal --list-ports

If you don’t specify a zone, the ports of the default zone will be listed.

Add and Remove Services and Ports

When you add (open) or remove (close) a service or a port on firewalld, you don’t need to restart the entire firewalld service itself but just to reload it. Adding a service is done with the --add-service= option. You can choose a specific zone. When you don't specify a zone, the default zone is considered.

You can add a service by specifying the network protocol to use

# firewall-cmd --add-service=https
success

You can instead add a port and need to indicate either TCP or UDP

# firewall-cmd --zone=home --add-port=5901-5910/tcp
success

The services and ports added are not persistent. If you restart the server or the firewalld service, you will lose the configuration. To make the configuration always permanent, you need to use the --permanent option and then, reload firewalld to take effect with --reloadoption

# firewall-cmd --permanent --zone=public --add-port=993/tcp
success

Now reload. For each configuration of firewalld, make sure to reload the service on your side. We will not show the reload command everytime.

# firewall-cmd --reload 
success

It is possible to add a range of ports

# firewall-cmd --permanent --zone=public --add-port=6350-6400/tcp && firewall-cmd --reload
success
success

You can remove a service with the --remove-service= option. You can also specify a zone (or not) for the default zone. Don't forget to reload after a modification

# firewall-cmd --permanent --remove-service=https
success

You can remove a port with the remove-port= for a specific zone if you want

# firewall-cmd --permanent --zone=external --remove-port=143
success

You can also check if a service is enabled on a zone with the query-service= option

# firewall-cmd --zone=external --query-service=ssh
yes

The same can be done with a port with the query-port=

# firewall-cmd --zone=public --query-port=3389/tcp
yes

Add and Remove a Source

A source in firewalld represents an ip address to be used in order to filter packets through a zone. You can add a source with the --add-source= option

# firewall-cmd --permanent --zone=trusted --add-source=172.16.8.0/24
success

You can display only all the sources of a zone

# firewall-cmd --zone=trusted --list-sources
172.16.8.0/24

Now you can remove a source

# firewall-cmd --permanent --zone=trusted --remove-source=172.16.8.0/24
success

Configure Port Forwarding

In the network policy, you can need to forward inboud packets from one port to another customized one for a zone. To do this in firewalld, you need to enable the masquerading for the zone. The masquerading is form of address translation where an address of a private network is mapped behind a public address. This is generally done for external network.

Check if masquerading is already enabled

# firewall-cmd --zone=external --query-masquerade
yes

if it’s not in your case, then do it. You can make the change permanent

# firewall-cmd --permanent --zone=external --add-masquerade

Let us assume that we will forward the packets for port 143/tcp to port 4545/tcp at a new address.

# firewall-cmd --permanent --zone=external --add-forward-port=port=143:proto=tcp:toport=4545:toaddr=192.1.0.20
success

After the reload, you can check by listing the zone information. You can delete the forwarding with

# firewall-cmd --permanent --zone=external --remove-forward-port=port=143:proto=tcp:toport=4545:toaddr=192.1.0.20
success

Allow and Block ICMP Packets

Normally to secure a server, it’s recommended to block the icmp packets. There are some types of ICMP paquets such as echo reply and echo request. It’s interesting to know the type to block and it’s possible with the --get-icmptypes option

# firewall-cmd --get-icmptypes
address-unreachable bad-header communication-prohibited destination-unreachable echo-reply echo-request fragmentation-needed host-precedence-violation host-prohibited host-redirect host-unknown host-unreachable
....
....

Now you can choose the type of packet to block with the --add-icmp-block= option

# firewall-cmd --permanent --zone=external --add-icmp-block=echo-reply
success

Then reload and check the zone to see the result

# firewall-cmd --zone=external --list-all | grep icmp
icmp-block-inversion: no
icmp-blocks: echo-reply

Add and Remove Multiple Ports and Services at Once

Normally with firewalld you can not manage multiples services or ports in one command. But we can see how it’s possible to do it with a script bash. The idea is to create a loop into which we will list the ports or services to be added in the firewalld command. You can decide if you want the --permanent option for the configuration

# vim firewalld-ports.sh

#!/bin/bash
for i in 443 465 993 2626 3232
do
firewall-cmd --permanent --zone=public --add-port=${i}/tcp && firewall-cmd --reload
done

Don’t forget to reload in the script. Then change the permission

# chmod +x firewalld-ports.sh

Now you can run the script

# ./firewalld-port.sh 
success
success
success
success
success
success
success

If you want to remove multiple ports, just change the option with --remove-port. If you want to add or remove multiple services, just edit the script file by changing the list of ports to the list of services and the required option --add-service or --remove-service

# vim firewalld-services.sh    #!/bin/bash
for i in https imaps snmp smtps
do
firewall-cmd --permanent --zone=public --add-service=${i} && firewall-cmd --reload
done

Now you understand how firewalld works and some options to properly secure your server. With Firewalld, based on which zones and services you configure, you can increase the network security by controlling the traffic to allow or disallow. Service can be convenient to use around ports. Firewalld offers a graphical interface which can be used with firewall-config.

Reference:https://www.alibabacloud.com/blog/managing-your-firewall-on-centos-7-with-firewalld_594550?spm=a2c41.12636948.0.0

--

--

Alibaba Cloud
Alibaba Cloud

Written by Alibaba Cloud

Follow me to keep abreast with the latest technology news, industry insights, and developer trends. Alibaba Cloud website:https://www.alibabacloud.com

No responses yet