CentOS 7 - Fail2Ban with Apache ModSecurity


One of the tools I am using to secure a server is Fail2ban. It was working well for SSH and I wanted to extend it to provide more protection for Apache.

I installed it and enabled it.

jail.d/apache-modsecurity.conf

[apache-modsecurity]
enabled = true
backend = auto
port = http,https
filter = apache-modsecurity
logpath = %(apache_error_log)s
bantime = 19200
maxretry = 2
findtime = 3600
ignoreip = 127.0.0.0/8 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16

filter.d/apache-modsecurity.conf 

# Fail2Ban apache-modsec filter
#

[INCLUDES]

# Read common prefixes. If any customizations available -- read them from
# apache-common.local
before = apache-common.conf

[Definition]
failregex = ^%(_apache_error_client)s(?: \[client [\d\.:]+\])? ModSecurity:\s+(?:\[(?:\w+ \"[^\"]*\"|[^\]]*\]\s*)*Access denied with code [45]\d\d (?:.*)$
ignoreregex =

# https://github.com/SpiderLabs/ModSecurity/wiki/ModSecurity-2-Data-Formats
# Author: Daniel Black
# Sergey G. Brester aka sebres (review, optimization)



Helpful commands

  • firewall-cmd --permanent --zone=public --add-service=http - allow HTTP through (add https as well)
  • fail2ban-client reload apache-modsecurity - reload the Apache ModSecurity configuration
  • fail2ban-client status apache-modsecurity - check the status of Apache ModSecurity configuration
  • fail2ban-client get apache-modsecurity failregex - get the regex which will cause fail2ban to ban entries (if maxretries)
  • fail2ban-regex /var/log/httpd/error_log '^\[\]\s\[(:?error|\S+:\S+)\]( \[pid \d+(:\S+ \d+)?\])? \[client (?:\[?(?:(?:::f{4,6}:)?(?P(?:\d{1,3}\.){3}\d{1,3})|(?P(?:[0-9a-fA-F]{1,4}::?|::){1,7}(?:[0-9a-fA-F]{1,4}|(?<=:):)))\]?|(?P[\w\-.^_]*\w))(:\d{1,5})?\](?: \[client [\d\.:]+\])? ModSecurity:\s+(?:\[(?:\w+ \"[^\"]*\"|[^\]]*)\]\s*)*Access denied with code [45]\d\d (?:.*)$' - check the regex
  • h-rules | grep http - list the current http (and https) - there's probably a better way to do this

Double precision floating point format decoder - C++

 

This was fun to do, but I can't remember why I decided to do it

  bits.txt

Ref: https://en.wikipedia.org/wiki/Double-precision_floating-point_format

Find the PHP session files that are older than 24 minutes

Shell

sudo find /var/lib/php/session -mmin +24 -type f -exec ls -{} \;

Yes, that's the whole post

Apache 2.4 virtual host specific PHP-FPM error logs

If you are using PHP-FPM with Apache and you would like to separate the error logging by user, directory or virtual host, you can use the ProxyFCGISetEnvIf directive

In a server level Apache .conf file

Code

<Directory /home/user/public_html>
ProxyFCGISetEnvIf "true" PHP_ADMIN_VALUE "error_log=/var/log/php-fpm/user/error.log"
</Directory>

In this case, the error log for user would be

/var/log/php-fpm/user/error.log

Set up the ACL (AMI 2 Linux)

setfacl -m u:user:x /var/log/php-fpm
setfacl -m u:user:rx /var/log/php-fpm/user
setfacl -d -m u:user:r /var/log/php-fpm/user

Test it with

sudo su user
more /var/log/php-fpm/user/error.log

Credit to:

Apache 2.4 virtual host specific PHP-FPM error logs
Comment from PHP.net (documentation)

https://www.php.net/manual/en/install.fpm.configuration.php#123335

Using wkhtmltopdf to generate a PDF from eZ Platform

I wanted to produce a polished PDF of restricted content managed by https://ezplatform.com/ with the least amount of effort possible and I wanted an approach that would allow me to run a single command on the command line.

My first approach was to try to use a browser's print to PDF feature, but I wasn't happy with the results. So I tried https://wkhtmltopdf.org/,

After tinkering with various roles/permissions and firewall configurations with eZ Platform and Symfony I chose to create a PDF user which was allowed to log in and view only the target content. I used curl to log in, extracted the eZ session id cookie and passed it to wkhtmltopdf for rendering.


#!/bin/bash
if [ "$#" -ne 1 ]; then
    echo "Usage: $0.sh url"
    exit;
fi;
USER=pdfuser
PASS=somepassword

URL=$1;
PDF=`echo $1 | sed "s/.*\/\([^\/]\+\)$/\1/"`
FOOTER_LEFT=${PDF^^}
LOGIN_URL=`echo $1 | sed "s/^\(https\?:\/\/[^\/]\+\/\).*$/\1login/"`
CSRF_TOKEN=`curl -s -X GET --cookie-jar cookie "$LOGIN_URL" | grep -o "name=\"_csrf_token\" value=\"\([^\"]\+\)\"" | sed "s/.*value=\"\([^\"]\+\)\"/\1/"`
LOGIN_DATA="_username=$USER&_password=$PASS&_csrf_token=$CSRF_TOKEN"
curl -L -s -b cookie --cookie-jar cookie -d "$LOGIN_DATA" "$LOGIN_URL"_check > /dev/null
COOKIE=`grep -o "\(eZSESS.*\)$" cookie | sed "s/\s\+/ /g"`
wkhtmltopdf --cookie $COOKIE --print-media-type --margin-left .5in --margin-right .5in --margin-top .5in --margin-bottom .5in "$URL" --footer-left "$FOOTER_LEFT" --footer-center 'Page [page] of [topage]' --footer-font-name 'Open Sans' --footer-font-size 8 --footer-right 'Updated [date]' "$PDF.pdf"

Thanks to: https://serverfault.com/a/306360/311430 for help with the cookies in the Apache log