0

The short summary:

I am attempting to configure fail2ban on a host which monitors traffic in a docker container. My fail2ban matches, and fail2ban does indeed ban the ip address. But the ip address it bans is wrong?

The setup and diagnosis

Sample snippet in jail.local

[php-custom] 
enabled   = true
port      = http,https
filter    = php-custom 
logpath   = /var/lib/docker/containers/*/*-json.log
maxrety   = 0
bantime   = 8640000

My custom php-custom.conf filter rule: (i'm attempting to ban anything php as I am running a .net app):

[Definition]

failregex = ^{"log":".*<HOST>.*(GET|POST).*(.php).*$

ignoreregex = 

The horrible spam traffic I am attempting to block/ban:

{"log":"127.0.0.1 47.95.1.195 - - [05/Jul/2018:21:42:40 +0000] \"GET /phpMyadmin_bak/index.php HTTP/1.1\" 503 213 \"-\" \"Mozilla/5.0\"\n","stream":"stdout","time":"2018-07-05T21:42:40.24318153Z"}
{"log":"127.0.0.1 47.95.1.195 - - [05/Jul/2018:21:42:40 +0000] \"GET /www/phpMyAdmin/index.php HTTP/1.1\" 503 213 \"-\" \"Mozilla/5.0\"\n","stream":"stdout","time":"2018-07-05T21:42:40.823999106Z"}
{"log":"127.0.0.1 47.95.1.195 - - [05/Jul/2018:21:42:42 +0000] \"GET /tools/phpMyAdmin/index.php HTTP/1.1\" 503 213 \"-\" \"Mozilla/5.0\"\n","stream":"stdout","time":"2018-07-05T21:42:42.495745595Z"}
{"log":"127.0.0.1 47.95.1.195 - - [05/Jul/2018:21:42:42 +0000] \"GET /phpmyadmin-old/index.php HTTP/1.1\" 503 213 \"-\" \"Mozilla/5.0\"\n","stream":"stdout","time":"2018-07-05T21:42:42.686355079Z"}
{"log":"127.0.0.1 47.95.1.195 - - [05/Jul/2018:21:42:42 +0000] \"GET /phpMyAdminold/index.php HTTP/1.1\" 503 213 \"-\" \"Mozilla/5.0\"\n","stream":"stdout","time":"2018-07-05T21:42:42.876219111Z"}
{"log":"127.0.0.1 47.95.1.195 - - [05/Jul/2018:21:42:43 +0000] \"GET /phpMyAdmin.old/index.php HTTP/1.1\" 503 213 \"-\" \"Mozilla/5.0\"\n","stream":"stdout","time":"2018-07-05T21:42:43.0685648Z"}
{"log":"127.0.0.1 47.95.1.195 - - [05/Jul/2018:21:42:43 +0000] \"GET /pma-old/index.php HTTP/1.1\" 503 213 \"-\" \"Mozilla/5.0\"\n","stream":"stdout","time":"2018-07-05T21:42:43.258384519Z"}

When I test it with fail2ban-regex, see below, N.B 127.0.0.1 is not my real ip address.

fail2ban-regex '{"log":"127.0.0.1 118.24.11.172 - - [07/Jul/2018:06:15:10 +0000] \"GET /mysql-admin/index.php HTTP/1.1\" 503 213 \"-\" \"Mozilla/5.0\"\n","stream":"stdout","time":"2018-07-07T06:15:10.68 3403757Z"}' '^{"log":".*<HOST>.*(GET|POST).*(.php).*$'

The output I get:

Running tests
=============

Use   failregex line : ^{"log":".*<HOST>.*(GET|POST).*(.php).*$
Use      single line : {"log":"127.0.0.1 118.24.11.172 - - [07/Jul/2...


Results
=======

Failregex: 1 total
|-  #) [# of hits] regular expression
|   1) [1] ^{"log":".*<HOST>.*(GET|POST).*(.php).*$
|      0.0.0.2  Sat Jul 07 06:15:10 2018
`-

Ignoreregex: 0 total

Date template hits:
|- [# of hits] date format
|  [1] Day(?P<_sep>[-/])MON(?P=_sep)Year[ :]?24hour:Minute:Second(?:\.Microseconds)?(?: Zone offset)?
|  [0] (?:DAY )?MON Day 24hour:Minute:Second(?:\.Microseconds)?(?: Year)?
|  [0] Year(?P<_sep>[-/.])Month(?P=_sep)Day 24hour:Minute:Second(?:,Microseconds)?
|  [0] Day(?P<_sep>[-/])Month(?P=_sep)(?:Year|Year2) 24hour:Minute:Second
|  [0] Month/Day/Year:24hour:Minute:Second
|  [0] Month-Day-Year 24hour:Minute:Second\.Microseconds
|  [0] TAI64N
|  [0] Epoch
|  [0] Year-Month-Day[T ]24hour:Minute:Second(?:\.Microseconds)?(?:Zone offset)?
|  [0] ^24hour:Minute:Second
|  [0] ^<Month/Day/Year2@24hour:Minute:Second>
|  [0] ^Year2MonthDay  ?24hour:Minute:Second
|  [0] MON Day, Year 12hour:Minute:Second AMPM
|  [0] ^MON-Day-Year2 24hour:Minute:Second
`-

Lines: 1 lines, 0 ignored, 1 matched, 0 missed [processed in 0.00 sec]

It appears to match, but it appears to say the ip address matched is 0.0.0.2 Sat Jul 07 06:15:10 2018 ??

I let this setup run for sometime, as I assumed it was working, and when inspecting the status by running fail2ban-client status php-custom I get the following:

|- Filter
|  |- Currently failed: 0
|  |- Total failed:     0
|  `- File list:        /var/lib/docker/containers/016ef4731565527d407a552af9bfe5cf3ec3623117b40a34ed09e9fb5b2ffb00/    016ef4731565527d407a552af9bfe5cf3ec3623117b40a34ed09e9fb5b2ffb00-json.log 
`- Actions
   |- Currently banned: 5
   |- Total banned:     5
   `- Banned IP list:   0.0.0.1 0.0.0.2 0.0.0.4 0.0.0.8 0.0.0.9

The i.p addresses all seem to be 0.0.0.1 and 0.0.0.2 etc?

I'm expecting it should be the actual ip address, as I am still getting the spam traffic.

Any advice or help as I'm very new to fail2ban as well as docker would be much appreciated.

Chuen Lee
  • 353
  • 4
  • 17

2 Answers2

0

I recommend configuring nginx to not log anything around these locations that you frequently get 404 message on. That way the CPU and disk IO saved writing the logs can be used for your real visitors.

CPU/IO time is also saved when you don't need fail2ban to scan through the logs.

Every real visitor is saved from being subject to IP/nftables rules slowing down their access.

You'll also be saved the anguish of looking at the logs and focusing on the background noise of the internet rather than the real visitors you care about.

Also your regex is overly broad an probably susceptible to DoS attacks.

danblack
  • 12,130
  • 2
  • 22
  • 41
0

I experienced the same. The problem and how I fixed it was an incorrect filter regex. It was hard to spot, but the HOST was parsing as just the last digit of the IP address (hence your random 0.0.0.X). Fail2ban somehow takes the number and makes it into 0.0.0.X IP address. Once I fixed the regex, the correct IPs started flowing.

As a side note - solving this was not the end of the road for me. The very next hurdle was the fact the fail2ban seemed to be working and banning correct IP adresses fine, but the service behind (php in your case, mysql in mine) was still receiving the rogue traffic. For that you need to consider what this guy has written (helped me a lot): LINK

Hope this helps!

KarelS
  • 1
  • 4