FirewallD on CentOS

July 11, 2017 | Security Linux

FirewallD is a frontend controller / wrapper for iptables used to implement persistent network traffic rules. Working with FirewallD has two main differences compared to directly controlling iptables (Ref: Introduction to FirewallD on CentOS):

  1. FirewallD uses zones and services instead of chain and rules.
  2. It manages rulesets dynamically, allowing updates without breaking existing sessions and connections.

FirewallD is included by default with CentOS 7 and is enabled by default.

[root@pulpo-admin ~]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2017-07-11 14:12:36 PDT; 34min ago
     Docs: man:firewalld(1)
 Main PID: 10906 (firewalld)
   CGroup: /system.slice/firewalld.service
           └─10906 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid

Jul 11 14:12:35 pulpo-admin.ucsc.edu systemd[1]: Starting firewalld - dynamic firewall daemon...
Jul 11 14:12:36 pulpo-admin.ucsc.edu systemd[1]: Started firewalld - dynamic firewall daemon.

firewall-cmd

firewall-cmd is the command line client of the FirewallD. It provides interface to manage runtime and permanent configuration.

[root@pulpo-admin ~]# firewall-cmd --state
running

Firewalld uses two configuration sets: Runtime and Permanent. Runtime configuration changes are not retained on reboot or upon restarting FirewallD whereas permanent changes are not applied to a running system.

Zones

Right after the minimal install of CentOS on pulpo-admin, the default zone is public:

[root@pulpo-admin ~]# firewall-cmd --get-default-zone
public

and all active network interfaces are bound to the public zone:

[root@pulpo-admin ~]# firewall-cmd --get-active-zones
public
  interfaces: eno1 ens1f0

To list all zones and their configurations:

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

[root@pulpo-admin ~]# firewall-cmd --list-all-zones

Let’s remove the GbE interface eno1 from the public zone and bind it to the trusted zone (Ref: RHEL7: How to get started with Firewalld):

[root@pulpo-admin ~]# firewall-cmd --permanent --zone=trusted --change-interface=eno1
The interface is under control of NetworkManager, setting zone to 'trusted'.
success

But that is not enough. The interface is under control of NetworkManager. Be default, all interfaces are bound to the default zone, which is public. To really permanently bind eno1 to the trusted zone, we need to modify NetworkManager configuration. We can use nmcli, Network Manager Command Line Interface, to do so.

[root@pulpo-admin ~]# nmcli con show
NAME    UUID                                  TYPE            DEVICE
eno1    1a641f99-21ff-4324-9166-963e063c2c7b  802-3-ethernet  eno1
ens1f0  bdc5d857-140d-48e2-a953-7d422e2405ba  802-3-ethernet  ens1f0
eno2    3daeaadd-aaab-4a04-89ad-5f41e2f4e859  802-3-ethernet  --
ens1f1  b8522386-019a-4463-83c2-67bbe6216243  802-3-ethernet  --

[root@pulpo-admin ~]# nmcli con mod eno1 connection.zone trusted

[root@pulpo-admin ~]# nmcli con up eno1
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/2)

Alternatively, we can change the zone of eno1 by editing the file /etc/sysconfig/network-scripts/ifcfg-eno1. Add ZONE=trusted to the file; then run nmcli con reload.

Verify that eno1 is now bound to trusted:

[root@pulpo-admin ~]# firewall-cmd --get-zone-of-interface=eno1
trusted

And we now have 2 active zones:

[root@pulpo-admin ~]# firewall-cmd --get-active-zones
public
  interfaces: ens1f0
trusted
  interfaces: eno1

Fail2ban

Fail2ban scans log files and bans IP addresses that makes too many password failures. It updates firewall rules to reject the IP address. Fail2Ban can read multiple log files such as sshd or Apache web server ones.

Fail2ban packages are available from the EPEL repository. To install Fail2ban with support for manipulating firewalld rules (Ref: Install Fail2ban on Centos 7 to Protect SSH via firewalld):

# yum install -y fail2ban-firewalld

To configure Fail2ban, add a file /etc/fail2ban/jail.local with the following contents:

[sshd]
enabled = true
maxretry = 3
bantime = 86400

Enable and start the fail2ban service:

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

Verify that the sshd jail has indeed been enabled:

# fail2ban-client status
Status
|- Number of jail:      1
`- Jail list:   sshd

Verify that Fail2ban has added a FirewallD rule to block IP addresses that are generating failed login attempts:

# firewall-cmd --direct --get-all-rules
ipv4 filter INPUT 0 -p tcp -m multiport --dports ssh -m set --match-set fail2ban-sshd src -j REJECT --reject-with icmp-port-unreachable

An ipset list called fail2ban-sshd has been created. We can list the current contents of the list:

# ipset list fail2ban-sshd
Name: fail2ban-sshd
Type: hash:ip
Revision: 1
Header: family inet hashsize 1024 maxelem 65536 timeout 86400
Size in memory: 16592
References: 1
Members:
201.249.207.212 timeout 86393

or

# fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed: 0
|  |- Total failed:     1
|  `- Journal matches:  _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
   |- Currently banned: 1
   |- Total banned:     1
   `- Banned IP list:   201.249.207.212

References