自己ホスト型Vaultwardenインスタンスをデプロイする方法
今日、誰もが複数のアカウントや資格情報を管理する必要があります。そのため、適切で可能であればオープンソースのパスワードマネージャーが必要です。パスワード管理に関しては、Linuxには多くの選択肢があります。例えば、以前は標準ツールであるGPGやgitに基づいた素晴らしいコマンドライン指向のパスワードマネージャー「pass」について話しました。この記事では、個人や小規模な組織にとって理想的な解決策となる可能性のある代替手段であるVaultwardenを探ります。
このチュートリアルでは、自分でホストするVaultwardenインスタンスをデプロイする方法と、リバースプロキシとしてCaddyを使用してLet's Encrypt証明書を取得する方法を学びます。
このチュートリアルでは、あなたは学びます:
- Dockerを使用してVaultwardenインスタンスをデプロイする方法
- Caddyをリバースプロキシとして使用してLet’s Encrypt TLS証明書を取得する方法
ビットワーデン対ボルトワーデン
Bitwardenは、2要素認証ログイン、強力なパスワードのランダム生成のサポート、専用のブラウザ拡張機能を通じたログインフォームの自動入力、モバイルデバイス用クライアントアプリケーションなど、今日のこの種のソフトウェアに求められるすべての機能を備えた、機能が豊富なオープンソースのパスワードマネージャーです。
基本的なBitwardenアカウントの作成は無料ですが、そのオープンソースの性質により、Bitwardenサーバーを自己ホスティングすることが可能です。これは主にC#で記述され、MS SQLをデータベースとして使用しています。ただし、Bitwardenインスタンスはリソースを多く消費し、維持管理が複雑になる可能性があります。このため、Bitwarden APIの代替であり、より軽量な実装であるVaultwardenが作成されました。Vaultwardenは以前はBitwarden_RSとして知られており、Rustで記述され、Sqliteをデータベースとして使用します。Vaultwardenインスタンスをデプロイするための推奨方法は、公式のDockerイメージを使用することです。このチュートリアルでは、その方法と、Caddyをリバースプロキシサービスとして使用してLet's EncryptのTLS証明書を取得する方法を学びます。
キャディとは何ですか?
CaddyはGoで書かれたオープンソースのウェブサーバーで、提供するサイトのHTTPSを自動的に有効にします。リバースプロキシとして機能することができ、ACME(Automatic Certificate Management Environment)プロトコルを使用してTLS証明書を自動的に取得および更新することができます。
docker-composeファイルの作成
私たちのDocker化されたVaultwardenインスタンスを、Dockerイメージとして利用可能なCaddyと連携させる必要があるため、サービスのオーケストレーションとコンテナ間の通信を容易にするために、私たちの小さなインフラストラクチャをdocker-composeファイルで記述したいと思います。以下のようになるはずです:
version: "3"
services:
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: always
volumes:
- /etc/localtime:/etc/localtime:ro
- /srv/vaultwarden:/data
caddy:
image: caddy:2
container_name: caddy
restart: always
ports:
- 80:80
- 443:443
volumes:
- /srv/caddy/Caddyfile:/etc/caddy/Caddyfile:ro
- /srv/caddy/config:/config
- /srv/caddy/data:/data
- /srv/caddy/logs:/logs
environment:
DOMAIN: "<yourdomain>"
EMAIL: "<youremail>"
LOG_FILE: /srv/caddy/logs/access.log
分析してみましょう。
「vaultwarden」サービス
docker-composeファイルで定義した最初のサービスは「vaultwarden」であり、vaultwarden/serverイメージに基づいています。サービス定義の一環として、生成されるコンテナを「vaultwarden」と呼ぶことを指定し、非常に重要なことに、サービスが停止した場合に常に再起動されるように再起動ポリシーを定義しました。
私たちはまた、サーバー上の特定のファイルをコンテナ内の他のファイルにマップするために、2つのバインドマウントを定義しました。そのうちの最初のファイルは/etc/localtimeです:これをコンテナ内の対応するファイルにマップして、Vaultwardenがホストと同じタイムゾーンを使用することを保証しました。2つ目のバインドマウントでは、コンテナ内の/dataディレクトリを、ホスト上の私たちの選んだディレクトリにマップしました。この場合、私は/srv/vaultwarden/dataを選びましたが、パスは任意です。「data」ディレクトリには、他のものの中で、VaultwardenがSqliteデータベースファイルを保存する場所があり、これは定期的にバックアップしたいものです(たとえば、専用のcronジョブを設定することで)。
キャディサービス
私たちが定義した2つ目のサービスは、docker-composeファイルの「caddy」です。公式のCaddyのDockerイメージを使用し、コンテナを「caddy」と名付けました。そして、「vaultwarden」サービスと同様に、「常に」再起動するポリシーを設定しました。Caddyをリバースプロキシとして使用し、ACMEクライアントとしてLet’s Encryptの証明書を取得させるために、ホストのポート80と443をコンテナ内の同じポートにマッピングしました。
次に、4つのバインドマウントを定義しました。最初のものでは、コンテナ内の/etc/caddy/CaddyFileをホストシステム上の任意のパス(この場合は/srv/caddy/Caddyfile)にマッピングしました。Caddyに不慣れな方のために説明すると、Caddyfileは1つまたは複数のウェブサイトを定義するために使用される人間に優しい設定ファイルです(このことについては後ほど詳しく説明します)。
私たちが定義した2番目、3番目、4番目のバインドマウントは、コンテナ内の/data、/config、および/logsディレクトリを、ホストシステム上の/srv/caddy/data、/srv/caddy/config、および/srv/caddy/logsディレクトリにそれぞれマッピングします。
最後に、Caddyfileで後に使用されるいくつかの環境変数を定義しました: DOMAIN(Vaultwardenに使用するドメインで、証明書を取得したいドメイン)、EMAIL(リクエストに関連付けるメールアドレス)、および LOG_FILE(Caddyのログが書き込まれるファイルのパスを定義するために使用される)。
Caddyfileの作成
CaddyfileはCaddyを使用してウェブサイトを定義するために使用されます。この場合、私たちのCaddyfileは次のようになります:
{$DOMAIN}:443 {
log {
output file {$LOG_FILE} {
roll_size 10MB
roll_keep 10
}
}
tls {$EMAIL}
reverse_proxy /notifications/hub vaultwarden:3012
reverse_proxy vaultwarden:80 {
header_up X-Real-IP {remote_host}
}
}Caddyfileで最初に指定するのはウェブサイトのアドレスです。この場合、{$DOMAIN}記法を使用しました。これは、docker-composeファイルで「caddy」サービスのために定義したDOMAIN環境変数の値に置き換えられます。サイトの定義はその後、中括弧の間に記述されます。
ログ設定
最初に定義したのは、logディレクティブを介したログの動作です。outputを使用することで、ログをどこに書き込むべきかを指定しました。Caddyは「モジュール」を使用してログメッセージを管理します。デフォルトでは「stderr」モジュールを使用し、ログをコンソール(標準エラーファイルディスクリプタ)に書き込みます。この場合、ログをファイルに書き込む必要があるため、Caddyに「file」モジュールを使用するよう指示しました。最後に、ログファイルのパスをハードコーディングする代わりに、以前に定義したLOG_FILE環境変数を使用しました。
次に、roll_size と roll_keep ディレクティブを使用してログのローテーションを定義しました。前者は、ファイルが「ロール」されるべきサイズ(この場合は10MB)を定義するために使用され、後者は保持するログファイルの数を設定します。
リバースプロキシの設定
次に私たちが行ったのは、Caddyのリバースプロキシ動作を設定することでした。reverse_proxy ディレクティブを使用して行いました。このディレクティブで使用する構文は次のとおりです:
reverse_proxy [<matcher-token>][<upstreams...>]「matcher-token」は、ディレクティブが適用される条件を制限するために使用されます。この場合、スラッシュで始まるパスを使用しました:リクエストが一致する場合のみ処理されます。ディレクティブと共に使用される2つ目の引数は、リクエストがリダイレクトされるべきバックエンドです。
リクエストを /notifications/hub パスを使用してポート3012の「vaultwarden」へリダイレクトします(この場合、「vaultwarden」はdocker-composeファイルで定義したサービスの名前で、コンテナのホスト名としても使用されます)。それ以外のすべてはポート80の同じバックエンドへリダイレクトされます。 header_up ディレクティブはヘッダーを操作するために使用されます。この場合、「X-Real-IP」を「{remote_host}」に設定します。これはクライアントのIPで置き換えられます。これは、Vaultwardenがログに使用できるようにし、fail2banなどのサービスがそれを処理できるようにするために行われます。
docker-composeファイルで定義した通り、事前に作成したディレクトリ/srv/caddyの下に、拡張子なしの「Caddyfile」という名前のファイルに内容を保存する必要があります:
sudo mkdir /srv/caddyサービスを開始します
Caddyfileが準備できたので、コンテナを起動できます。docker-compose up コマンドを実行するだけで済みます(docker-composeファイルがある同じディレクトリ内で実行するか、-fにdocker-composeファイルのパスを渡すことによって)。サービスをバックグラウンドで実行したいので、-dオプションを使用する必要があります:
sudo docker-compose up -d前述のように、CaddyがLet's EncryptからHTTPチャレンジを通じてTLS証明書を取得するためには、指定されたドメインが公開アクセス可能でなければなりません。すべてが期待通りに進めば、指定されたアドレスでVaultwardenにアクセスできるはずです。
アカウントを作成し、暗号化されたボールトを設定することが可能になりました。
結論
このチュートリアルでは、BitwardenとVaultwardenの違いを学び、Dockerを使用してプライベートサーバーに自己ホスト型のVaultwardenインスタンスをデプロイする方法を見ました。また、Caddyをリバースプロキシとして使用して、Let's EncryptからTLS証明書を取得する方法も見ました。

