ひとことで言うと
SSH鍵とは、秘密のプライベートなファイルと、共有可能なパブリックなファイルからなる、対になった暗号化ファイルのこと。これを使えば、パスワードを入力することなく、リモートコンピュータに自分の身元を証明できるんです。
解決する問題
インターネットの黎明期、リモートサーバーを管理したいと思ったら、Telnetのようなものを使っていました。ユーザー名とパスワードを入力すると、それらがネットワーク上を平文(プレーンテキスト)で飛び交い、誰にでも見られてしまう状態でした。これはまるで、混雑した部屋で銀行の暗証番号を大声で叫ぶようなもの。ヤバいですよね。
そこに登場したのが、Secure Shell、SSHです。SSHは通信全体を暗号化し、これは画期的な進歩でした。パスワードを入力しても、サーバーに届くまでの間にごちゃ混ぜにスクランブルされるようになったのです。かなりマシになりました!しかし、パスワードにはまだ問題があります。脆弱だったり、忘れたり、推測されたり、ブルートフォース攻撃を受けたりする可能性があります。何十台ものサーバーのパスワードを開発チーム全体で管理するのは、セキュリティ的にも運用的にも悪夢です。誰が何にアクセスできるのか?誰かが会社を辞めたらどうするのか?50台のサーバーのパスワードを変更して、全員に新しいパスワードを伝えるのでしょうか?
これこそが、SSH鍵が解決するために設計された問題です。SSH鍵は、「知っているもの」(パスワード)を「持っているもの」(秘密鍵)に置き換えます。この公開鍵認証と呼ばれる方法は、人間にとっても自動化システムにとっても、劇的に安全で、はるかに便利なのです。これは、簡単に盗まれてしまう1本のマスターキーを持つことと、開ける必要のあるドアごとに生体認証でロックされたユニークなキーカードを持つことの違いのようなものです。
内部の仕組み
SSH鍵の背後にある魔法は、非対称暗号と呼ばれる概念です。単純なパスワード(あなたとサーバーの両方が同じものを知っている対称的な秘密)とは異なり、SSH鍵ペアは、2つの別々でありながら数学的に関連付けられた鍵で構成されます。
公開鍵と秘密鍵のペア:一方通行なラブストーリー
魔法の南京錠と、それに合うユニークな鍵を1本だけ持っていると想像してみてください。この南京錠があなたの公開鍵です。この南京錠のコピーを100万個作って、誰にでも渡すことができます。ウェブサイトに掲載したり、友人にメールしたり、アクセスしたいすべてのサーバーに置いたりできます。これは公開されているものなので、外部に漏れても害はありません。
あなたの秘密鍵は、その特定のブランドの南京錠を開けることができる唯一無二の鍵です。あなたはこの鍵を命がけで守ります。自分のコンピュータに保管し、決して誰とも共有せず、理想的にはパスフレーズで保護します。
- 秘密鍵は、デジタルの署名を作成できます。
- 公開鍵は、その署名が対応する秘密鍵によって作成されたことを検証できます。
重要なのは、公開鍵を使って秘密鍵を割り出すことはできないということです。この数学的な関係は一方向にしか機能しないため、「非対称」と呼ばれます。
認証のハンドシェイク
では、ログインしようとすると、これはどのように機能するのでしょうか?あなたが ssh user@server.com とタイプしたとしましょう。
- 自己紹介: あなたのコンピュータ(クライアント)がサーバーのドアをノックします。「こんにちは、
userとしてログインしたいです。私の公開鍵はご存知のはずです。これがそのIDです。」 - チャレンジ: サーバーは
userの~/.ssh/authorized_keysファイルを調べます。このファイルは、そのユーザーとしてログインを許可された公開鍵のリストです。サーバーは一致する公開鍵を見つけます。「ああ、あなたの公開の南京錠ですね!信じますが、証明が必要です。秘密鍵を持っていることを証明するために、私がたった今作ったこのランダムな一度きりのメッセージに署名してください:R2-D2_is_the_true_hero。」 - 署名: あなたのクライアントがチャレンジを受け取ります。そして、あなたの秘密鍵を使って、その特定のメッセージに対するユニークなデジタル署名を作成します。その後、この署名をサーバーに送り返します。あなたの秘密鍵自体は、決して、絶対にあなたのコンピュータから離れることはありません。
- 検証: サーバーは署名を受け取ります。そして、手元にある公開鍵を使って、元のチャレンジメッセージと照らし合わせて署名を検証します。その特定のメッセージに対してその署名を作成できたのはあなたの秘密鍵だけなので、サーバーはあなたと話していることを確信します。
- アクセス許可: 計算が合いました。サーバーは「署名は有効です。どうぞお入りください!」と言って、シェルセッションを許可します。この間、パスワードがネットワークを通過することは一切ありません。
鍵の種類:一家の肖像(RSA、ECDSA、Ed25519)
すべての鍵が同じように作られているわけではありません。鍵ペアと署名を生成するために、異なる数学的アルゴリズムを使用しています。一般的に見られるのは、主に3つのタイプです。
| アルゴリズム | 要するに | 鍵長(典型的) | 評価 |
|---|---|---|---|
| RSA | 古株。巨大な素数の因数分解の難しさに基づく。 | 2048 or 4096ビット | 今でも強力で広くサポートされているが、現代の基準では低速で大きな鍵が必要。 |
| ECDSA | 現代の標準。楕円曲線暗号を用いて、より小さく、より高速に。 | 256 or 384ビット | 素晴らしい選択肢。256ビットのECDSA鍵は3072ビットのRSA鍵と同等のセキュリティを提供。 |
| Ed25519 | 今一番イケてるやつ。さらに高速な特定の種類の楕円曲線鍵。 | 256ビット | サポートされていれば最良の選択肢。高速、安全で、特定の攻撃に耐性があるように設計。 |
今日では、その優れたパフォーマンスとセキュリティから、一般的にEd25519が推奨される選択肢です。
フィンガープリントって何?
公開鍵は、長くて醜い文字列です。簡単に覚えたり比較したりできるものではありません。フィンガープリントは、公開鍵をハッシュ関数(SHA256など)に通して作成された、短くてユニークな要約です。
SHA256:88+EM65U024w0E7sF2w8w3n98w/L3t8d7f6e5g4h
これは人間が読めるシリアル番号のように機能します。初めてサーバーに接続するとき、SSHはサーバーの公開鍵のフィンガープリントを表示し、それを信頼するかどうか尋ねてきます。これは、そのフィンガープリントを他の安全なチャネル(例えば、システム管理者に電話して読み上げてもらうなど)で確認することで、「中間者攻撃」を防ぐ唯一のチャンスです。
実社会でのストーリー
自動デプロイスクリプト
DevOpsエンジニアのMayaは、20台のWebサーバー群を管理していました。会社のアプリの新しいバージョンをデプロイするたびに、彼女のスクリプトは各サーバーにログインして最新のコードを取得し、サービスを再起動する必要がありました。最初のスクリプトでは、サーバーのパスワードを20回連続で要求され、気が狂うほど時間がかかりました。次のバージョンでは、スクリプトにパスワードをハードコーディングしましたが、これはCISO(最高情報セキュリティ責任者)の目をひきつらせるものでした。最終的に、彼女はデプロイ専用のSSH鍵ペアを1つ生成しました。彼女はその公開鍵を20台すべてのサーバーに追加しました。今では、彼女のスクリプトは完璧かつ安全に実行され、手動の介入なしに数秒ですべてのマシンにログインします。
教訓: SSH鍵は、安全なパスワードレス自動化の礎です。
契約終了した業務委託者
ある小さなスタートアップが、3ヶ月のプロジェクトのためにフリーランサーのDavidを雇いました。彼にステージングサーバーへのアクセス権を与えるため、テックリードのChenはDavidの公開SSH鍵を教えてもらい、サーバーの authorized_keys ファイルに追加しました。これでDavidは安全にログインして作業ができるようになりました。契約終了時、Chenのサーバーアクセスに関する「オフボーディング」プロセスは、authorized_keys ファイルを開き、Davidの鍵が含まれる行を削除するという、たった一つのコマンドで完了しました。共有パスワードを変更したり心配したりすることなく、アクセスは即座にかつクリーンに取り消されました。
教訓: SSH鍵は、ユーザーごとに、きめ細かく、監査可能で、簡単に取り消しできるアクセス制御を提供します。
最初のGitHubプッシュ
新しい開発者のSamがチームに参加し、プライベートなコードリポジトリをクローンしました。最初の変更を加えた後、彼は git push を試みました。しかし、「Permission denied」エラーに遭遇しました。多くの企業と同様に、彼の会社もセキュリティ上の理由からGitHubへのパスワードベースの認証を無効にしていたのです。社内Wikiには、新しいSSH鍵を生成し、GitHubの設定に移動して、公開鍵(id_ed25519.pub)の内容を「SSH and GPG keys」セクションに貼り付けるように指示されていました。その後、彼はリポジトリのSSH URL(git@github.com:...)を使ってコードをプッシュできるようになりました。GitHubは、コードをプッシュしているのが本当にSamであることを確認するために、まったく同じチャレンジレスポンスメカニズムを使用していました。
教訓: SSH鍵は、シェルアクセスだけでなく、ほとんどのコードホスティングプラットフォームを含むサービスへの認証の標準です。
よくある間違いと落とし穴
- 秘密鍵を共有してしまう。 絶対に、絶対に、絶対に、あなたの秘密鍵(
id_ed25519やid_rsa)を誰かに送ったり、どこかにアップロードしたりしないでください。それはあなたの秘密です。それを共有すると、このセキュリティモデルの目的が完全に損なわれます。 - パスフレーズを忘れる。 あなたの秘密鍵はディスク上のただのファイルです。もしあなたのラップトップが盗まれたら、攻撃者はそれをコピーするだけです。強力なパスフレーズはこのファイルを暗号化し、泥棒があなたのラップトップのパスワードとあなたの鍵のパスフレーズの両方を解読する必要があるようにします。これは重要な防御層です。
- 公開鍵のフィールドに秘密鍵を貼り付けてしまう。 やってしまいがちな間違いです。新しいサービスを設定していて、公開鍵を求められ、間違ったファイルの内容を誤ってコピー&ペーストしてしまうことがあります。共有している鍵が
.pubで終わっていることを常に再確認してください。 - 弱くて古い鍵を使う。 今の時代に1024ビットのRSA鍵を生成するのは悪い考えです。資金力のある攻撃者によって解読される可能性があります。モダンなデフォルトに固執しましょう:Ed25519か、少なくとも4096ビットのRSA鍵を使いましょう。
- 何も考えずに「yes」とタイプする。 新しいホストに初めて接続するとき、SSHはそのホストの信頼性が確立できないと警告し、そのフィンガープリントを表示します。ただ盲目的に受け入れないでください。これは中間者攻撃が起こりうる瞬間です。信頼できないネットワークにいる場合は、別のチャネルを通じてフィンガープリントを確認してください。
なぜ注目すべきか
もしあなたが開発者、システム管理者、DevOpsエンジニア、あるいはリモートコンピュータにログインする必要がある人なら誰でも、SSH鍵は単なる「あったらいいな」ではなく、基本的な必須知識です。それらは、マシンへのアクセスを管理するためのプロフェッショナルで、安全で、効率的な方法なのです。
以下のようなときにSSH鍵について考えるべきです:
- 新しいサーバー(クラウドまたはオンプレミス)をセットアップするとき。
- 別のマシンに接続する必要があるスクリプト(
scp,sftp,rsync,git)を書くとき。 - 新しいチームメンバーのアクセスを設定するとき。
- GitHub、GitLab、またはBitbucketに接続するとき。
- パスワードの入力をやめたいとき。
SSH鍵の使い方を学ぶことは、リモートマシンの単なるユーザーから、使いこなせるオペレーターへとステップアップするための通過儀礼です。
さらに深く
- RFC 4251: The Secure Shell (SSH) Protocol Architecture - コアとなるSSHプロトコルの公式IETF仕様書です。
- Wikipedia: Secure Shell (SSH) - SSHの歴史、アーキテクチャ、用途を網羅的に概観できます。
- GitHub Docs: Connecting to GitHub with SSH - SSH鍵認証の最大手ユーザーの一つであるGitHubによる、実践的で現実的なガイドです。
- OpenSSH Project Page - 最も普及しているSSH実装のホームページです。
- RFC 8032: Edwards-Curve Digital Signature Algorithm (EdDSA) - モダンなEd25519およびEd448アルゴリズムの仕様書です。
- SSH.com: SSH Keys - SSHの商用利用を推進する企業の一つによる詳細な解説です。