Repelling all unauthorized access attempts to the server with fail2ban!

9 min

language: ja bn en es hi pt ru zh-cn zh-tw

Hello, I'm Incompetent. In my previous article https://soulminingrig.com/blog/what\-country\-is\-the\-person\-trying\-to\-gain\-unauthorized\-access\-to\-my\-server\-via\-ssh/, I confirmed that there were too many access attempts from various IPs in just one day. I've been running it casually until now, and while I haven't actually been subjected to unauthorized access, I should take countermeasures.
Also, it's a bit annoying that the log files are accumulating too much and becoming difficult to read. So, I've decided to introduce Fail2Ban, which I became interested in when it was installed as a dependency during iRedMail installation a while ago.

What is this?

It is possible to block IPs when a configured number of attempts are made, based on log auditing.
Furthermore, it is also possible to drop the packets themselves via iptables when attempts are made. [Installation

Since I'm logged in as root this time, I won't use sudo. I searched with `pkg` and found the following package, so I'll install it.

pkg install py311-fail2ban-1.1.0  
  

Basically, it is not recommended to modify the fail2ban.conf configuration file itself; instead, you should create and write to `jail.local`. So this time,
SSH, Postfix, Dovecot
I really dislike login attempts related to these three, so I will configure them.
Also, looking at various websites, it seems that it's possible to set not only in seconds but also in '1w' (1 week) and '1d' (1 day), so I'm going to set it quite aggressively. I'll ban them for a week without mercy.

~ # cat /usr/local/etc/fail2ban/jail.local  
[sshd]  
enabled = true  
port    = ssh  
logpath = /var/log/auth.log  
bantime = 1w  
findtime = 1d  
maxretry = 5  
  
[postfix]  
enabled = true  
port    = smtp,ssmtp,submission  
logpath = /var/log/maillog  
bantime = 1w  
findtime = 1d  
maxretry = 10  
action = block-drop[name=postfix, port=smtp, protocol=tcp]  
  
[dovecot]  
enabled = true  
port    = pop3,pop3s,imap,imaps,submission  
logpath = /var/log/maillog  
bantime = 1w  
findtime = 1d  
maxretry = 10  
action = block-drop[name=dovecot, port=imap, protocol=tcp]  
  

It seems like it's better to create a [default] section, but for now, I'll only apply it to these three and add more if necessary. By the way, the reasons I set it to one week are:

  • First of all, I'm currently logging in via key authentication, so there's no way to make a mistake.

  • Once I log into the mail server, the login authentication continues for a while, so I rarely attempt to log in manually.

  • Once banned, I want to drop the packets entirely.

  • More than 5 login failures in a day is inherently strange.

So, is it quite strict? Or lenient? I don't want to consume too many resources by making the ban period too short, so I set it this way. By the way, it seems that GET methods on HTTP servers can also be banned. https://hana-shin.hatenablog.com/entry/2023/05/24/210949 I haven't implemented it yet because I only run this server as an intermediary server, but I might try it if it seems necessary. And, I've added action = block-drop, and its settings are as follows.

# cat /usr/local/etc/fail2ban/action.d/block-drop.conf  
[Definition]  
  
actionstart = iptables -N f2b-&LTname>  
              iptables -A f2b-&LTname> -j DROP  
              iptables -I INPUT -p all -j f2b-&LTname>  
              iptables -I FORWARD -p all -j f2b-&LTname>  
  
actionstop = iptables -D INPUT -p all -j f2b-&LTname>  
             iptables -D FORWARD -p all -j f2b-&LTname>  
             iptables -F f2b-&LTname>  
             iptables -X f2b-&LTname>  
  
actioncheck = iptables -n -L INPUT | grep -q 'f2b-&LTname>[     ]'  
  
actionban = iptables -I f2b-&LTname> -s &LTip> -j DROP  
  
actionunban = iptables -D f2b-&LTname> -s &LTip> -j DROP  
  

Basically, when an IP is banned, I've configured it to drop the entire packet. I remembered 'Reject' was an option, and upon re-examining https://serverfault.com/questions/157375/reject-vs-drop-when-using-iptables, it turns out 'Reject' should be used when you want the other party to know they've been denied. Since this is a ban, I decided to mercilessly send the entire packet into oblivion.

Startup and Health Check

Since it's FreeBSD, start it with this:

service fail2ban start  
  

If 'Server ready' appears, it's OK. I'll check the logs to confirm it's working correctly.

# tail /var/log/fail2ban.log  
2024-07-24 13:34:05,654 fail2ban.filter         [39963]: INFO    [sshd] Found  - 2024-07-24 13:34:05  
2024-07-24 13:34:05,755 fail2ban.filter         [39963]: INFO    [sshd] Found  - 2024-07-24 13:34:05  
2024-07-24 13:34:05,884 fail2ban.filter         [39963]: INFO    [sshd] Found  - 2024-07-24 13:34:05  
2024-07-24 13:34:06,000 fail2ban.filter         [39963]: INFO    [sshd] Found  - 2024-07-24 13:34:05  
2024-07-24 13:34:06,317 fail2ban.actions        [39963]: WARNING [sshd]  already banned  
2024-07-24 13:34:06,731 fail2ban.filter         [39963]: INFO    [sshd] Found  - 2024-07-24 13:34:06  
2024-07-24 13:37:14,327 fail2ban.filter         [39963]: INFO    [sshd] Found - 2024-07-24 13:37:14  
2024-07-24 13:42:12,266 fail2ban.filter         [39963]: INFO    [sshd] Found  - 2024-07-24 13:42:12  
2024-07-24 13:42:17,389 fail2ban.filter         [39963]: INFO    [sshd] Found  - 2024-07-24 13:42:17  
2024-07-24 13:42:23,357 fail2ban.filter         [39963]: INFO    [sshd] Found  - 2024-07-24 13:42:23  
  

Normally, IP addresses would be displayed, but I've hidden them properly this time. It was banned immediately! 'Gotcha, you little rascal!' I'm shouting in my heart.
(What am I thinking, celebrating against a bot and a machine?) I'll direct that silly victory pose to the ground and add the following to /etc/rc.conf so it starts automatically.

fail2ban_enable="YES"  
  

With this, the process will start automatically even after a server reboot.


So, that's all for today. By the way, I also thought it might be interesting to display in a chart what usernames were used for login attempts in the logs received so far. See you next time.

Related Posts