SuiteCRM 8.4.X & 8.5 Fail2Ban Implementation


I’ve been working on Fail2Ban for a client - They had it setup in their infrastructure but didn’t have it implemented with Suite.

I found an article here Protect Your SuiteCRM with Fail2Ban - Tutorial for Beginners - iGo Website Design Mississauga from @ pstevens

I thought i’d share the steps i took to update this logic to the 8.X versions.

I know the later 8.X versions have throttle login and such but if fail2ban is there you may as well have a failsafe :slight_smile:

Not too technical :slight_smile:


Is the distro i’m working on but this should be applicable to most ubuntu releases.


sudo apt update

– Install Fail2Ban

sudo apt install fail2ban

Create the Jail file - suitecrm.conf file in Fail2Ban

sudo nano /etc/fail2ban/jail.d/suitecrm.conf

enabled = true
filter = suitecrm
port = http,https
logpath = /var/www/html/logs/access.log
maxretry = 5


The log path you are looking for specifically is where you have instructed your Apache2 access logs to feed into.

You can find this by visiting “/etc/apache2/sites-available/”

Now we’ll set up the filter for Fail2Ban - this is the bit where you’re telling Fail2Ban what expression you are wanting Fail2Ban to look for when handing out these bans.

sudo nano /etc/fail2ban/filder.d/suitecrm.conf

before = common.conf

_daemon = suitecrm

failregex = ^<HOST> - - \[.*\] \"POST .* HTTP/1\.[0-1]\" 401
ignoreregex =


Let’s break the regex down into parts.

  • ^ this matches the start of the log line
  • <HOST> fail2ban has some special tags that match an IP address or Host name
  • - - this matches the 2 dashes in the log
  • \[.*\] this matches the date/timestamp in the square brackets, I could have matched the date more precisely, but we don’t need to in this case. We have to escape the [ as it has meaning in regex as we will see later.
  • \"POST this matches the start of the request string and limits it to just POST requests
  • .* this matches the host:port combination that is being requested
  • HTTP/1\.[0-1]\" here we match both HTTP/1.0 and HTTP/1.1. We need to escape the . and the square brackets let us specify a range of values
  • 401 and finally the 401 error code

A failed login in the access.logs looks like the below;

XX.XX.XXX.XX - - [18/Dec/2023:10:48:47 +0000] "POST /login HTTP/1.1" 401 545 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/ Safari/537.36"
XX.XX.XXX.XX - - [18/Dec/2023:10:48:49 +0000] "POST /login HTTP/1.1" 401 545 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/ Safari/537.36"
XX.XX.XXX.XX - - [18/Dec/2023:10:48:49 +0000] "POST /login HTTP/1.1" 401 545 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/ Safari/537.36"

At this stage i used

sudo systemctl restart fail2ban

Then i tried a few failed logins - just one or two should do.

Then i checked to make sure Fail2Ban was reading what i told it to with;

sudo fail2ban-regex --print-all-matched /var/www/html/access.log /etc/fail2ban/filter.d/suitecrm.conf

This command is asking fail2ban to read the access.log based on the filter expressions.

It found the log file, it found 13 lines in the log file and found 3 lines that matched my expression - which is correct as i tried to login incorrectly 3 times.

To unban ip

sudo fail2ban-client set suitecrm unbanip XX.XXX.XX.XXX

To ban ip

sudo fail2ban-client set suitecrm banip XX.XXX.XX.XXX

To check IP bans
Enter Fail2Ban on the terminal as a client

sudo fail2ban-client -i

Then simply run

status suitecrm


Happy Hunting :slight_smile:


Good start, but consider this. When I telnet to Apache on http port 80 of an Apache web server, and issue a “GET / HTTP/2.0” command, along with a valid Host header, Apache will respond with a “HTTP/1.1 200 OK”, because the request isn’t real HTTP2 protocol, and isn’t being processed by Apache module mod_http2, it’s being treated as HTTP 1.1, because Apache detected it rightly as HTTP 1.1! And yet, Apache will incorrectly log it as HTTP2 just as I wrote in my request! Apache will log HTTP2 even when mod_http2 is disabled!

To make fail2ban protect SuiteCRM by not letting hackers trick your config that’s looking only for HTTP 1.x versions, you must skip the HTTP 1.x version number check in your failregex, because Apache will log any HTTP version number the hacker gives it, and process the request, so it’s easy for a hacker to put in a fake HTTP version number and bypass your faileregex and try a million passwords without ever getting banned by your fail2ban.


A better way is to suitecrm login logs showing login attempts and failed passwords. Grab the IP and do the ban and report it to then you can also use that database for secondary blocking before even processing a login attempt. That is beyond beginner fail2ban but not difficult.

The default ban time is fairly low. I usually set it low for the first attemp so if someone makes a legit mistake they can get back online in 10-20 minutes. But, I recommend using multipliers for the repeated failures so someone keeps trying then the bans increase quickly. They get banned for 17 minutes on the first ban, then a day on ban #2 then a month then 6 weeks or whatever your max ban time is. The bots are smart enough to know your 5 retry limit and will keep hitting at 4 tries if you have a short ban time.

If you have a log sample from suitecrm showing logins I can get you the regex to test. I’ve never seen login data logged in Suitecrm but it must be somewhere.

Otherwise, good post on fail2ban. It does work well.

1 Like