Score:0

Apache Log files Fail2ban and WordPress

za flag

I am trying to get Fail2ban to block brute force and persistent xmlrpc and wp-login attacks on a WordPress site.

I have an issue with the apache logging filenames. Getting past selinux issues was pretty fiddly, but I am quite close to getting it working.

Firstly, here is my Fail2Ban wordpress.conf file (in jail.d)

[wordpress]
enabled = true
usedns = no
port = http,https
filter = wordpress
banaction = firewallcmd-rich-rules
banaction_allports = firewallcmd-rich-rules

logpath = /var/www/html/site1/logs/*-access.log.*
          /var/www/html/site2/logs/*-access.log.*
          ... etc ...
maxretry = 1
findtime = 1200
bantime = 1440

This is working, but when I look at the output of "fail2ban-client status wordpress" it lists 10s of log files, which is pointless and inefficient. I can't make it pick up the current (todays) log file, without restarting the service.

Incidentally, it is currently showing 43 ip addresses as "currently banned".

in my ./logs folder

2023-08-23-access.log
access.log.1692835200

The issue is that I want the apache log file to always be called "access.log" then rotated to the form with the date. Then fail2ban can just look at "access.log" and will always be working on the current days file. I don't know where the datestamp suffix (assuming it is a datestamp) comes from.

Here is the entry in the apache sites.conf file causing the issue.

ErrorLog "|/usr/sbin/rotatelogs /var/www/html/site1/logs/error.log"
CustomLog "|/usr/sbin/rotatelogs /var/www/html/site1/logs/access.log 86400" combined

I am not telling it to put a stamp on the file, so why is it doing it?

Rotate logs is described here: https://httpd.apache.org/docs/2.4/programs/rotatelogs.html

Score:1
in flag

Always maintaining the same file name for the currently active one is what rotatelogs is designed to avoid - it opens a new file with a unique but predictable suffix (by default) or name pattern (when you use % characters) at the predefined interval / condition.

On sites with low visitor counts I'd suggest having a setting:

CustomLog "|/usr/sbin/rotatelogs -c /var/www/html/site1/logs/access.log.%Y.%m" combined 

that generates a new log file ever month with the name pattern for August 2023 like access.log.2023.08.

For sites that generate more traffic: generate a new log file daily (which is what the 86400 option you used did) and use

CustomLog "|/usr/sbin/rotatelogs -c /var/www/html/site1/logs/access.log.%Y.%m.%d " combined 

That generates a new log file ever day with the name pattern for August 24th 2023 like access.log.2023.08.24. (A pattern like that ensures that a ls -l will sort file in chronologic order and is something that I find much easier to use than for example access.log.24082023 that that's a personal preference.)

Since I now have a predictable filename pattern I can set cron job that runs just after midnight that runs:

#!/bin/bash

basefile="/var/www/html/site1/logs/access.log"
currentlog=$(date +$basefile.%Y.%m.%d) 
rm $basefile 
ln -s $currentlog $basefile

# and you can do some maintenance here as well, like for example 
# compress the log file from a week ago
oldlog=$(date --date="1 week ago" +$basefile.%Y.%m.%d)
gzip $oldlog 

Which creates a symbolic link from accesss_log to the the current log file for that day.

You can configure fail2ban with the static filename it expects /var/www/html/site1/logs/access.logand all is golden.


When you don’t want that you typically configure Apache httpd with:

CustomLog  /var/www/html/site1/logs/access.log combined

Then Apache hhtpd will always write log events to /var/www/html/site1/logs/access.log

But then you need to configure an external function to rotate the log file and because Apache httpd opens a file handle and renaming /var/www/html/site1/logs/access.log to /var/www/html/site1/logs/access.log.old-label doesn't close that file handle you need restart apache httpd.
When you don't restart Apache httpd all logs evens will continue to be written /var/www/html/site1/logs/access.log.old-label and not to a new /var/www/html/site1/logs/access.log

You can of course script that yourself, but most people use logrotate for that rather than reinventing the wheel.

jon_the_eye avatar
za flag
I can see how that would work, if you knew the filename you are going to create the link to it: but how would I do it in a cron activated bash script
jon_the_eye avatar
za flag
Do you think it be possible to not use rotatelogs at all in the httpd.conf ie set the logfile to be plain "access.log" - then at midnight run cron job to rename it "yyyy-mm-dd-access.log"? Wouldn't apache create a new file if it found it wasn't there, or would I need to do a "systemctl restart httpd" in my cron task?
HBruijn avatar
in flag
Now that I'm no longer on mobile: I edited my answer to respond to your comments.
jon_the_eye avatar
za flag
Thanks for you time. Thats what I need really, the predicable filename. I am implementing this solution.
Score:1
jp flag

HBruijn has already covered the log file parts well, but I would get back to your goal:

I am trying to get Fail2ban to block brute force and persistent xmlrpc and wp-login attacks on a WordPress site.

Apache's access logs can be pretty verbose for this purpose, and you could face performance issues with your configuration, as Fail2ban tries to digest and analyze them all.

There are WordPress plugins like WP fail2ban that can help with this by creating audit events that are only logging the login failures in /var/log/auth.log.

WP fail2ban provides the link between WordPress and fail2ban:

Oct 17 20:59:54 foobar wordpress(www.example.com)[1234]: Authentication failure for admin from 192.168.0.1 Oct 17 21:00:00 foobar wordpress(www.example.com)[2345]: Accepted password for admin from 192.168.0.1

WPf2b comes with three fail2ban filters: wordpress-hard.conf, wordpress-soft.conf, and wordpress-extra.conf. These are designed to allow a split between immediate banning (hard) and the traditional more graceful approach (soft), with extra rules for custom configurations.

I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.