Fail2Ban with docker and reverse proxy

Hi,

i’m trying to setup Vaultwarden with fail2ban both running in a docker container. I have created a jail and filter according to the wiki. When i test the fail2ban configuraiton it seems, that fail2ban is working properly and creates a ban. The only thing is that it actually does not ban me (the tester) from accessing the page. The Vaultwarden frontpage is still accessible from the web allthough fail2ban claims it has banned the public ip.

I can check the following points

  • :white_check_mark: fail2ban can read the vaultwarden logs
  • :white_check_mark: the “real” public ip is forwarded to Vaultwarden and its recognized by fail2ban
  • :white_check_mark: fail2ban detects the invalid login and creates a ban (see log)
  • :x: I can still access the vault web frontend allthough fail2ban claims it has banned it

Any idea what could be wrong?
I’m hosting Vaultwarden on my proxmox server within a Ubuntu 22.04 LTS VM.

Here are my configs:
docker-compose.yml

version: '3.9'

services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: always
    ports:
      - 8080:80
    environment:
      - SMTP_HOST=redacted
      - SMTP_FROM=redacted
      - SMTP_PORT=587
      - SMTP_SECURITY=starttls
      - SMTP_USERNAME=redacted
      - SMTP_PASSWORD=redacted
      - DOMAIN=https://vault.mydomain.com
      - ADMIN_TOKEN=*redacted*
      - LOG_FILE=/data/vaultwarden.log
    volumes:
      - data:/data/
  fail2ban:
    image: lscr.io/linuxserver/fail2ban:latest
    container_name: fail2ban
    privileged: true
    cap_add:
      - NET_ADMIN
      - NET_RAW
    network_mode: host
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/Berlin
      - VERBOSITY=-vv #optional
    volumes:
      - ./f2bconfig:/config
      - data:/data:ro

volumes:
  data:
  logs:

My jail.local conf.
I have only changed the chain to FORWARD, as i read that this is required when using docker. I have also tried INPUT, because somewhere i read, that you shouldn’t use FORWARD, when you have a reverse proxy infront of docker.

# Specify chain where jumps would need to be added in ban-actions expecting parameter chain
chain = FORWARD

filter.d/vaultwarden-auth.local

[INCLUDES]
before = common.conf

[Definition]

failregex = ^.*(Username or password is incorrect\. Try again|Invalid admin token)\. IP: <HOST>.*$

ignoreregex =

jail.d/vaultwarden-auth.local

[vaultwarden-auth]

enabled  = true
port     = 80
filter   = vaultwarden-auth
logpath  = /data/vaultwarden.log
action = iptables-allports[name=vaultwarden-auth, chain=FORWARD]
maxretry = 3
bantime = 60
# banaction = %(banaction_allports)s

The fail2ban log

 2023-06-15 06:04:47,826 7F5AF6011B38 INFO  [vaultwarden-auth] Found 62.redacted-ip - 2023-06-15 06:04:47
 2023-06-15 06:04:49,827 7F5AF6011B38 INFO  [vaultwarden-auth] Found 62.redacted-ip  - 2023-06-15 06:04:49
 2023-06-15 06:04:58,431 7F5AF6011B38 INFO  [vaultwarden-auth] Found 62.redacted-ip  - 2023-06-15 06:04:58
 2023-06-15 06:04:59,026 7F5AF5E0EB38 NOTIC [vaultwarden-auth] Ban 62.redacted-ip 
 2023-06-15 06:04:59,633 7F5AF6011B38 INFO  [vaultwarden-auth] Found 62.redacted-ip  - 2023-06-15 06:04:59
 2023-06-15 06:05:02,235 7F5AF6011B38 INFO  [vaultwarden-auth] Found 62.redacted-ip  - 2023-06-15 06:05:02
 2023-06-15 06:05:58,258 7F5AF5E0EB38 NOTIC [vaultwarden-auth] Unban 62.redacted-ip  

i think the problem might be that youre using fail2ban in a separate container, im not seeing or understanding how your proxy is working perhaps since i have only used fail2ban that is built into a linuxserver.io container called “swag” which is nginx and fail2ban in one.
my setup is
cloudflaretunnel > swag > vaultwarden
whatever proxy you are using, where is that sending the requests? the fail2ban container or the vaultwarden one? if the proxy is sending communication directly to the VW container then there has to be some mechanism to have the fail2ban container tell your proxy to not allow the connection. it looks like the fail2ban container youre using is the linuxserver.io one, are you sure youre using it for its intended purpose? they seem to have started to break out some components as “add ons” which can be used in the containers they create, perhaps youre using one of those?

anyway, since youre already using a linuxserver.io container i’d suggest switching to swag as your proxy, and then you have the fail2ban built in.

another thread of thought based on the information you posted, it looks like youre trying to add the ban based on trying to log into the admin portal. i handled this by limiting this access in the proxy rather than using another component, and since im using swag its nginx. you can add the below directive to how you have your proxy set up and add only the ip addresses youre expecting to allow access to the admin page like this. theres probably some better ways to do this but it seems to have worked ok for me. youll have to tweak it to your setup so the location and upstream app name match to how you have things set up

    location ~ (/bitwarden)?/admin {
        set $upstream_app bitwarden;
        set $upstream_port 80;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;
        allow x.x.x.x;
        allow x.x.x.x;
        deny all;
    }