6 ポイント 投稿者 GN⁺ 25 일 전 | 1件のコメント | WhatsAppで共有
  • SSH証明書は、従来の公開鍵ベースSSH認証の煩雑さを解消し、クライアントとサーバー間の自動信頼を提供する
  • OpenSSH 5.4からサポートされており、CA(認証局) がユーザー鍵とホスト鍵に署名することで、authorized_keys を修正せずに認証できる
  • 証明書には有効期限、許可ユーザー(principal)、アクセス元IP、強制コマンド(force-command) などを含められ、きめ細かなアクセス制御をサポートする
  • TOFU(Trust on First Use) の手順が不要になり、ホスト鍵変更時も警告なしで安全に接続できる
  • 自動署名サーバーやツールを活用すれば、大規模サーバー環境のSSH管理自動化とセキュリティ向上が可能

SSH証明書の概要と従来のSSH鍵ベース認証の限界

  • SSH接続時には、初めて接続するサーバーのホスト鍵フィンガープリントを確認する必要があり、多くのユーザーはこれを検証せずに yes を入力する TOFU(Trust on First Use) 方式を使っている
    • 管理者はサーバーのフィンガープリントを直接確認するか、ssh-keygen -l -f /etc/ssh/ssh_host_ed25519_key コマンドで検証できる
  • 公開鍵ベース認証ではパスワードなしで接続できるが、各サーバーの authorized_keys ファイルに公開鍵を配布する必要がある
  • SSHエージェント(ssh-agent)を使えば、秘密鍵をメモリに保存し、繰り返し入力せずに認証できる
  • 従来方式の限界
    • ユーザーごとにサーバーへ公開鍵をコピーする必要がある
    • ホスト鍵変更時にクライアント側で警告メッセージが発生する
    • TOFUによる信頼管理の煩雑さ

SSH証明書と認証局(CA)

  • SSH証明書(Certificate) はOpenSSH 5.4(2010年3月)からサポートされており、既存のSSH鍵フォーマットを拡張した構造
  • SSH CAはSSH鍵ペアで構成され、公開鍵が信頼のルートとして機能する
  • 主な利点
    • サーバーの authorized_keys ファイルを修正する必要がない
    • ホスト鍵を置き換えても警告が出ない
    • TOFU手順の排除により自動信頼を実現
    • 証明書に許可ユーザー(principal)許可IP有効期限強制コマンド(force-command) などを含められる
    • 証明書の期限切れ時にアクセスを自動的に遮断できる

SSH CAの構築と署名手順

  • CAシステムでECDSAアルゴリズムを用いてCA鍵ペアを生成
    • ssh-keygen -t ecdsa -C "SSH CA" -f CA/ssh-ca
  • ユーザーは自分の公開鍵(*.pub)をCAに渡し、CAはそれに**署名(sign)**して証明書(*-cert.pub)を発行する
    • 例: ssh-keygen -s CA/ssh-ca -I "Jane Jolie" -n jane -z 001 -V +1w jane.pub
  • サーバー構成
    • CA公開鍵を /etc/ssh/ssh-ca.pub に保存し、TrustedUserCAKeys 設定を追加
    • サーバーホスト鍵をCAで署名(ssh-keygen -h -s CA/ssh-ca ...)し、HostCertificate 項目に登録
  • クライアント構成
    • known_hosts ファイルに @cert-authority を1行追加
    • 例: @cert-authority *.example.com $(cat CA/ssh-ca.pub)

SSH証明書ベースの接続と検証

  • ユーザーは署名済み証明書と秘密鍵を一緒に使って接続する(ssh -i jane -l jane alice.example.com
  • サーバーログには証明書のID、シリアル番号(serial)、CAフィンガープリントが記録される
  • 複数のホスト名またはIPを証明書のprincipalとして追加できる
  • 証明書で指定されたprincipal以外のユーザーとしてログインを試みると、Certificate invalid: name is not a listed principal エラーが発生する
  • 証明書に強制コマンド(force-command) または 許可IP(source-address) を設定することで、きめ細かなアクセス制御が可能

点検とトラブルシューティングのチェックリスト

  • サーバー側の確認項目

    • TrustedUserCAKeys 設定とCA公開鍵の存在
    • ホスト鍵への署名と HostCertificate の指定
    • sshd の再起動が必要
  • クライアント側の確認項目

    • ユーザー鍵がCAによって署名されている必要がある
    • known_hosts@cert-authority 項目とprincipalが一致している必要がある
    • 証明書の期限切れ時には Certificate invalid: expired メッセージが表示される
    • 証明書の制約条件が一致しない場合、パスワード入力が求められる
    • SSHエージェントに証明書を追加すると、鍵と証明書の両方が登録される(ssh-add jane
    • 署名時のオプション(-O)で機能を制御できる
    • 例: -O clear ですべての権限を削除した後、permit-agent-forwardingpermit-port-forwarding のみを許可

ホスト鍵証明書の自動化

  • Pythonモジュール sshkey-tools とBottlePyを使って自動署名サーバー(hkbot) を実装
    • CAサーバーで hkbot.py を実行した後、HTTPリクエストでホスト公開鍵をアップロードすると自動署名される
    • クライアントでは curl -F hostkey=@/etc/ssh/ssh_host_ed25519_key.pub http://CA:8870 | sh コマンドで自動インストール
    • /etc/ssh/sshd_config を修正して検証後、systemctl restart sshd で適用
  • 以後のSSH接続では、証明書ベースで自動信頼とログインが可能になる

SSH証明書の利点まとめ

  • TOFU不要、クライアントとサーバー間の自動信頼
  • 短期有効証明書の発行により一時的なアクセス制御が可能
  • 証明書の期限切れ時にアクセスを自動遮断でき、authorized_keys の整理が不要
  • 強制コマンド、PTY制限、アクセス元IP制御 などのきめ細かなポリシー設定が可能
  • 自動化ツールにより大規模サーバー環境の管理簡素化が可能
  • 関連プロジェクトとして Smallstep SSH を紹介

追加参考資料

更新

  • SSH CAは自前のサーバーを保有し、root権限がある環境で特に有用
  • マルチユーザーシステムでは、既存の known_hosts および authorized_keys 方式が依然として必要
  • SSH証明書フォーマット標準化ドラフト: draft-miller-ssh-cert-06

1件のコメント

 
GN⁺ 25 일 전
Hacker Newsの意見
  • いまだにSSHパスワードを使っている人がいるのは驚き
    特に大企業の環境では複数のパスワードポリシーが絡み合っていて、単にサーバーへ接続するだけでも時間がかかる
    そのため ssh-keygen で鍵を使うよう案内しても、ほとんどは「そのうちやろう」と言って結局やらない

    • 鍵は個人や会社で中央管理の仕組みがあるときに有用
      しかし現実には 1 つの共通鍵を複数サーバーで使ったり、鍵を共有したりして、管理がすぐにぐちゃぐちゃになりがち
      パスワードには少なくとも単純だという利点がある
    • 私は何年もYubikeyベースのHSMで SSH 鍵を管理している
      パスワードはないが、ログイン時に物理的に Yubikey に触れる必要がある
    • ssh-copy-id のような分散鍵の利用は、ハッカーがネットワーク内を横移動しやすくするので、多くの組織がこれを禁止している
  • 数か月おきに誰かがまたSSH証明書を発見してブログ記事を書く
    私も 15 年前に関連記事を書いたが、今見ると不十分だった

    • 多くの人が鍵と証明書を混同している
      セキュリティエンジニアでさえ、SSH 証明書ではなく鍵認証を使っていることを忘れがちだ
    • SSH 証明書は特定のユーザーに限られた期間と権限でアクセスを許可できるので有用
    • 私も SSH 証明書は知っていたが、鍵ベースから移行できなかった
      複数サーバーの鍵を手作業で管理するのがあまりに面倒だ
      今からでも移行する価値があるか悩んでいる
    • 10 年前、職場で SSH CA を作ったときに上のブログ記事を参考にした
  • TOFU(Trust On First Use) 方式は単純だが、かなり通用する
    自分のサーバーではホスト鍵を直接確認したら、それで十分だ
    大企業環境では、内部サーバーの公開鍵一覧を SSL で署名された社内サイトに載せておけばよい
    しかしサーバー数が多い、または頻繁に入れ替わる環境では証明書のほうがはるかに優れており、TOFU には多くの面で限界がある
    ブラウザにもサーバーの TLS 鍵が変わったときに知らせる機能があればよいのにと思う

    • 1996 年から SSH を使っているが、実際に公開鍵を手動で検証する人を見たことがない
      ほとんどはただ "yes" と入力して先へ進む
  • 会社ではZscaler の SSL 検査のせいで時間と金を大量に無駄にしている
    "self-signed certificate in certificate chain" エラーが出ると、いつも頭痛の種だ

    • 友人の会社の Windows 11 に入っていた Zscaler を解析したが、ほぼマルウェア級だった
      独自のルート証明書を仕込み、ブラウザ設定をロックしてプロキシを使えなくする
      Firefox や Chrome の設定ファイルを修正しても即座に上書きされる
      しかも GUI から無効化するには IT のパスワードが必要だ
      Cybereason のアンチウイルスより少しましな程度だ
    • うちの会社のCisco Umbrellaも同じだ
      HTTP ベースのプロトコルをすべて壊す
      Git、RubyGems、go mod、Nix など数多くのツールが壊れる
      ベンダーは「透過的」だと言うが、実際にはまったくそうではない
      問題の診断に何時間もかかり、ほとんどの管理者はこうした破壊力を理解していない
    • ちなみに SSH 証明書はX.509 証明書とは別物
  • 記事では CA 証明書の利点しか触れられていなかったが、欠点も確かに存在する
    私は TOFU に起因するセキュリティ問題を経験したことがない

    • 「事故がなかったから安全だ」というのは、シートベルトをしなくてもいいという理屈と同じだ
      SSH 証明書の欠点があるなら、具体的にどの点なのか知りたい
    • TOFU は便利だが必須ではない
      セキュリティを強化したいなら、USB など安全なチャネルで公開鍵を交換すればよい
      証明書を使っても結局は同じ手順を踏む必要があり、ただ管理主体がユーザー側から管理者側へ移るだけだ
      大規模組織では証明書が有用な場合もあるが、一般的な安全性は同じだ
    • CA の設定を事前に構成できるなら TOFU は避けられる
      インストールスクリプトや配布イメージに含めればよい
      TOFU に意味があるのは、すでにセットアップ済みのマシンへアクセスするときだけだ
    • 「まだ TOFU によるセキュリティ事故がなかった」というのは、まだ起きていないだけという意味だ
  • うちの dev/stg 環境では毎日マシンの半分を再インストールしている
    SSH ホスト証明書のおかげで known_hosts を消したり鍵を維持したりする必要がなく、ずっと楽だ

  • 個人プロジェクトとしてSshifuというツールを作っている
    SSH 証明書ベースのログインとSSOを簡単にするツールだ
    サーバーに sshifu-server をインストールして CA として使い、各 SSH サーバーはこの CA を信頼するよう設定する
    ユーザーは npx sshifu コマンドでログインすれば終わりだ
    GitHub リポジトリを参照してほしい

  • 実運用環境では証明書ベースのアクセスが複雑な運用管理の問題につながる
    証明書の期限切れ、ユーザー削除、サーバー障害時のログインなど、さまざまな問題が発生する
    Userify では 15 年にわたりこうした問題を扱ってきたが、安定した SSH 認証基盤を作るのは決して簡単ではない

    • ただし SaaS 方式は最悪の選択だと思う
  • pico.sh に SSH 証明書サポートを追加したが、RBAC スタイルのアクセス制御を実装できて非常に便利だった
    ドキュメントリンクを参照

  • プロダクションでは SSH 証明書がむしろ複雑さを中央集権化して問題を大きくする
    単一の CA が常時利用可能でなければならず、障害時には全体のアクセスが止まる
    TTL の調整、信頼ルートの管理、デバッグの難しさなど、現実的な問題も多い
    結局、人々はキャッシュやエージェントを再導入する
    私たちは逆に、各ノードが HTTPS でユーザー情報をローカルの authorized_keysに同期するようにしている
    こうすれば中央制御は維持しつつ、障害は局所化される
    Userify ではこの方式を採用しており、認証だけでなく権限管理まで扱う
    証明書だけではユーザー作成、sudo ロール、ホームディレクトリの整理といった問題は解決できない

    • TOFU はどう解決するのか、という質問を受けた