In my last article I shared the steps to install ClamAV (antivirus tool for Linux) to protect your node against Trojans, Malware and other types of viruses. In this article I will share the steps to secure SSH and root login with fail2ban. Secure Shell (SSH) in itself is a cryptographic network protocol for operating network services securely over an unsecured network. But some servers are publicly accessible, so they may need an extra reinforcement to their SSH service. For this task, we will be installing a tool called Fail2Ban, which is a very reliable tool that helps protect many services from brute-force attacks. It basically scans the log file for the specific service and looks for failed login attempts in order to block them.
Fail2ban scans log files and bans IPs that show the malicious signs — too many password failures, seeking for exploits, etc. Generally Fail2Ban is then used to update firewall rules to reject the IP addresses for a specified amount of time, although any arbitrary other action (e.g. sending an email) could also be configured. Out of the box Fail2Ban comes with filters for various services (apache, courier, ssh, etc).
We need to install the EPEL repository first:
# yum install epel-release
Then we need to install it with
Rsyslog, since it scans the log output taken from Rsyslog:
# yum install fail2ban rsyslog -y
Steps to secure SSH and root login with fail2ban
Then we go ahead to configure it in order to secure SSH. We need to create a file named
sshd.local in the jail folder of
Fail2Ban and add below content
# cat /etc/fail2ban/jail.d/sshd.local [DEFAULT] bantime = 172800 maxretry = 5 [sshd] enabled = true filter = sshd action = iptables[name=SSH, port=ssh, protocol=tcp] maxretry = 5
This will ban attacks for
48 hours. Then we start the service and enable it for system startup services:
# systemctl start fail2ban # systemctl status fail2ban ● fail2ban.service - Fail2Ban Service Loaded: loaded (/usr/lib/systemd/system/fail2ban.service; disabled; vendor preset: disabled) Active: active (running) since Fri 2018-11-09 07:58:09 IST; 3s ago Docs: man:fail2ban(1) Process: 2531 ExecStart=/usr/bin/fail2ban-client -x start (code=exited, status=0/SUCCESS) Main PID: 2534 (fail2ban-server) Tasks: 3 CGroup: /system.slice/fail2ban.service └─2534 /usr/bin/python2 -s /usr/bin/fail2ban-server -s /var/run/fail2ban/fail2ban.sock -p /var/run/fail2ban/fail2ban.pid -x -b Nov 09 07:58:08 node1.example.com systemd: Starting Fail2Ban Service... Nov 09 07:58:08 node1.example.com fail2ban-client: 2018-11-09 07:58:08,985 fail2ban.server : INFO Starting Fail2ban v0.9.7 Nov 09 07:58:08 node1.example.com fail2ban-client: 2018-11-09 07:58:08,985 fail2ban.server : INFO Starting in daemon mode Nov 09 07:58:09 node1.example.com systemd: Started Fail2Ban Service.
Now with this configuration,
fail2ban will keep monitoring the
/var/log/secure log file based on your distribution and as soon as it finds multiple failed attempt (based on
maxretry value) from the same IP address then it will create a new
IPTABLES rule to block ssh from the respective node for the provided
My iptables rule before
# iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination f2b-SSH tcp -- anywhere anywhere tcp dpt:ssh ACCEPT udp -- anywhere anywhere udp dpt:domain ACCEPT tcp -- anywhere anywhere tcp dpt:domain ACCEPT udp -- anywhere anywhere udp dpt:bootps ACCEPT tcp -- anywhere anywhere tcp dpt:bootps Chain FORWARD (policy ACCEPT) target prot opt source destination ACCEPT all -- anywhere 192.168.122.0/24 ctstate RELATED,ESTABLISHED ACCEPT all -- 192.168.122.0/24 anywhere ACCEPT all -- anywhere anywhere REJECT all -- anywhere anywhere reject-with icmp-port-unreachable REJECT all -- anywhere anywhere reject-with icmp-port-unreachable Chain OUTPUT (policy ACCEPT) target prot opt source destination ACCEPT udp -- anywhere anywhere udp dpt:bootpc Chain f2b-SSH (1 references) target prot opt source destination RETURN all -- anywhere anywhere
Now I will do some failed login attempts from another node (node2.example.com) to this node (node1.example.com)
[root@node2 ~]# ssh node1 firstname.lastname@example.org's password: Permission denied, please try again. email@example.com's password: Permission denied, please try again. firstname.lastname@example.org's password: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
After some attempts I see the ssh connection gets refused
[root@node2 ~]# ssh node1 ssh: connect to host 10.0.2.20 port 22: Connection refused
Next I will check the firewall rule list on node1 again for f2b-SSH chain after
# iptables -L f2b-SSH Chain f2b-SSH (1 references) target prot opt source destination REJECT all -- node2.example.com anywhere reject-with icmp-port-unreachable RETURN all -- anywhere anywhere
As you see there is a new rule which blocks ssh port from
node2.example.com. So our configuration works as expected.
Lastly I hope the steps from the article to secure SSH and root login with fail2ban on Linux was helpful. So, let me know your suggestions and feedback using the comment section.