SSH
Secure Shell ・ えすえすえいち
暗号化と相互の認証を備えた遠隔操作の通信路。サーバ運用とGit操作の足回り。
✦ 30秒で試す — 航海1995年、大学のパスワード盗聴事件から生まれたログインのとき、秘密鍵はどう扱われる?予想してみる概要
SSH(Secure Shell)は、ネットワーク越しに別のコンピュータを安全に操作するためのプロトコルです。ssh user@example.com と打てば、暗号化された通信路の先に相手マシンのシェルが開き、目の前の端末と同じようにコマンドを実行できます。サーバにログインして設定を変える、ログを調べる、ファイルを転送する — サーバ運用の日常作業のほとんどが SSH の上で行われています。
SSH が保証するのは「盗み見られない」ことだけではありません。接続のたびに、相手のサーバが本物かどうか(ホスト認証)と、ログインしようとしているのが誰か(ユーザの認証)を確かめます。この「認証済みの暗号化チャネル」を土台に、ファイル転送の scp/SFTP、Git の push/pull、後述するポートフォワーディングによる任意の通信の中継まで、SSH は多目的のトンネルとして使われています。GitHub に公開鍵を登録する、デプロイ先のサーバに鍵でログインする、といった操作は開発者の通過儀礼と言ってよいでしょう。
標準では TCP の22番ポート番号で待ち受けます。インターネットに開いた22番には世界中から不正ログインの試行が絶え間なく届くため、SSH の設定はサーバのセキュリティの最初の関門でもあります。
なぜ生まれたか
SSH 以前、遠隔操作には telnet、ファイル転送には FTP、UNIX 同士の遠隔実行には rsh/rlogin が使われていました。これらに共通する致命的な問題は、パスワードを含むすべての通信が平文で流れることです。同じネットワークにいる誰かがパケットを覗けば、ログインパスワードがそのまま読めてしまいます。rsh に至っては「接続元のホスト名が信頼リストにあればパスワードなしで入れる」という仕組みで、送信元を偽れば誰でも入れました。顔の見える学術ネットワークの時代には許されていたこの前提は、インターネットの商用化とともに崩れました。
きっかけは1995年、フィンランドのヘルシンキ工科大学で起きたパスワード盗聴事件です。大学のネットワークに仕掛けられたスニファ(盗聴プログラム)で大量のパスワードが盗まれたことを受けて、同大学の Tatu Ylönen が「telnet と rsh をそのまま置き換えられる、暗号化された遠隔操作ツール」として SSH を開発・公開しました。使い勝手を変えずに通信だけを安全にした SSH は爆発的に広まり、のちにプロトコルを設計し直した SSH-2 が IETF で標準化され(2006年の RFC 4251〜4254)、OpenBSD の開発者たちによるフリーの実装 OpenSSH が事実上の標準になりました。いまでは telnet によるサーバ管理は「やってはいけないこと」の代名詞です。
詳細
三つの層 — 暗号化、ユーザ認証、チャネル
SSH-2 は3つの層でできています。いちばん下の「トランスポート層」が、接続直後の鍵交換で通信路全体を暗号化し、同時にサーバのホスト鍵でサーバの正体を確かめます。その上の「ユーザ認証層」が、暗号化された通信路の中でユーザの認証を行います。いちばん上の「コネクション層」は、1本の SSH 接続の中に複数の「チャネル」を多重化します。シェルのセッションも、ファイル転送も、ポートフォワーディングも、このチャネルの1本として運ばれます。
接続の流れを時間の順に追うと、次のようになります。TLS と似た構図ですが、TLS が認証局の証明書でサーバを確かめるのに対し、SSH は認証局を前提とせず、手元の known_hosts との照合を使う点が対照的です。
公開鍵認証 — 秘密がネットワークを流れない
ユーザ認証の方式で最も重要なのが公開鍵認証です。パスワード認証では、暗号化された通信路の中とはいえパスワードそのものがサーバに届きます。公開鍵認証では、秘密の情報は一切ネットワークを流れません。公開鍵暗号の鍵ペアを作り、公開鍵をあらかじめサーバの authorized_keys に登録しておくと、クライアントは「この接続に固有のデータ(鍵交換で決まったセッションの識別子を含む)」に秘密鍵で署名して送り、サーバは登録済みの公開鍵でその署名を検証します。
署名は接続ごとに違うデータに対して作られるので、盗み見た署名を別の接続で使い回すことはできません。秘密鍵は手元のマシンから出ていかないので、偽のサーバに接続してしまっても秘密鍵そのものは漏れません。総当たりも事実上不可能なため、実務ではパスワード認証を無効にして公開鍵認証だけに絞るのが定石です。鍵の種類はいまは Ed25519 が標準的で、秘密鍵はパスフレーズで暗号化して保管し、ssh-agent に一度だけ読み込ませて使い回すのが典型的な運用です。
known_hosts — 相手は本物か
初めてのサーバに接続すると「このホストの真正性は確認できません。続行しますか?」と聞かれます。これがホスト認証の入口で、サーバが名乗ったホスト鍵の指紋を利用者が確かめて承認すると、known_hosts ファイルに記録されます。次回からは記録と自動で照合され、鍵が変わっていれば大きな警告が出ます。サーバを作り直して鍵が変わっただけのこともありますが、偽のサーバへ誘導する中間者攻撃の兆候かもしれません。「いつもの WARNING だから」と known_hosts の該当行を機械的に消すのは、SSH の安全性の片翼を自分で外す行為です。
最初の1回だけは検証が利用者任せになる(Trust On First Use と呼ばれる割り切り)のがこのモデルの弱点で、厳格な組織では指紋の事前配布や、認証局がホスト鍵に署名する SSH 証明書でこれを補います。
ポートフォワーディング — 暗号化チャネルの転用
SSH の応用範囲を大きく広げているのがポートフォワーディングです。確立済みの SSH 接続をトンネルとして、別の通信を相手側へ運ぶ機能で、いわば1本の SSH を簡易的な VPN として使う仕組みです。
代表はローカルフォワーディングです。ssh -L 15432:db.internal:5432 bastion と実行すると、手元の 15432 番ポートへの接続が、踏み台サーバ bastion を経由して社内のデータベース(RDBMS)サーバの 5432 番へ転送されます。ファイアウォールの内側にある DB に、手元のツールから localhost:15432 としてつなげるわけです。逆向きのリモートフォワーディング(-R)は、サーバ側のポートへの接続を手元に引き込むもので、開発中の Web アプリを一時的に外へ見せるといった用途に使われます。踏み台を経由して目的のサーバへ直接つなぐ ProxyJump(多段 SSH)も、クラウド時代のサーバ運用では日常の道具です。
便利な機能ですが、ポートフォワーディングはファイアウォールの穴を利用者が自分で開けるのと同じ効果を持ちます。SSH で入れる人なら誰でも、内側のあらゆるサーバへの道を作れてしまうため、踏み台では AllowTcpForwarding で転送を制限することもあります。ssh-agent の転送(-A)も、踏み台の管理者権限を持つ人に手元の鍵を使わせる窓口になるので、多段接続には ProxyJump を使うのが安全です。
運用の落とし穴
SSH は強力なぶん、雑に扱うと事故の温床になります。定番の失敗は、パスフレーズなしの秘密鍵をリポジトリやチャットにうっかり置いてしまうことです。公開リポジトリに載った鍵は数分で自動収集されると考えたほうがよく、秘密鍵やトークンを置き場所ごと管理するシークレット管理の対象として扱います。退職者や不要になった公開鍵が authorized_keys に残り続けること、root での直接ログインを許したままにすることも典型です。秘密鍵は「サーバへの入館証そのもの」で、漏れたら対応する公開鍵をすべてのサーバから即座に撤去する必要があります。誰の鍵がどこに登録されているかの棚卸しは地味ですが、最小権限を保つうえで欠かせません。
この鍵管理の負担を減らすため、有効期限付きの SSH 証明書を必要なときだけ短時間発行する方式や、IdP での認証と連動させるアクセス基盤への移行も進んでいます。22番をファイアウォールで社内や踏み台からだけに絞り、ログイン試行を監視するのも基本です。暗号の側も更新が続いていて、OpenSSH は将来の量子計算機による解読に備えた鍵交換を既定にしています。それでもなお、1台のサーバと1人のエンジニアを最短距離でつなぐ道具として、SSH はインフラ作業の共通言語であり続けています。
試問
手元の PC から SSH でサーバへログインする場面です。通信路は接続の最初に暗号化され、そのあとでユーザの認証をします。認証の方法は、登録済みの公開鍵と手元の秘密鍵を使う公開鍵認証か、パスワードを入力するパスワード認証です。
SSH でログインするときに関わる6つの情報を、ネットワークを通ってサーバに届くものと、手元のPCから一度も出ないものに仕分けよ
項目を選んでから、入れる箱を選びます
