Sunday, March 3, 2019

What Is Firewalld & How To Configure Rules?

Image result for firewallIn this post we’d talk about ‘firewalld’ and it is benefits and how to get it configured in RHEL7 and above systems.

A Note on netfilter

In Linux ‘netfilter’ is being used which is a powerful network filtering sub-system. This allows kernel modules to inspect each packet traversing the system, and it could be dropped or rejected or allowed in a programmatic way and this applies to all incoming, outgoing and forwarded packets. So, in earlier RHEL6.x version there is ‘iptables’ being used which is a well-known netfilter program. However, in RHEL7.x version and above we've ‘firewalld’ in-place of ‘iptables’.

What is firewalld?

The new ‘firewalld’ is more powerful then earlier ‘iptables’ which can configure & monitor system firewall rules. A firewall is a way to protect machines from an unwanted traffic from outside. It covers both IPv4 & IPv6 rules and also ‘etables’  (to manage software bridges) settings. In earlier RHEL6.x version this was not possible using ‘iptables’, hence, there was ‘ip6tables’ & ‘etables’.

This daemon comes from ‘firewalld’ package which is installed by default in ‘base’ installation mode, however, not in ‘minimal’ mode.

How does firewalld works?

In ‘firewalld’, all network traffic is classified into zones. Based on criteria such as source IP address of a packet or incoming network interface, traffic gets diverted into corresponding zones where appropriate rules gets applied. Each zone would have it’s own list of ports or services to be opened or closed.

The below diagram shows a simple demonstration of a firewalld function. In this sketch it is assumed that the system firewalld is configured to allow only communication on ports 22 & 25, and rest all requests are blocked/denied.

There are zones in firewalld…….

So, firewalld would inspect every packet that is traversing into the system, first it would be checked for source address, if that source address is associated with a zone then rules of that zone would be applied. If source IP address doesn’t belong to a zone, then rules from incoming network zone would be parsed. Zones are predefined sets of rules. Network interfaces and sources can be assigned to a zone.

If a network interface is not associated with a zone, then default zone would be used. The public zone would be used as a default zone.

Each zone would have its own list of ports/services to be allowed or blocked, so if packet in a particular zone doesn’t match permitted port/protocol/service then it would generally be rejected. There is ‘trusted zone’ which allows all traffic by default which is one exception.

There are number of predefined zones which are suitable for various purposes such as ‘trusted’, ‘home’, ’internal’, ’public’, etc., available.  Like-wise there are predefined services defined using which a user or administrator could allow traffic to pass through firewall. The command ‘firewall-cmd --get-services’ could be used to list out predefined services.

Let’s see the implementation of firewalld

By default ‘firewalld’ package gets installed and services gets started. To check if the 'firewalld' service is running or active, run the below commands:

# systemctl status firewalld → this would tell us the service status

# systemctl is-active firewalld → shows if firewalld is currently active

# systemctl is-enabled firewalld → shows if the firewalld service is set to start on poweron/reboot

To find out if firewalld service is active and running using 'firewall-cmd' command:

# firewall-cmd --state

The predefined zones are stored in the "/usr/lib/firewalld/zones/" directory and can be instantly applied to any available network interface. These files are copied to the "/etc/firewalld/zones/" directory only after they are modified.

Configure firewall rules

There are three ways to configure rules in firewalld:
→ By editing files in  ‘/etc/firewalld/’ folder (not recommended).
→ By using ‘firewall-config’ command
→ By using ‘firewall-cmd’ command.

Let’s configure firewall settings by using ‘firewall-cmd’ command. So, first let’s start by querying for default zone being used.

[root@test ~]# firewall-cmd --get-default-zone

To find out list of zones available:

[root@test ~]# firewall-cmd --get-zones
block dmz drop external home internal public trusted work

To find out list of configured interfaces, ports, services for dmz zone the following command could be used. If zone option is not specified then it would list out details for default zone:

[root@test ~]# firewall-cmd --list-all --zone=dmz
{ like-wise “firewall-cmd --list-services" would show only list of services being enabled on default zone & "firewall-cmd --list-ports” to show only ports allowed on default zone }

Let’s see how to allow packets to pass through http (80) port on default zone. So, the command is:(one could skip the --zone parameter as the firewalld would use default zone if not mentioned) :
[root@test ~]# firewall-cmd --add-service=http --zone=public --permanent

Now, let’s see how to add a customized port number “4567/tcp” in firewall settings so that traffic would pass through in the default zone which is ‘public’:
[root@test ~]# firewall-cmd --permanent --add-port 4567/tcp --zone=public

These changes are not effective immediately, only after service restart/reload or system reboot. Without the "--permanent" option, a change will only be part of the runtime configuration.

Hence, after making changes to the rules table, run the command "firewall-cmd --reload" to make the new rules become effective. Any rules which are only part of runtime would be lost. Finally, run the command "firewall-cmd --list-all" command to find out all/active/enabled services/ports in firewalld default zone.

*The "firewall-cmd --runtime-to-permanent" command is also available to make runtime changes permanent which doesn't need the requirement to run "firewall-cmd --reload".

Also, there is 'firewall-cmd --remove-port' & 'firewall-cmd --remove-service' available to get a port/service removed from firewall rule set.

→ To list out all active/enabled ports in firewalld in default zone:

[root@test ~]# firewall-cmd --list-ports
80/tcp 4567/tcp

→ To list out all active/enabled services in firewalld in default zone:

[root@test ~]# firewall-cmd --list-services
ssh dhcpv6-client ftp http https

→ To list out all active/enabled services/ports in firewalld in default zone:

[root@test ~]# firewall-cmd --list-all
public (active)
 target: default
 icmp-block-inversion: no
 interfaces: enp0s8 enp0s3 br-demo
 services: ssh dhcpv6-client ftp http https
 ports: 80/tcp 4567/tcp
 masquerade: no
 rich rules:

Note: Using ‘--permanent’ parameter one could add/modify the rules and makes it persistent across reboots. Anytime running the command “firewall-cmd --reload” would drop runtime configurations and apply persistent configuration.

There is also 'rich-rule' set available which could be used to add more sophisticated firewall rules. Some of the use cases are like specific range of IP address on a particular port but deny access to one of the IPs in that range could be done using 'rich-rules'. This blog page shows a simple/basic configurations done in firewalld, users may have to refer further documentations to get to know about advanced/complex firewall configurations.

No comments: