bitwarden_rsでパスワード管理サーバーをセルフホスティング

作成: 2019年09月29日

更新: 2021年04月15日

bitwarden

最近注目を集めているbitwardenというパスワード管理サービスがある。有名なLastPass1Passwordのようにログインパスワードやクレジットカード情報をサーバー上で管理してくれる。bitwardenがこれらと違うのは基本料金が無料という点にある。課金することでチーム向けの機能が使えたりサポートが受けられたりするが、一般ユーザーは無料で問題ない。1Passwordに比べて機能が少ないともいわれているが、iOS、android、Windows、macOS、Linuxの全OSおよびWebをカバーしていて、パスワード生成、自動入力など基本はしっかり押さえいる。

セルフホスティング

しかしlastpassがハッキングされたようにbitwardenの利用者数がこれから多くなれば攻撃の対象になってしまうかもしれない。しかし、bittwardenはオープンソースで運営されていてソースコードもGitHubで公開されている。Dockerイメージとしても公開されているので、GitHubのReadmeに従えば簡単に自分のサーバーでデプロイすることができる。結局外部サーバーに預けることとなるが他の利用者と保存先を分けることになるので攻撃の対象にはなりにくいはず。費用を抑えるには自宅サーバーやAWSのt2.microなどでデプロイしたくなるが要求スペックが以外に重い。メモリ2GBのVPNを用いると結構な金額になる。
requirements

bitwarden_rs

そこで有志によって開発されたのがbitwarden_rs。Rustでbitwardenを構成しなおし、機能はそのままで軽量化に成功している。具体的な要求スペックは書かれていないがメモリ1GBのAWS t2.microやメモリ0.6GBのGoogle Cloud f1miroでも問題なく動く。また公式のbitwardenはセルフホスティングしても課金しなければ一部機能が使えないが、bitwarden_rsは非公式なためすべての機能が無料で使える。注意点としてあくまで非公式なためちゃんと公式のアップデートを追えているかを確かめる必要がある(2019/9/29時点では更新されている)。オープンソースなので自分でコントリビュートできるくらい理解できればよりセキュリティ的に完璧

bitwarden_rsのデプロイ

bitwarden_rsもdockerイメージが用意されていて、Readmeに従えば一応デプロイができるがhttpsの設定がどうもうまくいかないのでWikiに書いてあるDocker Composeを使った方法がいい。サーバーにDockerとdocker-composeを導入し、以下の2ファイルを作成する。

docker-compose.yml#docker-compose.yml

version: "3"

services:
  bitwarden:
    image: bitwardenrs/server
    restart: always
    volumes:
      - ./bw-data:/data
    environment:
      WEBSOCKET_ENABLED: "true" # Required to use websockets
      SIGNUPS_ALLOWED: "true" # set to false to disable signups

  caddy:
    image: abiosoft/caddy
    restart: always
    volumes:
      - ./Caddyfile:/etc/Caddyfile:ro
      - caddycerts:/root/.caddy
    ports:
      - 80:80 # needed for Let's Encrypt
      - 443:443
    environment:
      ACME_AGREE: "true" # agree to Let's Encrypt Subscriber Agreement
      DOMAIN: "bitwarden.example.org" # CHANGE THIS! Used for Auto Let's Encrypt SSL
      EMAIL: "bitwarden@example.org"  # CHANGE THIS! Optional, provided to Let's Encrypt
volumes:
  caddycerts:
Caddyfile#Caddyfile

{$DOMAIN} {
    tls {$EMAIL}

    header / {
        # Enable HTTP Strict Transport Security (HSTS)
        Strict-Transport-Security "max-age=31536000;"
        # Enable cross-site filter (XSS) and tell browser to block detected attacks
        X-XSS-Protection "1; mode=block"
        # Disallow the site to be rendered within a frame (clickjacking protection)
        X-Frame-Options "DENY"
    }

    # The negotiation endpoint is also proxied to Rocket
    proxy /notifications/hub/negotiate bitwarden:80 {
        transparent
    }

    # Notifications redirected to the websockets server
    proxy /notifications/hub bitwarden:3012 {
        websocket
    }

    # Proxy the Root directory to Rocket
    proxy / bitwarden:80 {
        transparent
    }
}

docker-compose.ymlのDOMAIN、EMAILの部分はLet's Encryptの証明書発行時に使われるので自分のドメイン、メールアドレスに変更する。ドメインを無料で済ませたいならfreenomieserverなどを使う。そのあと

$ docker-compose up -d

で起動、

$ docker-compose down

で停止できる。
SIGNUPS_ALLOWEDをfalseにすることで新規アカウント作成を禁止できるので自分のアカウントを作成したらfalseにして再起動すればいい。

$ docker-compose down && docker-compose up -d

更新

bitwarden_rsが定期的に更新されるのでセキュリティのため更新する必要がある.bitwarden_rsのdocker image を更新して再起動すればいい.

$ sudo docker-compose pull && sudo docker-compose down && sudo docker-compose up -d

自分は以下のようにcrontabに登録し,毎日pullして更新があったときのみ再起動している.

crontab0 4 * * * sudo docker-compose pull | grep "Downloaded newer image" && sudo docker-compose down && sudo docker-compose up -d && sudo docker image prune

移行

何らかの事情でサーバーを移行する際はdockerでバインドしているbw-dataディレクトリを移行すれば,ユーザーデータ,パスワードデータすべてが保持できる.