Fail2ban not banning

I’m trying to use the crazy-max/docker-fail2ban docker container to enforce fail2ban rules on my BitWarden container. Of note, my container is named bitwarden, not bitwarden_rs.

Relevant bits of my compose:

    container_name: bitwarden
    hostname: bitwarden
    image: bitwardenrs/server:latest
      - "/docker/config/bitwarden:/data"
      - "/etc/localtime:/etc/localtime:ro"
      - "LOG_FILE=/data/bitwarden.log"
      - "WEBSOCKET_ENABLED=true"
      - "TZ=America/New_York"
      - "3012:3012"
    restart: unless-stopped
      - "com.ouroboros.enable=true"
      driver: json-file
        max-file: "3"
        max-size: "10M"
    network_mode: BucketNet

    container_name: fail2ban
    hostname: fail2ban
    image: crazymax/fail2ban:latest
    network_mode: "host"
      - "NET_ADMIN"
      - "NET_RAW"
      - "/docker/config/fail2ban:/data"
      - "/var/log/auth.log:/var/log/auth.log:ro"
      - "/docker/config/bitwarden/bitwarden.log:/var/log/bitwarden.log:ro"
      - "/docker/config/nginx/var-log-nginx:/var/log/nginx:ro"
      - "/etc/localtime:/etc/localtime:ro"
      - "TZ=America/New_York"
    restart: unless-stopped
      - "com.ouroboros.enable=true"
      driver: json-file
        max-file: "3"
        max-size: "10M"

My action.d/iptables-common.local:

blocktype = DROP
blocktype = DROP

My filter.d/bitwarden.local:

before = common.conf
failregex = ^.*Username or password is incorrect\. Try again\. IP: <ADDR>\. Username:.*$
ignoreregex =

My jail.d/bitwarden.local:

enabled = true
port = 80,443,8081
filter = bitwarden
action = iptables-allports[name=bitwarden, chain=FORWARD]
logpath = /var/log/bitwarden.log
maxretry = 3
bantime = 14400
findtime = 14400

Of note, my BitWarden is not exposed directly at all, but reverse proxy’ed via Nginx. I have proper headers forwarded, and when I test and check my fail2ban logs I see messages with the correct IP and stating that it’s banning the IP, but nothing happens and I’m still able to access BitWarden.

Any ideas?

Hello @goose,

One thing i noticed that you only expose port 3012 and not 80. Maybe a typo in the config.

Regarding the blocking. Those headers only report in text which IP is the source. For the network stack it still is a local, probably docker, IP range. You need to block on the nginx side of that is the main entry point.

The bitwarden container never receives the external source IP directly, and only via the nginx container.

This is because I don’t need to expose port 80, as Nginx (Which is also a docker container) is reverse-proxying it.

But what your saying makes sense, I need to have fail2ban act on Nginx, not on Bitwarden_rs.

How do I modify the jail.d/bitwarden.local to do that?

Best i think is to share that logfile also to the nginx container it self maybe?

Hey, I’m having the same issue. However, I’m using Caddy as a reverse proxy and have it set up to include the origin IP in the header via header_up X-Real-IP {remote_host}.
I’ve got the fal2ban files set up in the same way as shown in GitHub - sosandroid/docker-fail2ban-synology: Adaptation of @crazy-max docker fail2ban for Synology now and it’s not working. I’m getting the following error:

fail2ban.utils          [1]: ERROR   b68beec0 -- stderr: "iptables v1.8.4 (legacy): can't initialize iptables table `filter': Table does not exist (do you need to insmod?)"
fail2ban.utils          [1]: ERROR   b68beec0 -- stderr: 'Perhaps iptables or your kernel needs to be upgraded.'
fail2ban.utils          [1]: ERROR   b68beec0 -- returned 3
fail2ban.actions        [1]: ERROR   Failed to execute ban jail 'bitwarden' action 'iptables-allports' info 'ActionInfo({'ip': '<my-ip>', 'family': 'inet4', 'fid': <function Actions.ActionInfo.<lambda> at 0xb65eb850>, 'raw-ticket': <function Actions.ActionInfo.<lambda> at 0xb65ebbb0>})': Error starting action Jail('bitwarden')/iptables-allports: 'Script error'

fail2ban should ban the remote IP address on the INPUT chain.