Vaultwarden自社構築でパスワード管理コストを月5万円削減する

インフラ中級メンバー限定
VaultwardenBitwardenDockerNginxSelf-hostedSecurity

50人チームで月6万円を払い続けている理由はあるか

パスワードマネージャーの法人契約は、社員数が増えるほどコストが膨らむ。

サービス 料金(年間契約) 50人・月額換算
1Password Business $7.99/ユーザー/月 約60,000円/月
Bitwarden Teams $4.00/ユーザー/月 約30,000円/月
Vaultwarden(自社構築) VPSのみ 約1,500円/月

1Password Business を50人チームで使うと、年間で約72万円。VPS上にVaultwardenを構築すると年間約1.8万円。差額は年間約70万円(月5.8万円)になる。


Vaultwardenとは

Vaultwarden は Bitwarden サーバーの非公式・軽量互換実装。Rust で書かれており、公式の Bitwarden アプリ(iOS・Android・Chrome拡張・デスクトップ)がそのまま使える

  • アイドル時のRAM使用量: 約50MB(公式Bitwardenサーバーの1/10以下)
  • ライセンス: AGPL-3.0(オープンソース)
  • 対応クライアント: Bitwarden の全公式クライアント

重要な前提: Vaultwarden は非公式実装であり、Bitwarden社のサポート対象外。セキュリティパッチの適用・バックアップは自社責任になる。それを理解した上で導入すること。


必要なもの

  • VPS: Ubuntu 22.04+ / 1vCPU・1GB RAM 以上(512MBでも動くが余裕を持って)
  • ドメイン: vault.example.com など(HTTPS必須・Bitwardenクライアントが HTTP を拒否する)
  • Docker・Docker Compose: 導入済みであること
  • Nginx: リバースプロキシとして使用

Step 1: ディレクトリ作成と docker-compose.yml

mkdir -p /opt/vaultwarden && cd /opt/vaultwarden

docker-compose.yml:

services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:80"
    volumes:
      - vw-data:/data
    env_file:
      - .env

volumes:
  vw-data:

127.0.0.1:8080 にバインドすることで、Vaultwarden はリバースプロキシ経由でのみアクセス可能になる。インターネットから直接叩けない。


Step 2: .env ファイルの設定

# .env
DOMAIN=https://vault.example.com
SIGNUPS_ALLOWED=true      # 初期アカウント作成後に false に変更
ADMIN_TOKEN=              # 後述の手順でArgon2ハッシュを生成して入れる
ENABLE_WEBSOCKET=true     # リアルタイム同期に必要

管理者トークンの生成(Argon2id):

docker run --rm -it vaultwarden/server /vaultwarden hash
# パスワードを入力するとArgon2ハッシュが出力される
# 出力された文字列を ADMIN_TOKEN に設定する

平文パスワードをそのまま ADMIN_TOKEN に入れない。Argon2ハッシュのみ有効。


Step 3: Nginx リバースプロキシ設定

server {
    listen 443 ssl;
    server_name vault.example.com;

    ssl_certificate     /etc/letsencrypt/live/vault.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/vault.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8080;
        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;

        # WebSocket(リアルタイム同期に必要)
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

server {
    listen 80;
    server_name vault.example.com;
    return 301 https://$host$request_uri;
}

現行バージョンでは、WebSocket は通常HTTPポートと同じポートで処理される。旧バージョンで必要だった /notifications/hub 用の別ロケーションブロックは不要。

SSL証明書は Certbot(Let’s Encrypt)で取得:

certbot --nginx -d vault.example.com

Step 4: 起動と初期設定

docker compose up -d
docker compose logs -f    # ログでエラーがないか確認

初期設定の手順:

  1. https://vault.example.com でアカウントを作成
  2. 全員のアカウント作成が終わったら .envSIGNUPS_ALLOWED=false に変更
  3. docker compose restart でコンテナ再起動
  4. https://vault.example.com/admin に管理者パスワードでログイン → 設定を確認

SIGNUPS_ALLOWED=false への変更を忘れると誰でもアカウントを作れる状態になる。必ず変更すること。


Step 5: バックアップ設定(最重要)

パスワードマネージャーはバックアップが止まった瞬間に運用失敗になる。3-2-1ルール(3コピー・2種類のメディア・1拠点外)を最低限守る。

SQLiteのバックアップ(実行中のコンテナから安全に取得):

# 直接ファイルをコピーしない(破損リスク)
# 必ず .backup コマンドを使う
docker exec vaultwarden sqlite3 /data/db.sqlite3 \
  ".backup '/data/db-backup.sqlite3'"

# バックアップファイルをホストにコピー
docker cp vaultwarden:/data/db-backup.sqlite3 /backup/vaultwarden/

バックアップ対象ファイル:

  • db.sqlite3 — メインDB(パスワード全件)
  • attachments/ — 添付ファイル
  • sends/ — Send機能のデータ
  • rsa_key.pem / rsa_key.pub.pem — 暗号化キー
  • config.json — 設定

cron で毎日自動バックアップ:

# crontab -e
0 3 * * * docker exec vaultwarden sqlite3 /data/db.sqlite3 \
  ".backup '/data/db-backup.sqlite3'" && \
  cp /var/lib/docker/volumes/vaultwarden_vw-data/_data/db-backup.sqlite3 \
  /backup/vaultwarden/db-$(date +\%Y\%m\%d).sqlite3

Cloudflare Tunnel との連携(ポート開放なしで公開)

VPS のポートを直接インターネットに公開したくない場合、Cloudflare Tunnel を使うと UFW でポートを閉じたままセキュアに公開できる。

# cloudflared インストール(Ubuntu)
curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb -o cloudflared.deb
dpkg -i cloudflared.deb

# 認証
cloudflared tunnel login

# トンネル作成
cloudflared tunnel create vaultwarden

# トンネル設定ファイル (~/.cloudflared/config.yml)
tunnel: <TUNNEL_ID>
credentials-file: /root/.cloudflared/<TUNNEL_ID>.json

ingress:
  - hostname: vault.example.com
    service: http://127.0.0.1:8080
  - service: http_status:404

注意: Cloudflare Tunnel 経由の場合、トラフィックは Cloudflare で一度復号化される。完全にエンドツーエンドで暗号化された通信が必要なら、Tunnel を使わず直接 HTTPS を提供する構成にする。パスワードデータ自体は Bitwarden の暗号化(AES-256)で保護されているため、実務上の許容範囲は自社のセキュリティポリシーによる。


まとめ:コスト比較の再確認

項目 1Password Business Vaultwarden
50人・月額 約60,000円 約1,500円(VPS)
50人・年額 約720,000円 約18,000円
年間削減額 約702,000円
クライアントアプリ 専用 Bitwarden公式(全OS)
サポート 公式24/7 コミュニティ・自己責任
運用負荷 ゼロ バックアップ・アップデート

「運用負荷」が増える分、コストが下がる構造。社内にLinux/Docker を触れる担当者がいるかどうかが判断基準になる。


会員限定:Nginx + Cloudflare WAF 設定ファイル一式

Vaultwarden を外部公開する際に必要な Cloudflare WAFカスタムルール(/admin パスの IP制限・海外からのブルートフォース対策) と、レート制限を組み込んだ Nginx 設定ファイル完全版 を会員限定で公開している。

この続きはメンバー限定です

メールアドレスを登録すると、本記事の設定ファイル・コードと全 10 本の実践記事が読めます。無料・いつでも解除可。

記事一覧に戻る