Skip to content

feat(nixos-laptop): SSH 鍵を TPM に封印する - #402

Open
gapul wants to merge 1 commit into
mainfrom
feat/laptop-tpm-agent
Open

feat(nixos-laptop): SSH 鍵を TPM に封印する#402
gapul wants to merge 1 commit into
mainfrom
feat/laptop-tpm-agent

Conversation

@gapul

@gapul gapul commented Aug 21, 2026

Copy link
Copy Markdown
Owner

なぜ

持ち出す機械なのにクライアント鍵がただのファイルだった。しかもラップトップは自分で証明書を更新できない(署名できるのは Touch ID のある Mac だけ)ので、一番長い有効期限の証明書を持つクライアントでもある。

弱い鍵の置き場所と長い有効期限が、同じ機械で重なっている。鍵ファイルと証明書を一緒に持ち出されれば残り期間ずっと入られるので、まずここを潰す。TPM に封印すれば鍵は取り出せず、端末ごと盗まれても証明書だけでは何もできない。

Mac の Secure Enclave 鍵の Linux 版にあたる。

モジュールはある(前言撤回)

services.ssh-tpm-agent が home-manager に入っている。NixOS 側のオプションしか見ずに「モジュールが無いので unit の手書きが要る」と書いたが、誤りだった。enable = true で足りる。

ただし home-manager の sshAuthSock.initialization は bash / fish / nushell しか定義していない(modules/misc/ssh-auth-sock.nix)。zsh が無いので SSH_AUTH_SOCK の export は自分で書いた。ここを踏むと agent は起動するのに ssh が見に行かない、という分かりにくい壊れ方をする。

ssh_config の IdentityAgent

IdentityAgent ~/.bitwarden-ssh-agent.sock の直書きをやめ、IdentityAgent SSH_AUTH_SOCK に変えた(5箇所)。

同じ ssh_config を sops で Mac / ラップトップ / WSL に配っている以上、機械ごとに違う agent を指す必要がある。IdentityAgentSSH_AUTH_SOCK より優先されるので、直書きのままだとラップトップで agent を立てても無視される。

母艦で実際にログインして等価であることを確認済み。

$ ssh -o IdentityAgent=SSH_AUTH_SOCK macmini
login OK via IdentityAgent=SSH_AUTH_SOCK

書き換えは IdentityAgent 行以外が変化していないことを差分で検証してから適用した。

TPM へのアクセス権

security.tpm2.enabletss グループが要る。モジュールが eval 時に assert してくれたので気付けた(実行時の permission error にならない)。LUKS の TPM スロットは initrd の root なのでこれを必要としないが、ssh-tpm-agent はユーザとして /dev/tpmrm0 を触る。

CI の穴

CI 用のラップトップ設定(nixos-laptop-ci)は home モジュールの一覧が本番と別物で、ssh-tpm-agent.nixrestic-backup-linux.nixsecrets.nix も含んでいなかった。この手の追加を CI がまったく検証できていない状態だったので、今回のものは揃えた。残りは別途。

確認

  • nixosConfigurations.nixos-laptop-ci の eval が通る
  • ビルド後の設定に ssh-tpm-agent の systemd user unit があること、zsh の init に export が入ることを eval で確認
  • WSL には漏れていないことを確認(TPM が無いので入っては困る)
  • nix fmt 差分なし、just docs 差分なし

実機での作業

ラップトップは今オフラインなので未検証。起動したら鍵を作る。

ssh-tpm-keygen -C laptop            # PIN を付けるなら --with-pin

そのあと母艦から just ssh-cert-host nixos-laptop#401)で証明書を発行する。

持ち出す機械なのに鍵がただのファイルだった。しかもラップトップは自分で証明書を
更新できない(署名できるのは Touch ID のある Mac だけ)ので、一番長い有効期限の
証明書を持つクライアントでもある。弱い鍵の置き場所と長い期限が同じ機械で重なる
ので、ここを先に潰す。

ssh-tpm-agent は home-manager にモジュールがある(services.ssh-tpm-agent)。ただし
sshAuthSock.initialization は bash / fish / nushell しか定義しておらず zsh が無い
ので、SSH_AUTH_SOCK の export は自分で書いた。

ssh_config の IdentityAgent は Bitwarden のソケット直書きだったのをやめ、
IdentityAgent SSH_AUTH_SOCK に変えた。同じ ssh_config を Mac / ラップトップ /
WSL に配っている以上、機械ごとに違う agent を指す必要がある。母艦で実際に
ログインして等価であることを確認済み。

CI 用のラップトップ設定は home モジュールの一覧が本番と別で、この手の追加を
検証できていなかったので揃えた。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant