ラズパイで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;
    }
}

コメント

タイトルとURLをコピーしました