×
Community Blog Managing Your Firewall on Centos 7 with Firewalld

Managing Your Firewall on Centos 7 with Firewalld

This article explains how firewalld works and shares some options to properly secure your server with firewalld.

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/zones directories 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 --masquerade option

  # 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 --reload option

  # 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.

0 0 0
Share on

Alibaba Clouder

1,935 posts | 433 followers

You may also like

Comments