FirewallD on CentOS
July 11, 2017 | Security LinuxFirewallD 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):
- FirewallD uses zones and services instead of chain and rules.
- 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