Die Installation eines Bitwarden-Servers ist ganz einfach, hatten sie gesagt.

Einfach nur 3 Befehle, hatten sie gesagt.

Das Schlimme an so einfachen Sachen: Wenn sie mal nicht funktionieren, dann findet sich die Lösung nur schwer bis garnicht...

Im Endeffekt habe ich es nicht geschafft, den Bitwarden-Server auf einem Mac zu installieren. Weder über die "einfachen 3 Zeilen", noch über den "on premise"-Weg.

Zum Glück stieß ich auf einen inoffiziellen bitwarden-Port namens vaultwarden (früher: bitwarden_rs), welcher sich als nicht "so einfach in der Installation" präsentiert, aber dafür so einfach in der Installation ist und schon nach der Eingabe von 2 Befehlen läuft.
Außerdem findet sich hier auch ein Weg, wie man von außerhalb des Docker-Containers auf den im Container laufenden Server zugreifen kann. Daran war ich beim "offiziellen Bitwarden" ebenfalls gescheitert.

Während das offizielle Bitwarden-Projekt für ein großes Hosting mit tausenden bis millionen Usern gedacht ist, kocht vaultwarden auf kleinerer Flamme. Für meinen Privatgebrauch ausreichend. Mehr als fünf User werden es sowieso nicht werden...

Doch moment... Was ist Bitwarden überhaupt?
Einer toller Passwortmanager, der erstens OpenSource ist und den man noch dazu selbst hosten kann.
Vaultwarden ist ein in Rust geschriebener Ableger des Bitwarden-Projektes, welcher mit den offiziellen Bitwarden-Browser-Plugins kompatibel ist und sich auch sonst in Sachen Frontend nicht wirklich unterscheidet.

Installation

Installationsanweisung, um vaultwarden als Docker-Container laufen zu lassen und dabei Registrierungen von Benutzern zu verbieten, außer ihre E-Mail-Adresse ist auf der Domain-Whitelist:

mkdir /pfad/zu/vaultwarden-verzeichnis
cd /pfad/zu/
docker pull vaultwarden/server:latest
docker run -d --name vaultwarden \
           -v /pfad/zu/vaultwarden-verzeichnis/:/data/ \
           -e SIGNUPS_ALLOWED=false \
           -e SIGNUPS_DOMAINS_WHITELIST=apfel-z.net
           -p 80:80 \
           --restart always
           vaultwarden/server:latest

Mit den beiden -e Environment-Variablen, die wir mitgeben, verbieten wir, dass irgendjemand auf diesem Server ein neues Konto eröffnet, fügen E-Mail-Adressen der eigenen Domain aber zu einer Whitelist hinzu.
Das heißt: Niemand kann ein Konto bei unserer Installation eröffnen, außer, er registriert sich mit einer E-Mail-Adresse der Domain apfel-z.net

Die -v Sache hat bei mir leider nicht funktioniert und das angegebene /pfad/zu/vaultwarden-verzeichnis-Verzeichnis blieb leer, obwohl /data innerhalb des Containers mit Dateien bevölkert ist.

Ich habe dann stattdessen ein Docker-Volume erstellt, um die vaultwarden-Daten erhalten zu können, sollte ich den Server mal neu herunterladen:

sudo docker volume create --name vaultwarden_data

Und dann statt -v /pfad/zu/vaultwarden-verzeichnis/:/data/ die Verknüpfung zum erstellten Docker Volume verwendet: -v vaultwarden_data:/data/

Wollen wir auf die Admin-Seite zugreifen, über welche sich Benutzer verwalten und globale Einstellung ändern lassen, müssen wir außerdem noch mit -e die Environment-Variable ADMIN_TOKEN mit einem möglichst langen geheimen Token mitgeben.
Diesen Token sollte man sich irgendwo sicher notieren (am besten in Vaultwarden selbst), da man ihn benötigt, um auf die Admin-Seite zugreifen zu können.

Vielleicht lieber nochmals der gesamte docker run-Befehl mit meinen Updates:

docker run -d --name vaultwarden \
           -v vaultwarden_data:/data/ \
           -e SIGNUPS_ALLOWED=false \
           -e SIGNUPS_DOMAINS_WHITELIST=apfel-z.net
           -a ADMIN_TOKEN=ganzLangerGeheimerAdminToken \
           -p 80:80 \
           --restart always
           vaultwarden/server:latest

"Interner" Docker-Port 80 auf den lokalen Port 8001 mappen

VBoxManage controlvm "default" natpf1 "vaultwarden,tcp,,8001,,80"

Web-UI lässt sich nun am lokalen Rechner unter http://127.0.0.1:8001 öffnen. Hier nun ein neues Konto erstellen und danach kann man sich einloggen.
Die Admin-Seite ist unter http://127.0.0.1:8001/admin aufrufbar. Zum Login benötigt man den bei docker run mitgegebenen ADMIN_TOKEN.

Reverse Proxy einrichten

Die beiden Module

LoadModule proxy_module libexec/apache2/mod_proxy.so
LoadModule proxy_http_module libexec/apache2/mod_proxy_http.so

müssen in /etc/apache2/httpd.conf aktiv sein. Also vorangestelltes # entfernen.

Dann einen neuen Virtual Host hinzufügen, der eine verfügbare Subdomain auf die interne Adresse http://127.0.0.1:8001 umleitet (in diesem Beispiel läuft der Reverse Proxy auf demselben Server, wie Docker/Vaultwarden).
Ein passendes Zertifikat hatte ich zuvor mit LetsEncrypt erstellt und im Verzeichnis /etc/letsencrypt/live/vaultwarden.apfel-z.net/ abgelegt.

sudo pico /etc/apache2/extra/httpd-ssl.conf

Nehmen wir an, meine Subdomain für Vaultwarden lautet vaultwarden.apfel-z.net

<VirtualHost *:443>
    SSLEngine on
    ServerName vaultwarden.apfel-z.net:443
    ServerAlias vaultwarden.apfel-z.net
    ServerAdmin spam-webmaster@apfel-z.de

    ErrorLog "/private/var/log/apache2/error_log"
    TransferLog "/private/var/log/apache2/access_log"
    CustomLog "/private/var/log/apache2/ssl_request_log" "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

    BrowserMatch ".*MSIE.*" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0
    Include /etc/letsencrypt/options-ssl-apache.conf

    SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
    SSLCertificateFile    /etc/letsencrypt/live/vaultwarden.apfel-z.net/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/vaultwarden.apfel-z.net/privkey.pem

    RewriteEngine On
    RewriteCond %{HTTP:Upgrade} =websocket [NC]
    RewriteRule /notifications/hub(.*) ws://127.0.0.1:3012/$1 [P,L]
    ProxyPass / http://127.0.0.1:8001/

    ProxyPreserveHost On
    ProxyRequests Off
    RequestHeader set X-Real-IP %{REMOTE_ADDR}s
</VirtualHost>

Apache neustarten, dann sollte Vaultwarden auch aus dem weltweiten Netz nutzbar sein:
sudo apachectl -k restart

Zusammen mit LetsEncrypt-Zertifikaten...

Kleine Info nebenbei: Um den Certbot von LetsEncrypt nutzen zu können, muss auch die Standard-HTTP-Adresse (non-HTTPS auf Port 80) auf dem ReverseProxy-Server eingerichtet werden. Ansonsten bekam ich immer den Fehler Challenge failed for domain vaultwarden.apfel-z.net

Dies wäre noch der kleine Eintrag

/etc/apache2/extra/httpd-vhosts.conf
<VirtualHost *:80>
    ServerAdmin spam-webmaster@apfel-z.net
    DocumentRoot "/Library/WebServer/Documents/vaultwarden.apfel-z.net"
    ServerName apfel-z.net
    ServerAlias vaultwarden.apfel-z.net
    ErrorLog "/private/var/log/apache2/error_log"
    CustomLog "/private/var/log/apache2/access_log" common
</VirtualHost>