Skip to content

Instantly share code, notes, and snippets.

@christophlehmann
Created November 8, 2018 07:33
Show Gist options
  • Select an option

  • Save christophlehmann/df3b7527602b7173a12c97ea8c67a03a to your computer and use it in GitHub Desktop.

Select an option

Save christophlehmann/df3b7527602b7173a12c97ea8c67a03a to your computer and use it in GitHub Desktop.
Apache log fail2ban sql injection scanner
[Definition]
failregex = ^<HOST> .*UNION%%20SELECT%%20CHAR.*HTTP
^<HOST> .*select\*from.*HTTP
^<HOST> .*select%%20name_const.*HTTP
# Dev notes
#
# % must be escaped with '%'
[sql-scanner]
enabled = true
port = http,https
maxretry = 2
bantime = 3600
logpath = /home/*/logs/access.log
action = %(action_mwl)s
@dannatofrenk
Copy link

Hey great job, I am trying it on my webservers, I found out with new fail2ban version: 0.11 you need to have the definition file with the same name of the jail: sql-scanner.conf (i put the jail in the jail.local)
Thank you for your job.

@AcckiyGerman
Copy link

Hi, thanks for the example. Please let me improve it a bit:

  • I've notice you have a typo in the second REGEX - a backslash instead of dot: select\*from should be select.*from
  • I would make the filter case insensitive by adding (?i) prefix (documentation)
  • if somebody want to add this filter via Plesk interface, he should add ignoreregex = string, otherwise plesk doesn't show the filter when you add a jail (I've spent like an hour to find it out).

So in my case, to use it with Plesk, the filter looks like this:

[Definition]
failregex = (?i)^<HOST> .*UNION%%20SELECT%%20CHAR.*HTTP
        (?i)^<HOST> .*select.*from.*HTTP
        (?i)^<HOST> .*select%%20name_const.*HTTP

ignoreregex =

@maethor
Copy link

maethor commented Jan 7, 2026

Hi. Thank you for the example et @AcckiyGerman thank you for your improvement.

I found that .*select.*from can be too large and can match legitimate lines. For example :

342.342.342.342 - - [06/Jan/2026:23:42:00 +0100] "GET /example.php?selected-shop-id=1&from_store=1 HTTP/1.1" 200 5043 "-"
342.342.342.342 - - [06/Jan/2026:23:42:00 +0100] "GET /select.php?from=test HTTP/1.1" 200 5043 "-"

Also I am adding a way to catch injections in the referrer, because I have seen attacks with SQL injections in referrer.
And I am adding an ignoreregex to ignore phpmyadmin and pgadmin.

[Definition]

failregex = (?i)^(.+ )?<HOST> .*UNION%%20SELECT%%20CHAR.* HTTP/
            (?i)^(.+ )?<HOST> .*select[^?&=]+(from|count).* HTTP/
            (?i)^(.+ )?<HOST> .*select%%20name_const.* HTTP/
            (?i)^(.+ )?<HOST> .*HTTP/.*UNION%%20SELECT%%20CHAR
            (?i)^(.+ )?<HOST> .*HTTP/.*select[^?&=]+(from|count)
            (?i)^(.+ )?<HOST> .*HTTP/.*select%%20name_const

ignoreregex = ^(.+ )?<HOST> .*(/.*myadmin/(.*sql|index).php|pgadmin|PgAdmin).*

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment