ラズパイでVaultwardenをdocker上でホストしてパスワード管理をやってみる
はじめに
皆さん、パスワードマネージャー使ってますか?とても便利なので仕事でもプライベートでも使っている人は多いともいます。最近VaultWardenというBitwardenの API と互換のある Rust で書かれた OSS があることを知りました。Bitwarden の有料機能も基本的に使える(SSO に関しては残念ながら公式採用されていない)ようなので、docker コンテナとしてラズパイでホストしてみたいと思います。
この記事では以下のことは紹介しません。
- ssl 化
- ドメイン取得
- port 開放など
最終構成
早速ですが最終的な docker compose を共有します。Vaultwarden はwikiがかなり充実しているので、一度見ておくことをおすすめします。
version: "3.8"
services:
nginx:
container_name: nginx
image: nginx:latest
volumes:
- ./data/nginx/conf.d:/etc/nginx/conf.d
- ./data/nginx/nginx.conf:/etc/nginx/nginx.conf
- ./data/letsencrypt:/etc/letsencrypt
restart: always
environment:
PUID: 1000
PGID: 1000
TZ: Asia/Tokyo
ports:
- "443:443"
depends_on:
- vaultwarden
mysql:
container_name: mysql
image: mariadb:latest
volumes:
- ./data/db:/var/lib/mysql
restart: always
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=password
- MYSQL_DATABASE=vaultwarden
- MYSQL_USER=vaultwarden
- MYSQL_PASSWORD=vaultwarden
vaultwarden:
container_name: vaultwarden
image: vaultwarden/server:latest
restart: always
environment:
- DOMAIN=https://example.com
- DATABASE_URL='mysql://vaultwarden:vaultwarden@mysql/vaultwarden'
- ADMIN_TOKEN='<TOKEN>'
- RUST_BACKTRACE=1
volumes:
- ./data/vaultwarden:/data
depends_on:
- mysql
vaultwarden-backup:
container_name: vaultwarden-backup
image: ttionya/vaultwarden-backup:latest
restart: always
environment:
- BACKUP_KEEP_DAYS=1
- CRON='0 * * * *'
- DB_TYPE=mysql
- MYSQL_HOST=mysql
- MYSQL_PASSWORD=vaultwarden
volumes:
- ./data/vaultwarden:/bitwarden/data
- ./data/vaultwarden-rclone-data:/config
depends_on:
- vaultwarden
Nginx で SSL を終端して、Vaultwarden へリバースプロキシさせます。mysql の docker イメージはラズパイ用がないので、mysql と互換のある mariaDB を使います。Vaultwarden は他の DB もサポートしているので、コンテナの数を減らしたい場合は SQLite を使えます。
vaultwarden の設定詳細
-
DOMAIN
- host する vaultwarden の domain を設定します。
-
DATABASE_URL
-
接続する DB への URL を記述します。SQLite を使う場合は不要です。
-
mysql の場合以下のように指定をします。
-
'mysql://<user>:<password>@mysql/vaultwarden[?ssl_mode=(disabled|required|preferred)&ssl_ca=/path/to/cart.(crt|pem)]'
-
-
-
ADMIN_TOKEN
-
管理画面を有効にするために設定します。基本は OFF にしておき、必要になったら ON にすることをおすすめします。
-
token の値は何でも OK ですが、セキュアランダムな値にするのがお勧めされています。
-
簡単な設定では 次のコマンドが紹介されています。
-
openssl rand -base64 48
-
-
一方でもっとセキュアな方法がお勧めされています。
-
docker run --rm -it vaultwarden/server /vaultwarden hash --preset owasp
-
-
この方法ではパスワードが 2 回聞かれるので、適切な値を入力すると token が生成されます。
-
-
SMTP の設定
- 上記 docker compose yaml では設定していませんが、vaultwarden が email を送信できるようにするために SMTP 設定を追加できます。
- 詳細はwikiを確認してください。
- 私は test 用で Gmail を設定しました。その場合はGoogle account でアプリパスワードを発行する必要があります。
- 発行したアプリパスワードと gmail アドレスを以下のように設定します。
- SMTP_HOST=smtp.gmail.comSMTP_PORT=465 SMTP_SECURITY=force_tls SMTP_USERNAME=<mail-address> SMTP_PASSWORD=<less-secure-app-password>
backup の設定詳細
-
wikiによれば、backup が必要な項目は以下の 3 つです
- 環境変数
data
ディレクトリ- Database
-
すべて手動でやってもいいですが、vaultwarden-backupを使えば rclone を使ってクラウドにバックアップを保存できます
-
rclone の設定についてはこちらの記事を参照ください。
-
backup から復元するにはクラウドにある zip ファイルを local に配置して restore 用の docker container にマウントする必要があります。
-
docker run --rm -it \ -v <復元したdataを配置したいディレクトリ>:/bitwarden/data/ \ -v <Rcloneの設定ファイルが配置されているディレクトリ>:/config/ \ -v <バックアップファイルを配置したディレクトリ>:/bitwarden/restore/ \ -e DB_TYPE=mysql \ -e MYSQL_HOST=mysql \ -e MYSQL_PASSWORD=vaultwarden \ ttionya/vaultwarden-backup:latest restore \ --zip-file "/bitwarden/restore/<バックアップファイル名>"
nginx の設定詳細
- Proxy の設定についてはwikiにサンプルがあるので、それを使います。特に特別な設定は必要ありません。
- websocket の設定は使っていなければ削除しても大丈夫です。
upstream vaultwarden-default {
zone vaultwarden-default 64k;
server http://vaultwarden:80;
keepalive 2;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' "";
}
server {
listen 80;
listen [::]:80;
server_name example.com;
if ($host = example.com) {
return 301 https://$host$request_uri;
}
return 404;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name example.com;
# Specify SSL Config when needed
ssl_certificate /path/to/certificate/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /path/to/certificate/letsencrypt/live/example.com/privkey.pem;
ssl_trusted_certificate /path/to/certificate/letsencrypt/live/example.com/fullchain.pem;
client_max_body_size 525M;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://vaultwarden-default;
}
}