Block Brute-Force requests with Firewall Daemon from Bash Script
Firewall Daemon can help to protect against ongoing brute force attacks by detecting attempted attacks on the Linux host. To permanently protect the host from suspicious sources they can be blocked. The following bash script prevent from suspicious requests by append the IP address as argument and set it to reject
using firewall-cmd
.
#!/bin/bash
# permanently reject or remove suspicious sources by kernel firewall
# dependency: firewalld (fail2ban optional)
if [[ $1 == "add" && $2 =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
echo "$2 add to reject"
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="'$2'" reject'
elif [[ $1 == "remove" && $2 =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
echo "$2 being to remove"
firewall-cmd --permanent --zone=public --remove-rich-rule='rule family="ipv4" source address="'$2'" reject'
elif [[ $1 == "add6" && $2 =~ ^[A-Za-z0-9]{1,4}\:[A-Za-z0-9]{1,4}\: ]]; then
echo "$2 add to reject"
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv6" source address="'$2'" reject'
elif [[ $1 == "remove6" && $2 =~ ^[A-Za-z0-9]{1,4}\:[A-Za-z0-9]{1,4}\: ]]; then
echo "$2 being to remove"
firewall-cmd --permanent --zone=public --remove-rich-rule='rule family="ipv6" source address="'$2'" reject'
else
echo "Usage: fw add|remove [source IPv4]"
echo " fw add6|remove6 [source IPv6]"
exit 0
fi
firewall-cmd --reload
sleep 1
if [[ -f /run/fail2ban/fail2ban.pid ]]; then
systemctl restart fail2ban
else
echo "fail2ban not running"
fi
sleep 2
firewall-cmd --list-all
The script was written on Debian 10 (buster), Debian has ufw installed by default, so you have to install firewalld and disable ufw, as well as on Ubuntu 20. On RHEL and CentOS 7+ family and Fedora firewalld is default and the script can be used.
Save the script lines into a file, for instance as fw
and make them executable, then run the script to block an ip address with add
.
chmod u+x fw
./fw add 192.168.89.56
Use remove
to swipe the ip address from the chain if desired.
How to enable Firewalld on Debian
The firewalld package is available on the official Debian 10 repositories. Installation is quick as shown below commands.
sudo apt update
sudo apt -y install firewalld
Install firewalld in the terminal as root or user with sudo privileges.
sudo ufw disable
If ufw
is activated, the uncomplicated firewall (ufw) for managing the netfilter must be deactivated in order to make firewalld
to the standard firewall.
$ sudo systemctl enable firewalld
$ sudo systemctl start firewalld
Run the firewall daemon and activate it for the system start.
$ sudo firewall-cmd --state
running
Check if firewall daemon is running and the service is available.
$ sudo firewall-cmd --reload
Load the new firewall rules and keep the status information.
Using Debian after run firewall-cmd --reload
the error appears:
Error: COMMAND_FAILED: ‘/usr/sbin/ip6tables-restore -w -n’ failed: ip6tables-restore v1.8.2 (nf_tables:
line 4: RULE_REPLACE failed (no such file ordirectory): rule in chain OUTPUT
The solution is to run update-alternatives to force Debian to use iptables instead of nftables.
$ sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
$ sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
After switching from nftables to iptables, restart the Linux machine with reboot
.
Firewalld configuring
Firewalld is a firewall-management solution that acts as a front-end for the iptables packet filter system provided by the Linux kernel. firewall-cmd
is the utility used to manage the firewall configuration. The firewalld
daemon manages groups of rules using entities called “zones”. Zones are like sets of rules that determine what traffic to allow based on the known trust of the networks to which the computer is connected. A zone is assigned to the network interfaces in order to determine the behavior that the firewall should allow.
Assign an interface to the zone public using the firewall-cmd
tool, check zones and interfaces with the command.
$ sudo firewall-cmd --zone=public --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces:
sources:
services: dhcpv6-client https ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
rule family="ipv4" source address="10.10.10.1" reject
If no network interface appears at interfaces
, this must still be assigned to the zone, to querying the interface name use ip
or ifconfig
(net-tools).
$ ip link
$ ip addr
$ ifconfig
Here at the virtual Debian (buster) it is Link 2 ens33
.
The interface ens33
we assign to the default zone public.
$ sudo firewall-cmd --zone=public --change-interface=ens33
Check the interface assigned to the zone use get-active-zones.
$ firewall-cmd --get-active-zones
public
interfaces: ens33
$ sudo firewall-cmd --zone=public --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33
sources:
services: dhcpv6-client https ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
rule family="ipv4" source address="10.10.10.1" reject
The interface ens33 is assigned to zone public.
Interacting Fail2ban and firewalld
Fail2ban (failure leads to ban) is an IPS framework developed in Python to prevent attacks. It runs on all Unixoid OS that is based on a managable packet filter system or a firewall such as iptables or firewalld on Linux.
ln the script (above), if available and executed, the addresses banned by fail2ban are restored to their previously active state after firewalld has been processed.
firewall-cmd add | remove source address
Using firewall-cmd to reject suspicious requests from sources.
$ sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.10.10.1" reject'
The locked IP address can be removed with the following command line.
$ sudo firewall-cmd --permanent --remove-rich-rule='rule family="ipv4" source address="10.10.10.1" reject'
Execute the rule entered through the firewall daemon.
$ sudo firewall-cmd --reload
Help to use firewall-cmd
Check the entered and enabled rules of the Public zone.
$ sudo firewall-cmd --zone=public --list-all
Get current firewall rules with the following commands.
$ sudo firewall-cmd --list-all
Use the iptables command to list current rules.
$ sudo iptables -vxnL
Show standard zone for connections and interfaces.
$ firewall-cmd --get-default-zone
Set a zone as the default zone.
$ sudo firewall-cmd --set-default-zone=zone_name
Output currently active zones.
$ firewall-cmd --get-active-zones
Get output of predefined zones.
$ firewall-cmd --get-zones
Get help and man page of firewall-cmd.
$ firewall-cmd --help
$ man firewall-cmd
The next related post might also be helpful, see in Block IP address using Linux Firewall.