メインコンテンツへスキップ
← ブログに戻る
開発ログ2026年3月23日by K.hirano

パスワードも SSH 鍵も、自宅に置いておく——Vaultwarden + Bitwarden SSH Agent で作る個人セキュリティ基盤

クラウドパスワードマネージャーへの不安と ~/.ssh/ ファイル管理の煩雑さを、Vaultwarden(RasPi 5 Docker)と Bitwarden SSH Agent の組み合わせで解決した実録。GNOME Keyring の競合解消・毎回確認ダイアログによるプロンプトインジェクション対策・snap バージョン非依存のソケット設定まで解説。

#vaultwarden#Bitwarden#ssh#password-manager#self-hosted#raspberry-pi#security#linux

パスワード管理ツールは「使っていれば安全」ではないと気づいたのは、クラウドパスワードマネージャーの大規模な情報漏洩ニュースを見てからです。

保管庫自体が狙われる。そういう可能性を、頭の隅に置きながら使い続けるのはなかなか居心地が悪い。個人の鍵束を、自分で管理できる場所に置きたいと思い始めました。

もうひとつ、ずっと気になっていたのがSSH鍵の扱いです。サーバーを増やすたびに ~/.ssh/ にファイルが増え、authorized_keys も各サーバーに分散する。どこに何を置いたか、ファイルの権限は正しいか——管理が属人的になっていくのが嫌でした。

この2つの問題を、Raspberry Pi 5 とデスクトップ上の Bitwarden で一度に解決できました。

  • Vaultwarden(Bitwarden互換OSSサーバー)を RasPi 5 に Docker でデプロイ
  • Bitwarden デスクトップの SSH Agent 機能で SSH 鍵も一元管理
  • SSH 鍵はファイルシステムに置かず、認証のたびに確認ダイアログが出る設計
  • GNOME Keyring との競合だけ注意が必要

目次

Vaultwardenとは何か

Bitwarden は広く使われているパスワードマネージャーですが、公式のサーバーを使わず自分でホストできるOSSの互換実装が Vaultwarden です。

公式 Bitwarden サーバーと比べると:

項目公式BitwardenVaultwarden
ホスト先Bitwarden社のクラウド自宅サーバー
コンテナサイズ数百MB〜65MB
DBMSSQL等SQLite(小規模向け)
ライセンスAGPL-3.0AGPL-3.0
Bitwardenクライアント互換○(完全互換)

重要なのは「完全互換」の部分です。Vaultwarden をサーバーにしても、クライアントは Bitwarden の公式アプリ(ブラウザ拡張・デスクトップ・スマホ)をそのまま使えます。鍵束をまるごと自分の管理下に置きながら、クライアントの操作感は変わらない。

Bitwarden 保管庫の管理画面(アイテムは非表示) Bitwarden Desktop の保管庫一覧。ログイン・カード・ID・メモ・SSHキーをひとつの場所で管理できる(アイテムは非表示処理済み)。

構成の全体像

terminal
[ デスクトップ(Ubuntu) ]
  ├── Bitwarden Desktop (snap v2026.2.1)
  │     └── SSH Agent 機能 ON
  └── ~/.bashrc に SSH_AUTH_SOCK 設定

[ RasPi 5(192.168.11.x)]
  └── Vaultwarden (Docker, port 8222, LAN内のみ)

[ 各サーバー(aiserver / QNAP 等)]
  └── authorized_keys に Bitwarden 生成の公開鍵のみ登録

Bitwarden デスクトップが SSH Agent として動作し、SSH 接続時には Vaultwarden の保管庫から秘密鍵を取り出して使います。秘密鍵はファイルシステムに置かない。~/.ssh/id_ed25519 のようなファイルは不要になります。

RasPi 5 へのデプロイ

docker-compose.yml の要点:

yaml
services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: unless-stopped
    ports:
      - "192.168.11.x:8222:80"  # ← RasPi 5 の LAN IP に置き換える
    volumes:
      - ./data:/data
    environment:
      - SIGNUPS_ALLOWED=false
      - ADMIN_TOKEN=${ADMIN_TOKEN}
      - DOMAIN=https://vault.example.com

SIGNUPS_ALLOWED=false は初回アカウント作成後すぐに設定します。外部公開する場合は必須です。

ADMIN_TOKEN は平文ではなく Argon2 ハッシュを使います。Vaultwarden のドキュメントに生成コマンドが記載されています。

Cloudflare Tunnel で独自ドメインとして公開すると、スマホとブラウザ拡張からも使えます。ただしデータは RasPi 5 の SQLite に保存されていて、クラウドには何も置いていない。

Vaultwarden ロック画面(独自ドメイン) Vaultwarden に独自ドメインで接続したロック画面。Bitwarden の公式クラウドではなく、自宅サーバーがバックエンド。

Bitwarden SSH Agent の設定

Bitwarden Desktop v2025.x 以降、SSH Agent が標準機能として搭載されています。設定 → セキュリティ → SSH Agent と進み、有効にするだけです。

なお、ここから先の SSH Agent まわりの手順はクライアント(Bitwarden Desktop)側の機能です。サーバーが Vaultwarden でも公式 Bitwarden クラウドでも、同じ手順がそのまま使えます。

ひとつだけ重要な選択があります。「常に確認する(毎回ダイアログ表示)」を選ぶことを勧めます。

SSH 接続のたびに「この接続を許可しますか?」というダイアログが表示されます。面倒に感じるかもしれませんが、これはプロンプトインジェクション攻撃への実質的な防御になります(AIコーディングツールでの3秒で終わる攻撃、Claude Code と Codex CLI に潜んでいた3つの穴Blog3秒で終わる攻撃、Claude Code と Codex CLI に潜んでいた3つの穴git cloneして起動するだけでAPIキーが流出していた——Claude CodeとCodex CLIに存在した3つのCVEの仕組みを解説。CVE-2026-21852・CVE-2025-59536・CVE-2025-61260はいずれも修正済み。バージョン確認方法と30秒でできる安全確認手順も紹介。も参考になります)。

仮に作業中のターミナルに悪意のある出力が挟まれ、SSH 接続を試みるコマンドが実行されたとしても、確認ダイアログが出ます。画面を見ていれば気づける。自動応答させないことに意味があります。

Bitwarden SSH Agent の認証フロー図。ssh コマンド実行のたびに確認ダイアログが出て、人間が認可しないと接続できない。秘密鍵は保管庫の中にありファイルには置かない 毎回の確認ダイアログが「人間のゲート」になる: 秘密鍵はファイルに置かず、認可なしでは1本も接続できない。

SSH鍵使用確認ダイアログ ssh コマンド実行時に表示される確認ダイアログ。「認可」を押さないと接続できない設計。

Bitwarden SSH Agent 設定画面 設定 → SSH エージェントを有効にする → 認証要求を「常に表示する」に設定。

GNOME Keyring との競合を解消する

Ubuntu デスクトップ環境では、GNOME Keyring がデフォルトで SSH Agent として動作しています。Bitwarden SSH Agent と競合するため、GNOME Keyring の SSH コンポーネントを無効化する必要があります。

bash
# ~/.config/autostart/gnome-keyring-ssh.desktop
[Desktop Entry]
Type=Application
Name=GNOME Keyring: SSH Agent
Hidden=true

Hidden=true にすることで GNOME Keyring の SSH Agent が起動しなくなります。パスワードのキーリング機能(Secrets サービス)には影響しません。SSH 部分だけが無効化されます。

次に ~/.bashrc に SSH_AUTH_SOCK を設定します。Bitwarden snap パッケージのソケットパスはバージョンで変わるため、動的に取得する書き方にします:

bash
# Bitwarden SSH Agent(snap版 — バージョン非依存)
_bw_sock=$(ls ~/snap/bitwarden/*/bitwarden-ssh-agent.sock 2>/dev/null | sort -V | tail -1)
if [ -n "$_bw_sock" ]; then
  export SSH_AUTH_SOCK="$_bw_sock"
fi
unset _bw_sock

再ログイン後に echo $SSH_AUTH_SOCK でパスが表示され、ssh-add -l で登録済み鍵の一覧が出れば完了です。

Bitwarden アカウントセキュリティ設定 アカウント単位のセキュリティ設定。Vault Timeout を「再起動時」に設定し、クリップボード自動消去は「なし」(コピー内容は手動管理)。

SSH鍵の発行とサーバーへの配布

Bitwarden Desktop → SSH鍵 タブから新しい ED25519 鍵を生成できます。秘密鍵は保管庫内に暗号化して保存され、公開鍵だけを各サーバーに配布します。

配布は通常通り ssh-copy-idauthorized_keys への直接追記で行います。既存の鍵を使っていた場合、旧公開鍵を authorized_keys から削除するのを忘れないようにします。

旧秘密鍵ファイルが残っている場合は、パスワードマネージャーのセキュアノートに保存してからファイルを削除する手順が安全です。デジタルの鍵は削除すれば消えますが、消す前にどこかに記録しておく習慣はアナログの鍵管理と変わらない。

既存のSSH鍵をインポートする

新規生成だけでなく、いま ~/.ssh/ にある鍵を保管庫へ移すこともできます。Bitwarden Desktop の「新規」→「SSHキー」で、既存の秘密鍵の中身を貼り付けるだけです。

知っておくと迷わない点が3つあります。

  • 対応形式は OpenSSH 形式と PKCS#8 形式ssh-keygen で作った一般的な鍵(-----BEGIN OPENSSH PRIVATE KEY----- で始まるもの)はそのまま貼り付けられます
  • 新規生成できるのは ED25519 のみですが、インポートなら RSA など既存の鍵タイプも持ち込めます。古いサーバーの都合で RSA 鍵を捨てられない場合も、保管庫管理には乗せられます
  • パスフレーズ付きの鍵はそのままではインポートできません。先に ssh-keygen -p -f ~/.ssh/id_ed25519 -N "" でパスフレーズを外してからインポートします。鍵を裸にするのは一瞬不安になりますが、保管庫自体がマスターパスワードで暗号化されているため、パスフレーズの役割は保管庫の暗号化に引き継がれると考えれば筋が通ります

インポートして SSH 接続を確認できたら、元のファイル(~/.ssh/id_ed25519 等)は削除します。前述の通り、削除前にセキュアノートへ控えを残しておくと安心です。

GitHubとGitでも同じ鍵が使える

Bitwarden SSH Agent は標準の ssh-agent 互換として動くので、サーバー接続だけでなく Git の SSH 認証もそのまま通ります。GitHub に公開鍵を登録して、

bash
ssh -T [email protected]

を実行すると、いつもの確認ダイアログが出て、許可すると「Hi xxx!」が返ってきます。git push のたびにダイアログが出るのが煩わしい場合は、Bitwarden 側の認証要求を「保管庫がロックされるまで記憶」に変える選択肢もあります(私は毎回表示のままにしています。pushは1日に何十回もしないので)。

コミットの SSH 署名(git config gpg.format ssh)にも同じ鍵を指定できます。サーバー接続・Git 認証・署名が1本の鍵束に揃うのは、保管庫管理に移行した後のわかりやすい恩恵です。

Windowsで使う場合

FAQ でも触れていますが、需要が多いので手順の骨子を書いておきます。Windows 版 Bitwarden Desktop の SSH Agent は、名前付きパイプ \\.\pipe\openssh-ssh-agent を使います。これは Windows 標準の OpenSSH 認証エージェントが使うのと同じ場所なので、先にそちらを止める必要があります。

  1. services.msc を開き、「OpenSSH Authentication Agent」サービスを停止して「無効」に設定
  2. Bitwarden Desktop の設定で SSH Agent を有効化
  3. ターミナル(PowerShell)で ssh-add -l を実行し、鍵一覧が見えれば完了

Linux の GNOME Keyring と構図は同じで、「OS に最初から居る SSH Agent を黙らせてから Bitwarden に席を譲る」のがポイントです。なお WSL2 から使う場合は、Windows 側のパイプを WSL 側へ中継する一手間(npiperelay + socat)が追加で必要になります。

Windows の名前付きパイプ競合図。OpenSSH 認証エージェントと Bitwarden SSH Agent が同じ名前付きパイプを使うため、先に OpenSSH 側のサービスを停止してから Bitwarden に席を譲る Windows の罠: 同じ名前付きパイプを取り合うため、標準の OpenSSH エージェントを先に停止する。

つまずいたときの確認ポイント

私がハマった点と、調べていて見かけた定番の詰まりどころをまとめます。

ssh-add -l が「Could not open a connection」になる、または一覧が空

①Bitwarden Desktop が起動しているか ②保管庫のロックが解除されているか ③echo $SSH_AUTH_SOCK が Bitwarden のソケットを指しているか——この順で確認します。保管庫がロックされると SSH Agent も止まる仕様です。欠点ではなく「ロック=鍵束ごと閉まる」という一貫性だと理解しています。

古い解説にある EXPERIMENTAL_CLIENT_FEATURE_FLAGS は設定が必要?

2024〜2025年頃の解説では、Vaultwarden 側に EXPERIMENTAL_CLIENT_FEATURE_FLAGS=ssh-key-vault-item,ssh-agent を設定する手順がよく書かれています。現在は SSH Agent がデスクトップクライアント側の安定機能になったため、本記事の docker-compose(フラグなし)で問題なく動いています。例外は Web Vault(ブラウザの管理画面)に「SSHキー」タイプが表示されないケースで、その場合のみ ssh-key-vault-item を足すと表示されます。

確認ダイアログが出ずに接続だけ失敗する

Bitwarden Desktop が最小化ではなく完全終了していると、Agent ごと居なくなります。ログイン時の自動起動で常駐させる運用にすると安定します。

実際に使ってどうか

移行してから数週間が経ちます。最初「毎回ダイアログが出るの面倒だな」と思っていたのに、1週間もしたら出ないとむしろ不安になっていました。人間はすぐ慣れる。

ssh aiserver とコマンドを打つと、Bitwarden の確認ダイアログが出て、許可を押すと接続できる。最初は手間かなと思いましたが、慣れると気にならない。むしろ「誰かに気づかれずに SSH 接続される」という状況が物理的に発生しにくくなった感覚があります。

もうひとつ気づいたのは、サーバーを追加するときの手順が整理されたことです。以前は「どの鍵をどこに配布したか」を頭で管理していましたが、今は「Bitwarden の公開鍵を authorized_keys に追加する」に統一されました。鍵の種類が1つになっている。

Vaultwarden のバックアップは QNAP NAS へ定期的にとっています。SQLite ファイル(data/db.sqlite3)をコピーするだけで完結します。rclone crypt 経由でクラウドへ暗号化バックアップすれば、RasPi が壊れても復元できます。

FAQ

Q. RasPi 5 が落ちている間は SSH できなくなりますか?

なりません。Bitwarden デスクトップは起動時に保管庫をローカルキャッシュします。Vaultwarden サーバーへの接続は同期時のみ必要で、SSH Agent の動作はキャッシュを使います。

Q. スマホから Vaultwarden に接続できますか?

できます。Bitwarden モバイルアプリの「サーバーURL」を自分のドメインに設定するだけです。操作感はクラウド版と変わりません。

Q. GNOME Keyring を無効化するとパスワードのキーリングも壊れますか?

SSH コンポーネントだけを無効化するため、GNOME Secrets サービス(パスワードリング)には影響しません。Hidden=true は SSH 部分のみに作用します。

Q. Bitwarden snap のソケットパスがバージョンアップで変わりませんか?

~/.bashrc の設定(ls ~/snap/bitwarden/*/... | sort -V | tail -1)を使うと、最新バージョンのソケットを自動参照します。snap がアップデートされても再設定不要です。

Q. Windows でも同じ構成は使えますか?

Bitwarden Desktop(Windows版)にも SSH Agent 機能があります。ただし Windows の OpenSSH Agent サービスとの競合処理が別途必要です。手順の骨子は本文の「Windowsで使う場合」の節にまとめました。

パスワードマネージャーは「どこかのサーバーを信頼する」ことで成り立っています。自己ホストはその信頼先を自分に変えることで、信頼範囲を自分の手の届く場所に限定する選択です。

完璧ではない。停電すれば落ちるし、RasPi が壊れればバックアップから復元しなければならない。でも「見知らぬサービスの信頼性に賭ける」よりは、自分の管理範囲の問題として対処できる方が気持ちが落ち着く。

信頼をどこに置くかという話は答えが出ませんが、少なくとも自分の目の届く場所に置けているという感覚は悪くないです。

関連記事

この記事を書いた人

HW系エンジニアとして20年以上、10,000件を超える顧客訪問と2,000件を超える単独ソリューション実績。AIツールを使った個人開発やIoT農園など、Raspberry Piを使ったオートメーション化なども実践中です!エンジニア専門結婚相談所も運営中、ClaudeCodeで解決できない心の課題も解決いたします!

META-MARK

GPU・CPU・PCパーツをMetaScoreで比較できます。

1,000件超のパーツデータベース。性能・効率・コスパの3軸スコアで、カタログスペックに振り回されない選択を。