All traffic banned
jsmue opened this issue · comments
I think I'm dealing with a bug because I've checked all the settings and the plugin generally behaves as described. Unfortunately, my traffic is being blocked and I can't find a reason why.
I am using the latest plugin version (0.7.1) with the latest Traefik version (2.10.5). I use Docker as a provider.
For my tests I use the Traefik dashboard, which I have secured with Simle Auth. Additional brute forcing protection would be a welcome addition.
In my setup, I first tried to lock myself out by entering the wrong credentials: that worked straight away. Since then - I tested this two weeks ago - I have no longer been able to authenticate myself successfully. I am always blocked with the status '403'. What I have tried:
- Change the order of the middlewares: No influence
- Put my IP on the whilelist: Works, I get through. However, this is not a good solution for dynamic IPs.
- Set Allow rules for certain paths: Works, but undermines brute forcing protection.
What I am missing is a way to check on the banned IP adresses. Is there a way to find out, what's happening?
Thanks!
Here is an excerpt from my traefik_dynamic.yaml (for completeness):
my-fail2ban:
plugin:
fail2ban:
rules:
bantime: "3h"
enabled: true
findtime: "10m"
maxretry: 4
whitelist:
ip:
- "::1"
- "127.0.0.1"
routers:
api:
rule: Host(`dashboard.mydomain.com`)
entrypoints:
- websecure
middlewares:
- simpleAuth
- my-fail2ban
service: api@internal
tls:
certResolver: lets-encrypt
Hello @jsmue,
Thanks for your interest in this Traefik Plugin!
This Plugin does not know know any information about how Traefik will handle your request afterwards, or before entering the plugin mechanism. Therefore, it cannot know that you have locked yourself out by entering wrong credentials.
Could you try again, but without the simpleAuth
middleware?
Hi @tomMoulard,
i've just checked. Disabling simpleAuth
doesn't change the behavior. In my access logs the page view creates about 45 lines. First I have a status 302, then 200:
{"ClientAddr":"92.xxx.xxx.xx:59696","ClientHost":"92.xxx.xxx.xx","ClientPort":"59696","ClientUsername":"-","DownstreamContentSize":34,"DownstreamStatus":302,"Duration":386159,"GzipRatio":0,"OriginContentSize":0,"OriginDuration":0,"OriginStatus":0,"Overhead":386159,"RequestAddr":"traefik.mydomain.com","RequestContentSize":0,"RequestCount":6795,"RequestHost":"traefik.mydomain.com","RequestMethod":"GET","RequestPath":"/","RequestPort":"-","RequestProtocol":"HTTP/2.0","RequestScheme":"https","RetryAttempts":0,"RouterName":"api@file","StartLocal":"2023-11-07T18:51:44.26804881+01:00","StartUTC":"2023-11-07T17:51:44.26804881Z","TLSCipher":"TLS_CHACHA20_POLY1305_SHA256","TLSVersion":"1.3","entryPointName":"websecure","level":"info","msg":"","request_User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36","time":"2023-11-07T18:51:44+01:00"}
{"ClientAddr":"92.xxx.xxx.xx:59696","ClientHost":"92.xxx.xxx.xx","ClientPort":"59696","ClientUsername":"-","DownstreamContentSize":3124,"DownstreamStatus":200,"Duration":773618,"GzipRatio":0,"OriginContentSize":0,"OriginDuration":0,"OriginStatus":0,"Overhead":773618,"RequestAddr":"traefik.mydomain.com","RequestContentSize":0,"RequestCount":6796,"RequestHost":"traefik.mydomain.com","RequestMethod":"GET","RequestPath":"/dashboard/","RequestPort":"-","RequestProtocol":"HTTP/2.0","RequestScheme":"https","RetryAttempts":0,"RouterName":"api@file","StartLocal":"2023-11-07T18:51:44.276384115+01:00","StartUTC":"2023-11-07T17:51:44.276384115Z","TLSCipher":"TLS_CHACHA20_POLY1305_SHA256","TLSVersion":"1.3","entryPointName":"websecure","level":"info","msg":"","request_User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36","time":"2023-11-07T18:51:44+01:00"}
Then I have more than 40 lines with status 403; they all look pretty similar, for example like this:
{"ClientAddr":"92.xxx.xxx.xx:59696","ClientHost":"92.xxx.xxx.xx","ClientPort":"59696","ClientUsername":"-","DownstreamContentSize":0,"DownstreamStatus":403,"Duration":540676,"OriginContentSize":0,"OriginDuration":0,"OriginStatus":0,"Overhead":540676,"RequestAddr":"traefik.mydomain.com","RequestContentSize":0,"RequestCount":6798,"RequestHost":"traefik.mydomain.com","RequestMethod":"GET","RequestPath":"/dashboard/js/app.ccc19229.js","RequestPort":"-","RequestProtocol":"HTTP/2.0","RequestScheme":"https","RetryAttempts":0,"RouterName":"api@file","StartLocal":"2023-11-07T18:51:44.428084327+01:00","StartUTC":"2023-11-07T17:51:44.428084327Z","TLSCipher":"TLS_CHACHA20_POLY1305_SHA256","TLSVersion":"1.3","entryPointName":"websecure","level":"info","msg":"","request_User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36","time":"2023-11-07T18:51:44+01:00"}
I am sorry, but I cannot reproduce your issue. I've tried using your dynamic configuration, but with not luck.
Can you reproduce your issue using my configuration ?
My docker-compose reproduction case
Using this as a base, here is my configuration:
Please note that I experience no difference in both fail2ban@file
and fail2ban-registery@docker
middlewares.
# docker-compose.yml
version: '3.9'
services:
traefik:
image: traefik:v3.0
command:
- --api.insecure=true
- --providers.docker
- --log.level=DEBUG
- --providers.file.filename=/tmp/traefik.yml
# - --experimental.localPlugins.fail2ban-local.moduleName=github.com/tomMoulard/fail2ban
- --experimental.plugins.fail2ban-registery.modulename=github.com/tomMoulard/fail2ban
- --experimental.plugins.fail2ban-registery.version=v0.7.1
ports:
- 80:80
- 8080:8080
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./traefik.yml:/tmp/traefik.yml
# - .:/plugins-local/src/github.com/tomMoulard/fail2ban/
tty: true
whoami:
image: traefik/whoami # https://github.com/traefik/whoami
command: -name whoami
labels:
# traefik.http.routers.fail2ban-local.rule: Host(`fail2ban-local.localhost`)
# traefik.http.routers.fail2ban-local.middlewares: fail2ban-local
# traefik.http.middlewares.fail2ban-local.plugin.fail2ban-local.rules.enabled: true
# traefik.http.middlewares.fail2ban-local.plugin.fail2ban-local.rules.bantime: 3h
# traefik.http.middlewares.fail2ban-local.plugin.fail2ban-local.rules.findtime: 10m
# traefik.http.middlewares.fail2ban-local.plugin.fail2ban-local.rules.maxretry: 4
# traefik.http.middlewares.fail2ban-local.plugin.fail2ban-local.whitelist.ip: 127.0.0.2,::1
# traefik.http.middlewares.fail2ban-local.plugin.fail2ban-local.blacklist.ip: 127.0.0.3
# traefik.http.middlewares.fail2ban-local.plugin.fail2ban-local.rules.urlregexps[0].regexp: /no
# traefik.http.middlewares.fail2ban-local.plugin.fail2ban-local.rules.urlregexps[0].mode: block
# traefik.http.middlewares.fail2ban-local.plugin.fail2ban-local.rules.urlregexps[1].regexp: /yes
# traefik.http.middlewares.fail2ban-local.plugin.fail2ban-local.rules.urlregexps[1].mode: allow
traefik.http.routers.fail2ban-registery.rule: Host(`fail2ban-registery.localhost`)
traefik.http.routers.fail2ban-registery.middlewares: fail2ban-registery
traefik.http.middlewares.fail2ban-registery.plugin.fail2ban-registery.rules.enabled: true
traefik.http.middlewares.fail2ban-registery.plugin.fail2ban-registery.rules.bantime: 3h
traefik.http.middlewares.fail2ban-registery.plugin.fail2ban-registery.rules.findtime: 10m
traefik.http.middlewares.fail2ban-registery.plugin.fail2ban-registery.rules.maxretry: 4
traefik.http.middlewares.fail2ban-registery.plugin.fail2ban-registery.whitelist.ip: 127.0.0.2,::1
traefik.http.routers.fail2ban-local.rule: Host(`fail2ban-local.localhost`)
traefik.http.routers.fail2ban-local.middlewares: fail2ban@file
# ./traefik.yml
http:
middlewares:
fail2ban:
plugin:
fail2ban-registery:
rules:
bantime: "3h"
enabled: true
findtime: "10m"
maxretry: 4
whitelist:
IP:
- "::1"
- "127.0.0.1"
Hi @tomMoulard,
I have investigated the issue further and have come to the interim conclusion that it is less a problem with the fail2ban middleware itself and more a problem with the traefik dashboard.
When I browse through the dashboard, I get numerous errors 400 in the console. I checked with fail2ban inactive. If activated, fail2ban blocks me immediately.
For example, when browsing individual tabs in the dashboard, the following path is requested (you can also add http
and udp
in your mind)
/api/tcp/routers?search=&status=&per_page=10&page=2
opening it in the browser returns: {"message":"invalid request: page: 2, per_page: 10"}
. Since my instance has a manageable number of routers, there is no page 2 so far (even if there was, page 3 would probably be queried immediately).
I'm thinking about restricting access to this dashboard to a specific network anyway, so I can definitely use the middleware. No idea whether it makes sense to think about improvements to the middleware. If there is one point, it might be to be able to set the error codes it responds to.
Tanks for looking into this at least!
Oh ! Ok, I got why you have this error ! When showing the dashboard, your browser makes roughly 60 to 70 requests to show the UI, therefore it is making let's say 65 requests to your traefik service. The catch is that you configured the plugin to block any user that does more than 4 requests during a 10-min time window.
With this setting configured as is, the first 5 requests made by your browser were successful, but not the following ones.
Try changing this maxretry
setting to 70, and you will be able to see the dashboard, but not to reload the page.
As this seems to be a configuration issue, I am closing this issue.
In case I'm wrong, feel free to re-open the issue.