Skip to content

feat(ssh): 鍵を配るのをやめて認証局と短命の証明書にする - #401

Open
gapul wants to merge 5 commits into
mainfrom
feat/ssh-ca
Open

feat(ssh): 鍵を配るのをやめて認証局と短命の証明書にする#401
gapul wants to merge 5 commits into
mainfrom
feat/ssh-ca

Conversation

@gapul

@gapul gapul commented Aug 21, 2026

Copy link
Copy Markdown
Owner

なぜ

authorized_keys に公開鍵を撒く方式は、機械が増えるたび、鍵を作り直すたびに全台を触ることになる。失効も「全部から消して回る」しか手段がない。hosts/homeserver.nix のコメントが実態を書いていた。

Keys are not declared here: they live in the Bitwarden-managed agent, and this repo is public. Add them by hand

CA なら信頼する側の設定は1回で終わり、以後は証明書を切るだけでサーバに触らない。有効期限があるので失効は放っておけば起きる。

CA 鍵の置き場所

MacBook の Secure Enclave、protection = "bio"署名のたびに Touch ID が要るのがこの構成の要で、Mac にコードを実行できる攻撃者がいても、人が物理的に指を置かない限り証明書は生まれない。

常時起動のサーバに CA を置く案は採らなかった。踏まれた瞬間に無承認で刷り放題になり、しかも TrustedUserCAKeys に載っている以上その危険は毎日続く。

鍵は sk-ecdsa-sha2-nistp256@openssh.comnix-secure-enclave-key が CryptoTokenKit の identity を macOS 標準の SSH プロバイダ経由で見せるため、OpenSSH からは FIDO 認証器と同じ扱いになり、-w でプロバイダを指すだけで通常の CA 署名に乗る。

予備 CA を作らない

予備 CA は使うのが数年に一度でも、任意 principal の発行権を常時抱えることになる。復旧に必要なのは「Mac が死んでも入れること」だけなので、ログイン権しか持たない break-glass 鍵で代替する(docs/SSH_CA.md)。

enclave の identity が1本な理由

nix-secure-enclave-key は2本目以降の identity に対して使える秘密鍵スタブを作らず、公開鍵の参照ファイルしか置かない(ssh-keygen -sinvalid format で落ちる)。ssh ensure での作り直しは応答が返らず、ssh-keygen -K での吸い出しは対話プロンプトが噛み合わない。

なので enclave を割り当てられる役は1つしかない。都度承認が効くことの価値が高い CA に使い、証明書を載せる側は enclave である必要がないので既存の Bitwarden 管理鍵をそのまま使う。上流が直れば分離できる。

Mac 以外のマシン

発行できるのは Touch ID のあるこの Mac だけなので、他のマシンは自分で更新できない。長めの有効期限を切って持っていく運用にしてある。承認端末を1台に絞ると決めた結果の非対称性で、仕様。

just ssh-cert ~/tmp/laptop.pub 720   # 30 日

ついでの修正

just secrets が壊れていた。#393 で消した secrets/secrets.yaml を指したままだったので、common / darwin / homelab を選べる形にし、rekey は全ファイルを回すようにした。

確認

  • 実際に証明書を発行して検証済み。Signing CA: ECDSA-SK … (using sk-ecdsa-sha2-nistp256@openssh.com)、principal は gapul
  • コミットした nix/keys/ssh-user-ca.pub が実際の署名 CA と一致することを照合
  • nixosConfigurations.{homeserver,nixos-laptop-ci} の eval が通り、TrustedUserCAKeys/etc/ssh/gapul-user-ca.pub に解決する
  • nix fmt 差分なし、just docs 差分なし

マージ後

サーバ側を deploy してから、break-glass 鍵の設置(docs/SSH_CA.md)。Proxmox の CT は NixOS 化前なので sshd_config に手で1行足す。

gapul added 3 commits August 21, 2026 18:42
各ホストの authorized_keys に公開鍵を撒く方式は、機械が増えるたび鍵を作り直す
たびに全台を触ることになり、失効の手段も「全部から消して回る」しかなかった。
homeserver は実際に手置きのままだった。

CA 鍵は MacBook の Secure Enclave に置き protection = bio にしてある。署名の
たびに Touch ID が要るので、Mac にコードを実行できる攻撃者がいても、人が指を
置かない限り証明書は生まれない。常時起動のサーバに CA を置くと踏まれた瞬間に
無承認で刷り放題になるため選んでいない。

予備 CA は作らない。TrustedUserCAKeys に載せっぱなしになるので、数年に一度しか
使わないのに任意 principal の発行権を毎日抱えることになる。復旧に必要なのは
ログイン権だけなので break-glass 鍵で代替する(docs/SSH_CA.md)。

enclave の identity は1本だけ。nix-secure-enclave-key は2本目以降に使える秘密鍵
スタブを作らず公開鍵の参照しか置かないため、割り当てられる役は1つ。都度承認の
価値が高い CA に使い、証明書を載せる側は既存の Bitwarden 管理鍵をそのまま使う。

合わせて just secrets を修正。#393 で消した secrets/secrets.yaml を指したままで
壊れていた。
クライアントは人が操作する3種類(macbook / nixos-laptop / スマホ)だけで、
macmini と homeserver はアクセス先。信頼する側に Mac が入っていなかったので、
darwin 用のモジュールを足した。

macOS の sshd は nix 管理ではないが、/etc/ssh/sshd_config が
Include /etc/ssh/sshd_config.d/* で終わっているので drop-in で足りる。
既存ファイルを書き換えないので、OS 更新で戻される心配もない。

誤って macmini に配ったクライアント証明書は実機から削除済み。
gapul added 2 commits August 22, 2026 12:52
「2本目の identity にスタブが作られない」は原理的な制約ではなく、
ssh-keygen -K が resident key を全部同じファイル名に書き出し、2本目で
Overwrite (y/n)? を聞いてくるのに非対話で走っているせいだった。答えてやれば
取り出せる。ツール側は一時ディレクトリに複数ペアが出てくる前提で fingerprint で
選り分ける作りなので、そこが噛み合っていない。

これで CA (label ca) と認証鍵 (label auth) を分けられるので、CA は
~/.ssh/id_enclave_ca に移した。役割の違う鍵を1本に兼ねる状態を解消する。
コミットしてある CA 公開鍵も差し替え、実際に発行して署名者と一致することを確認。

回避手順は docs/SSH_CA.md に残した。どちらが残るかは列挙順次第なので
fingerprint 照合が必須という注意つき。
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