Bitwarden-rs mit fail2ban absichern

Moin!

Bitwarden-rs wurde umbenannt in Vaultwarden. Ihr findet eine aktuelle Anleitung auf Basis von Docker-compose in meinem Archiv!

Im letzten Beitrag über Bitwarden-rs haben wir die Grundinstallation durchgeführt.
Um unseren Dienst vor Brute-Force Attacken von Unbekannten zu schützen installieren wir nun Fail2Ban.

Fail2Ban ist in der Lage, Logs mit konfigurierbaren Filtern nach bestimmten Begriffen bzw. Zeilen zu durchsuchen. Wird ein zutreffender Begriff gefunden, löst eine Action aus, die die anfragende IP für eine frei wählbare Zeit ins Jail steckt.
So sind wir in der Lage bei mehreren falschen Loginversuchen die anfragende IP zu blocken.

tl;dr:

Wir schützen unseren Dienst vor Scriptkiddies und Trolls.

Ich stelle euch 2 Möglichkeiten vor Fail2Ban zu installieren:

  1. Möglichkeit: Wir installieren Fail2Ban in dem Bitwarden-rs Container, lesen die Logdatei aus und blocken dort die anfragende IP.
  2. Möglichkeit: Wir installieren einen Rsyslog Server und Fail2Ban auf dem Reverse Proxy. Danach übertragen wir die Syslog von Bitwarden zum Proxy, lesen die Syslogs aus und blocken direkt am Reverse Proxy die anfragende IP.

Nr. 1 eignet sich gut für Lösungen ohne Reverse Proxy und ist einfacher.

Nr. 2 eignet sich deutlich besser für Lösungen mit Reverse Proxy, zudem ist es möglich mit einer Fail2Ban Installation mehrere Dienste zu schützen. Leider auch aufwendiger.

Wir starten mit Nr. 1:

Voraussetzung dafür:

Verbindung per SSH zu dem Bitwarden Container. Container zerstören und die Umgebungsvariabel anpassen, damit das Loggen in einer Datei ermöglicht wird.

sudo docker rm bitwardenrs
sudo docker run -d --name bitwardenrs \
--restart=always \
-v /bw-data/:/data/ \
-p 80:80 \
-e DATABASE_URL='mysql://bitwarden_user:bitwarden_pw@ip_mysqlserver/bitwarden' \
-e SIGNUPS_ALLOWED=false \
-e SIGNUPS_VERIFY=true \
-e INVITATIONS_ALLOWED=false \
-e ADMIN_TOKEN=TrageHierDeinenVorherGeneriertenTokenEin \
-e SMTP_FROM_NAME=Bitwarden \
-e SMTP_HOST=smtpausgangsserver \
-e SMTP_FROM=eureemail@domain.tld \
-e SMTP_PORT=587 \
-e SMTP_SSL=true \
-e SMTP_EXPLICIT_TLS=true \
-e SMTP_USERNAME=username \
-e SMTP_PASSWORD=passwort \
-e DOMAIN=https://subdomain.eurodomain.tld \
-e LOG_FILE=/bw-data/bitwarden-rs.log \
-e LOG_LEVEL=info \
bitwardenrs/server:latest

Nun Fail2Ban installieren und eine Filterregel für die normale Vault anlegen.

sudo apt update && apt upgrade -y
sudo apt install fail2ban
sudo nano /etc/fail2ban/filter.d/bitwarden-rs.conf

[INCLUDES]
before = common.conf

[Definition]
failregex = ^.*Username or password is incorrect\. Try again\. IP: <ADDR>\. Username:.*$
ignoreregex =

Danach eine Filterregel für das Admininterface erstellen.

sudo nano /etc/fail2ban/filter.d/bitwarden-rs-admin.conf

[INCLUDES]
before = common.conf

[Definition]
failregex = ^.*Invalid admin token\. IP: <ADDR>.*$
ignoreregex =

Nun erstellen wir das Jail für die Vault und konfigurieren Parameter wie max. Loginversuche (maxretry) oder Banzeit (bantime).

sudo nano /etc/fail2ban/jail.d/bitwarden-rs.local

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

Anschließend erstellen wir das Jail für die Adminoberfläche.

sudo nano /etc/fail2ban/jail.d/bitwarden-rs-admin.local

[bitwarden-rs]
enabled = true
port = 80,443
filter = bitwarden-rs-admin
action = iptables-allports[name=bitwarden-rs]
logpath = /bw-data/bitwarden-rs.log
maxretry = 3
bantime = 14400
findtime = 14400

Nun passen wir noch die Action an. Dies ist nötig, da bei Docker Containern die Chain nicht als Input sondern als FORWARD gekennzeichnet sein muss.

sudo nano /etc/fail2ban/action.d/iptables-allports.conf

[Init]

blocktype = DROP
chain = FORWARD

Neustarten des Fail2Ban Dienstes und mit dem Smartphone mehrere Male mit falschen Daten auf Bitwarden einloggen. Danach prüfen wir ob die anfragende IP geblockt wurde.
Im Log taucht die Meldung „BAN IP xxx.xxx.xxx.xx“ auf.

sudo systemctl restart fail2ban.service

sudo cat /var/log/fail2ban.log

So sollte es aussehen wenn die IP erfolgreich gebannt wurde.

Ein entbannen der IP ist so möglich.

sudo fail2ban-client set bitwarden-rs unbanip xxx.xxx.xxx.xxx

Nun wenden wir uns der 2. Möglichkeit zu.

Vorraussetzung dafür:


Wir starten mit der Verbindung per SSH zu dem Bitwarden Container. Danach Container zerstören, die Umgebungsvariabel anpassen, damit Syslog genutzt wird und den Logtreiber auf Syslog ändern.

sudo docker rm bitwardenrs
sudo docker run -d --name bitwardenrs \
--restart=always \
--log-driver syslog \
--log-opt syslog-address=udp://IP.des.Reverse.Proxys:514 \
--log-opt tag=Bitwarden-rs \
-v /bw-data/:/data/ \
-p 80:80 \
-e DATABASE_URL='mysql://bitwarden_user:bitwarden_pw@ip_mysqlserver/bitwarden' \
-e SIGNUPS_ALLOWED=false \
-e SIGNUPS_VERIFY=true \
-e INVITATIONS_ALLOWED=false \
-e ADMIN_TOKEN=TrageHierDeinenVorherGeneriertenTokenEin \
-e SMTP_FROM_NAME=Bitwarden \
-e SMTP_HOST=smtpausgangsserver \
-e SMTP_FROM=eureemail@domain.tld \
-e SMTP_PORT=587 \
-e SMTP_SSL=true \
-e SMTP_EXPLICIT_TLS=true \
-e SMTP_USERNAME=username \
-e SMTP_PASSWORD=passwort \
-e DOMAIN=https://subdomain.eurodomain.tld \
-e USE_SYSLOG=true \
-e LOG_LEVEL=info \
bitwardenrs/server:latest

Nun sind wir soweit mit der Konfiguration des Bitwarden Containers fertig.
Wir bauen eine SSH Verbindung zum Reverse Proxy auf, installieren und konfigurieren dort den Syslog Server.

sudo apt update && sudo apt upgrade -y
sudo apt install rsyslog
sudo nano /etc/rsyslog.conf

#################
#### MODULES ####
#################

module(load="imuxsock") # provides support for local system logging
#module(load="imklog")   # provides kernel logging support
#module(load="immark")  # provides --MARK-- message capability

# provides UDP syslog reception
module(load="imudp")
input(type="imudp" port="514")

# provides TCP syslog reception
#module(load="imtcp")
#input(type="imtcp" port="514")

###############
#### RULES ####
###############

#
# First some standard log files.  Log by facility.
#
auth,authpriv.*                 /var/log/auth.log
*.*;auth,authpriv.none          -/var/log/syslog
#cron.*                         /var/log/cron.log
daemon.*                        -/var/log/daemon.log
kern.*                          -/var/log/kern.log
lpr.*                           -/var/log/lpr.log
mail.*                          -/var/log/mail.log
user.*                          -/var/log/user.log

# Pro Logsender ein syslog-file
$template DynaFile,"/var/log/syslog-%HOSTNAME%.log"
*.* -?DynaFile

# IP's die Syslogs zum Server senden dürfen
$AllowedSender UDP, 127.0.0.1, IP.des.Bitwarden.Containers/24

Rsyslog neustarten, damit die Konfig übernommen wird.

sudo systemctl restart rsyslog.service

Anschließend installieren wir Fail2Ban und erstellen die Filterregel für die Vault.

sudo apt install fail2ban
sudo nano /etc/fail2ban/filter.d/bitwarden-rs.conf

[INCLUDES]
before = common.conf

[Definition]
failregex = ^.*Username or password is incorrect\. Try again\. IP: <ADDR>\. Username:.*$
ignoreregex =

Darauf folgt die Filterregel für das Admininterface.

sudo nano /etc/fail2ban/filter.d/bitwarden-rs-admin.conf

[INCLUDES]
before = common.conf

[Definition]
failregex = ^.*Invalid admin token\. IP: <ADDR>.*$
ignoreregex =

Danach legen wir das erste Jail an.

sudo nano /etc/fail2ban/jail.d/bitwarden-rs.local

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

Jetzt das Jail für die Adminoberfläche.

sudo nano /etc/fail2ban/jail.d/bitwarden-rs-admin.local

[bitwarden-rs]
enabled = true
port = 80,443
filter = bitwarden-rs-admin
action = iptables-allports[name=bitwarden-rs]
logpath = /var/log/syslog-Bitwarden-rs.log
maxretry = 3
bantime = 14400
findtime = 14400

Nun passen wir noch die Action an. Dies ist nötig, da bei Docker Containern die Chain nicht als Input sondern als FORWARD gekennzeichnet sein muss.

sudo nano /etc/fail2ban/action.d/iptables-allports.conf

[Init]

blocktype = DROP
chain = FORWARD

Neustarten des Fail2Ban Dienstes und mit dem Smartphone mehrere Male mit falschen Daten auf Bitwarden einloggen. Danach prüfen wir ob die anfragende IP geblockt wurde.
Im Log taucht die Meldung „BAN IP xxx.xxx.xxx.xx“ auf.

sudo systemctl restart fail2ban.service

sudo cat /var/log/fail2ban.log

So sollte es aussehen wenn die IP erfolgreich gebannt wurde.

Ein entbannen der IP ist so möglich.

sudo fail2ban-client set bitwarden-rs unbanip xxx.xxx.xxx.xxx

Grüße gehen aus dem Archiv!

5 Kommentare zu „Bitwarden-rs mit fail2ban absichern“

  1. Nochmal danke auch für dieses Tut. Ich habe versucht, Variante 2 nachzubauen. Es kommen allerdings 2 Logs bei meinem Nginx-Server an – eins unter der lokalen Bitwarden-IP-Adresse (syslog-192.168.1.102.log) und eins unter dem Hostnamen (syslog-Bitwarden.log). In diesen Logs sind allerdings keinerlei falsche Einlogg-Versuche enthalten.

    In einem Log ist Folgendes enthalten: … [bitwarden_rs::api::admin][ERROR] Invalid admin token. IP: 192.168.1.100 – das ist allerdings die lokale Nginx-Adresse und nicht die IP meines Handys im Mobilfunknetz.

    Hast Du eine Idee, was bzw. wo ich da noch suchen kann? Ich habe jetzt alles doppelt und dreifach gecheckt und die Kommunikation zwischen Bitwarden und Nginx funktioniert auch – allerdings scheint Bitwarden das Falsche bzw. nicht das Gewünschte zu loggen…

    Danke 🙂

    TANTE EDIT:
    Kleine Korrektur: In der syslog-192.168.1.102.log sind jetzt auch die fehlerhaften Logins im Log, allerdings auch mit der lokalen Nginx-IP. Komisch…

  2. Freut mich das dir der Blog weiter hilft. 🙂
    Damit der Nginx reverse proxy die echte IP weiterleiten kann muss dieser auch so konfiguriert werden.
    In deinem Fall nihmt der Proxy das Paket an und schaut auf welche Domain es geroutet werden soll. Anschließend leitet er das Paket an die am Proxy hinterlegte IP weiter.
    Ist nun der Header am Proxy falsch konfiguriert leitet der Proxy seine IP anstatt der Real IP des Paketsenders weiter.
    Soweit klar?
    Stichwort bei dem Problem ist – X-Real-IP

    1. Hab mich jetzt nochmal drangesetzt, komme aber nicht weiter. Nach allem, was im Netz gefunden habe, sollte meine Config funktionieren, tut sie aber nicht:
      # Real IP Determination
      # Docker subnet:
      set_real_ip_from 172.0.0.0/8;
      # Local subnets:
      set_real_ip_from 10.0.0.0/8;
      set_real_ip_from 192.0.0.0/8;
      set_real_ip_from 192.168.0.0/24;
      set_real_ip_from 192.168.1.100;
      # NPM generated CDN ip ranges:
      include conf.d/include/ip_ranges.conf;
      # always put the following 2 lines after ip subnets:
      real_ip_header X-Forwarded-For;
      real_ip_recursive on;
      Es steht immer die Nginx-IP im Log. Wie sieht denn Deine Nginx-Config aus?

      Danke

  3. Danke für die Anleitung, habe mich auch an Version 2 probiert und nun das skurile Verhalten, dass fail2ban die externe IP blockt und banned, aber dieser Ban keine Auswirkungen hat. Konnte danach fröhlich weiter falsche Passwörter eingeben und mich auch erfolgreich einloggen. In den iptables steht der Ban auch drin. Mir fehlt die Idee wonach ich suchen soll, um meinen Fehler zu finden :/

    1. Moin!
      Schön das dir der Beitrag gefällt!
      Hast du per Zufall Cloudflare als Domain Verwalter?
      Check mal bei deinem Verwalter ob die IP Anfragen über einen Proxy des Anbieters gehen.
      Bei Cloudflare ist das oft der Fall.
      Sollte das nicht helfen kannst du dich gerne noch mal melden 🙂

      Grüße Lucas

Kommentar verfassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.