SSD Nodes Learn 🎉 VPS $5.50/月〜
ガイド Matt Connor著者 Matt Connor

SSHの歴史:telnetからOpenSSHまで

1995年、ヘルシンキでのパスワード盗聴攻撃をきっかけにSSHが誕生しました。telnetとrloginからOpenSSH、ポスト量子暗号のデフォルトまで、検証済みの流れを解説します。

SSH の歴史の始まり

SSH の歴史は、盗まれたパスワードから始まります。1995 年以前、リモートの Unix マシンにログインするには telnet または rlogin を使うのが一般的でした。どちらもパスワードを読み取り可能なテキストとしてネットワーク上に送信していました。ネットワークトラフィックを監視できる人なら、パスワードを読み取れました。1990 年代初頭までには、実際に大規模な監視が行われていました。

SSH は、この問題に対する 1 人の回答として 1995 年に作成され、無償で公開されました。その後、プロトコルは 1 度再構築され、現在ほとんどの人が使用しているプログラムは、フォークからさらにフォークされたものです。以下の日付は重要です。各段階は、特定の障害への対応として生まれたためです。

Telnet と rlogin が実際に送信した内容

Telnet は、Jon Postel と Joyce Reynolds が 1983 年 5 月に公開した RFC 854 で定義されています。TCP で運ぶ端末セッションについて規定していますが、暗号化機能は一切ありません。入力したすべてのバイトは、パスワードも含めて、経路上のあらゆる機器が読み取れる平文のまま送信されます。

rlogin は Berkeley Unix から生まれ、後に RFC 1282(BSD Rlogin、B. Kantor、1991 年 12 月)で文書化されました。読み取り可能なパスワードよりも危険な機能として、ホストベースの信頼を追加しました。サーバーに対して、指定したホストからのログインをパスワードなしで受け入れるよう設定できました。この RFC には「A Cautionary Tale」という節があり、「信頼されたホストからのパスワード認証を迂回すると、1 台が侵害された時点で、そのように設定されたすべてのシステムが危険にさらされる」と記載されています。また、この信頼関係はホスト名を基準にするため、DNS(domain name system)の侵害や偽装アドレスによって破られることも説明しています。

どちらの設計も、当時のネットワークには適していました。初期の Ethernet は共有媒体でした。セグメント上のすべてのマシンがすべてのフレームを受信し、自分宛てでないフレームを無視する仕組みでした。フレームを無視しなくなる promiscuous mode に設定したマシンは、他のマシンの通信をすべて確認できました。さらに、大学が数千人の学生に shell アカウントを提供していたため、1 つの侵害されたアカウントが、学部全体のパスワード収集に使われる可能性がありました。

修正なしで公開された1994年の勧告

1994年2月3日、CERTは勧告CA-94:01「継続的なネットワーク監視攻撃」を公開しました。この勧告は、侵入者がインターネット上の数万台のシステムについて、アクセス情報を取得していたと報告しています。侵入者が使用したツールは、ネットワークインターフェースをプロミスキャスモードに設定し、新しいtelnet、rlogin、FTPセッションが開始されるたびに、その冒頭部分を記録していました。そこにはユーザー名とパスワードが含まれます。

CERTは、ネットワーク経由でアクセスするすべてのアカウントのパスワードを変更するようサイトに勧告しました。これをプロトコルの仕様と照らし合わせると、問題は明らかです。新しいパスワードを初めて使用したとき、そのパスワードも同じ通信経路を平文で通過します。telnetにもrloginにも修正を組み込む余地はありませんでした。どちらのプロトコルにも、そのための仕組みが存在しなかったためです。

ヘルシンキでの盗聴攻撃から SSH が生まれた理由

1995 年、ヘルシンキ工科大学のネットワークが、CERT が説明していた種類のパスワード盗聴攻撃を受けました。同大学の研究者だった Tatu Ylönen は代替ソフトウェアを作成し、1995 年 7 月にフリーウェアとして公開しました。彼はそれを Secure Shell と名付けました。

このソフトウェアを支えた設計上の決定は 2 つありました。セッションを暗号化したため、ネットワークセグメント上で通信を監視しても有用な情報は得られませんでした。また、サーバーが暗号鍵で自身の身元を証明したため、クライアントは正しいマシンに接続したかどうかを確認できました。これは、rlogin がホスト名を信頼していたことで残されていた問題でした。

さらに、既存のコマンドと同じコマンドを使えたことも普及につながりました。sshrshrlogin の代わりになり、scprcp の代わりになりました。切り替えに必要だったのは習慣の変更であり、ワークフローの変更ではありませんでした。1995 年末までに、ユーザーベースは 50 か国で約 20,000 ユーザーに達しました。同年 12 月、Ylönen はソフトウェアの開発と販売を目的として SSH Communications Security を設立しました。

無償リリースから商用製品へ

SSH が事業化されると、ソースコードのライセンスが変更されました。その後のリリースには、他者がコードでできることを制限する条項が含まれ、誰でも自由に再利用できた最後のリリースは ssh 1.2.12 でした。これは不適切なことではありません。単に、世界中の人々が基盤として利用できる SSH のバージョンの更新が止まり、その一方で開発は世界中の人々が追随できない場所で続いたということです。どのコードが残るかはライセンスによって決まります。このパターンについては、オープンソースライセンスが現代のインフラストラクチャを形作った経緯で詳しく確認できます。

OpenBSD が 1999 年に OpenSSH をフォークした理由

1999 年の初め、Björn Grönvall はその最後のフリーリリースに戻り、バグの修正を始めました。彼のバージョンは OSSH と呼ばれ、SSH 1.3 プロトコルだけを話しました。

OpenBSD プロジェクトは OSSH を引き継ぎ、再構築しました。プロジェクト自身の説明によると、Theo de Raadt、Niels Provos、Markus Friedl、Bob Beck、Aaron Campbell、Dug Song がコードの整理、監査、拡張を行いました。その成果が OpenSSH 1.2.2 であり、1999 年 12 月 1 日に OpenBSD 2.6 とともにリリースされました。

なぜ、1 つの小規模なオペレーティングシステムプロジェクトによるフォークが、ほぼすべてのマシンで使われるようになったのでしょうか。理由は、OpenBSD が OpenSSH に必要としていたものにあります。OpenBSD は、デフォルト設定で安全に動作することを目指して監査済みのベースシステムを提供しています。そのため、暗号化されたリモートログイン機能も、そのベースシステムに、制限のないライセンスで含める必要がありました。制限のないライセンスで提供される監査済みコードは、他のすべてのオペレーティングシステムベンダーも求めていたものです。Damien Miller、Philip Hands らはほぼすぐに移植版のブランチを開始しました。バージョンの 10.5p1 に含まれる p は、そこに由来します。OpenBSD はクリーンなバージョンを開発し、移植版のブランチが他の環境に必要な接続部分を追加します。現在使われているシステムへ Unix が分かれていった経緯があるため、この接続部分が必要になります。

続いて、2 番目のプロトコルバージョンにも対応しました。OpenSSH 2.0 は、2000 年 6 月 15 日に OpenBSD 2.7 とともにリリースされました。

SSH-2 がバージョンアップではなく新しいプロトコルである理由

SSH-1 は、暗号化ストリームの完全性保護に CRC-32 を使用していました。CRC-32 は、攻撃者への耐性ではなく、通信エラーの検出を目的としたチェックサムです。1998 年、CORE SDI の Ariel Futoransky と Emiliano Kargieman は、その問題がもたらす影響を示しました。CBC または CFB の暗号モードと CRC-32 の組み合わせでは、攻撃者は平文を 16 バイト程度知っているだけで、受信側が正規のものとして受け入れる選択暗号文を挿入できました。これは、サーバー上でコマンドを実行できることを意味します。

この欠陥はプロトコルそのものに存在していたため、互換性を壊さずに修正することはできませんでした。その代わりに、実装には検出機能が追加されました。これは deattack.c というファイルに収められ、攻撃の発生時に検出を試みるコードでした。2001 年 2 月、この検出機能自体に整数オーバーフローがあることが判明しました。CVE-2001-0144 により、修正を適用したサーバーとクライアントに対してリモートコード実行が可能になりました。修復できない設計にはパッチが蓄積し、そのパッチ自体が新たなバグをもたらします。

SSH-2 は secsh という IETF ワーキンググループで策定され、2006 年 1 月に RFC として公開されました。アーキテクチャは RFC 4251、トランスポート層は RFC 4253、ユーザー認証は RFC 4252、接続層は RFC 4254 で規定されています。層に分割したことが重要です。これにより、各層を個別に置き換えられるためです。この後の歴史の大部分は、その置き換えが進んだ過程です。

特に重要な変更は 2 つあります。完全性保護は CRC-32 から、共有秘密を鍵として使用する HMAC(ハッシュベースメッセージ認証コード)へ移行しました。これにより、MAC を計算できない攻撃者はパケットを偽造できません。また、鍵合意は Diffie-Hellman に移行しました。SSH-1 では、クライアントがセッション鍵を選び、サーバーの RSA 鍵で暗号化して送信していました。そのため、後からサーバーの秘密鍵を入手した者は、記録済みのセッションを復号できました。Diffie-Hellman はセッションごとに新しい秘密を導出します。この秘密が送信されることはありません。そのため、現在の通信を記録し、後からホスト鍵を盗んでも、得られる情報はありません。この性質を前方秘匿性と呼びます。

SSH-2 は SSH-1 とのワイヤ互換性を持ちません。そのため、10 進数のバージョン番号を増やすのではなく、番号自体が変わりました。

SSH-1 が修復ではなく削除された理由

削除には 3 つの OpenSSH リリース がかかりました。Version 7.0 では、2015 年 8 月 11 日に、コンパイル時のデフォルト設定で protocol 1 を無効にしました。Version 7.4 では、2016 年 12 月 19 日に、protocol 1 のサーバーサポートを削除しました。Version 7.6 では、2017 年 10 月 3 日に、設定オプションとドキュメントも含めてクライアント側も削除しました。

古い機器向けのオプションとして残すほうが、利用者にとって親切だったでしょう。しかし、CRC-32 検出器の問題が、その選択が拒否された理由を示しています。このオーバーフローに到達できたのは、protocol 1 のコードがコンパイルに含まれていたためです。また、そのコードは、多くの管理者が自分のシステムでは休止していると考えていた処理経路に存在していました。リリースされたコードには到達される可能性があります。削除されたコードには到達できません。

最初の SSH 接続で host key の警告が表示される理由

暗号化により、通信が非公開であることは保証されます。しかし、接続相手が誰かまでは保証されません。攻撃者が通信経路に入り、サーバーになりすまして応答すると、攻撃者との通信が完全に暗号化された状態になります。これは machine-in-the-middle 攻撃です。SSH は host key でこれに対処します。サーバーは、key pair の秘密鍵を保持していることを証明します。クライアントは、その key を前回記録した値と照合します。接続自体の仕組みについては、SSH 接続を開くときに何が起きるかを参照してください。

初回接続には前回がありません。そのため、クライアントには比較対象がなく、次のように確認を求めます。

The authenticity of host 'vps.example.com (203.0.113.10)' can't be established.
ED25519 key fingerprint is SHA256:BQ0Qs2jVXhH2lPZ2rM0aQ0mQ8f9pQ0m3nH0oQ1bYqkE.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

yes と答えると、その key が ~/.ssh/known_hosts に保存されます。以後の接続では、保存された値と比較されます。不一致があると、プログラムで最も強い警告が表示されます。

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!

この最初の確認メッセージは、プロトコルに弱点が1つあることを正直に示しています。初回接続時の信頼、つまり trust on first use は、その接続に使用したネットワークの安全性に依存します。この問題は解消できます。接続前に、プロバイダーのコンソールまたはサーバーの build log で fingerprint を確認してください。DNS に SSHFP record (RFC 4255) として公開する方法もあります。ただし、この方法を使うには DNSSEC が必要です。独自の certificate authority (CA) で host key に署名し、個々の key ではなく CA をクライアントに信頼させる方法もあります。実際には、確認せずにこのメッセージを受け入れる人が大半です。この点は正直に認識しておくべきです。

公開鍵がパスワードに取って代わった理由

公開鍵認証は初期の SSH リリースから存在していましたが、一般的な運用方法になるまでにはなお数年かかりました。この仕組みは非対称です。クライアントはチャレンジに署名し、秘密鍵を保持していることを証明します。秘密鍵がクライアントの外へ出ることはありません。パスワードは逆です。SSH はパスワードを暗号化されたチャネル内で送信しますが、サーバーは実際の秘密情報を受け取ります。そのため、侵害されたサーバーや悪意のあるサーバーが、別の場所であなたになりすますために再利用できる情報を保持することになります。

2 つ目の理由は、計算上の違いです。公開アドレスで port 22 を開いているサーバーには、常に自動化されたログイン試行が届きます。パスワードは推測可能な文字列です。一方、鍵は現実的な範囲では推測できません。PasswordAuthentication no を設定すると、この種の攻撃を根本から防げます。そのため、あらゆるセキュリティ強化チェックリストに登場します。鍵の生成とローテーションについては SSH 鍵管理の基本 で、サーバー側の設定については VPS の SSH を強化する で説明しています。

SSH のアルゴリズム一覧が変わり続ける理由

階層化されたプロトコルでは、新しいプロトコルを作らなくてもアルゴリズムを廃止できます。OpenSSH はこの仕組みを継続的に利用しており、リリース日からその進行速度が分かります。

Ed25519 は、chacha20-poly1305 cipher と bcrypt で保護された private key format とともに、30 January 2014 の OpenSSH 6.5 で導入されました。Ed25519 signature は署名ごとの nonce を決定論的に生成するため、署名時の乱数生成器が弱くても private key が漏えいしません。これは、実際のインシデントで DSA と ECDSA の private key が復元された原因そのものです。

DSA は反対の経過をたどりました。OpenSSH 7.0 は 2015 年に、ssh-dss host key と user key を実行時に無効化しました。このアルゴリズムは 160-bit の private key と SHA-1 に制限されているためです。Version 9.8 は 1 July 2024 に DSA をコンパイル時に無効化しました。Version 10.0 は 9 April 2025 に DSA を削除しました。プロジェクトの説明では、「2015 年に始まった非推奨化プロセスを完了」したことになります。無効化から削除まで 10 年かかりました。

RSA 自体は消えませんでしたが、古い signature format は廃止されました。OpenSSH 8.8 は 26 September 2021 に、SHA-1 で作成された RSA signature をデフォルトで受け付けなくなりました。release notes には理由が明確に記載されています。SHA-1 は暗号学的に破られており、chosen-prefix collision は USD 50,000 未満で実現可能だったためです。古い server への接続時に sign_and_send_pubkey: no mutual signature supported を見たことがあるなら、それがこの変更です。あなたの key に問題はありません。相手側が要求した signature algorithm に問題があります。

同じプロセスは現在、脅威が現れる前に key exchange にも適用されています。現在取得された network traffic は、将来、十分な性能を持つ quantum computer を最初に所有した者によって保存され、復号される可能性があります。そのため、そのような machine が存在する前に key agreement を変更する必要がありました。OpenSSH 9.0 は 8 April 2022 に hybrid key exchange をデフォルトにしました。sntrup761x25519-sha512@openssh.com は post-quantum algorithm と X25519 exchange を組み合わせます。そのため、新しい algorithm に問題があっても、結果が classical part より弱くなることはありません。OpenSSH 9.9 は 19 September 2024 に mlkem768x25519-sha256 を追加しました。これは NIST が 2024 年に標準化した ML-KEM (module lattice key encapsulation mechanism) を基盤としています。OpenSSH 10.0 はこれを key agreement のデフォルトにしました。プロジェクトの post-quantum ページで、その理由を説明しています。OpenSSH 10.1 は 6 October 2025 に、相手側がこれに対応していない場合の警告を開始しました。

** WARNING: connection is not using a post-quantum key exchange algorithm.
** This session may be vulnerable to "store now, decrypt later" attacks.
** The server may need to be upgraded.

この警告はデフォルトで有効で、ssh_configWarnWeakCrypto option で制御します。実際の動作と、この警告を出す server への対処方法については、post-quantum SSH key exchange のデフォルト設定で説明します。

目の前のサーバーにとって、この履歴が意味すること

入力するコマンドは、1995 年以降ほとんど変わっていません。その下にあるものは、ほぼすべて置き換えられています。整合性チェック、鍵交換、署名アルゴリズム、コードベースそのものも対象です。それが可能だったのは、各置き換えが意図的な削除で終わり、その削除によって誰かの環境で問題が発生したからです。

そのため、SSH のセキュリティは主にバージョンで決まります。デフォルト設定には、どのアルゴリズムを提示し、どれを拒否し、どの警告を表示するかという判断が組み込まれています。古いサーバーは、そのリリースでまだ許可されているアルゴリズムを提示し続け、古いクライアントに合わせて古い方式までネゴシエーションを下げ続けます。2026 年 8 月時点の最新リリースは OpenSSH 10.5 で、2026 年 8 月 11 日に公開されました。これと、3 年間誰も変更していないマシンのバージョンとの差が、問題の大きさを示します。新しい VPS で最初の 10 分以内に確認すべき項目です。新しい VPS で最初の 10 分以内に行う確認

FAQ

SSH を作成したのは誰ですか。なぜ作成したのですか。

ヘルシンキ工科大学の研究者 Tatu Ylönen が、大学ネットワークでパスワードの盗聴攻撃が発生したことを受け、1995 年に SSH を作成しました。当時のリモートログインツールである telnet と rlogin は、パスワードを可読テキストのままネットワーク上に送信していました。そのため、共有セグメントを監視している者は、通過する認証情報を収集できました。彼は 1995 年 7 月にこのプログラムをフリーウェアとして公開しました。同年末までに、50 か国でおよそ 20,000 人が利用するようになり、1995 年 12 月には SSH Communications Security を設立しました。

SSH-1 と SSH-2 の違いは何ですか。

両者は異なるプロトコルであり、通信上の互換性はありません。SSH-1 は単一の一体化したプロトコルで、完全性の検証に CRC-32 を使用し、クライアントがサーバーの RSA 鍵で暗号化したセッション鍵を送信していました。SSH-2 は処理をトランスポート層、認証層、接続層に分割します(RFCs 4251 から 4254、2006 年 1 月)。完全性の検証には HMAC を使用し、Diffie-Hellman でセッション鍵を導出します。そのため、後からホスト鍵を盗まれても、記録済みの通信内容は秘匿されます。SSH-1 は段階的に OpenSSH から廃止され、2017 年 10 月の version 7.6 で終了しました。

OpenSSH が元の SSH 実装に置き換わったのはなぜですか。

元の実装の開発は、制限の厳しいライセンスの商用製品へ移行し、自由に再利用できる最後のリリースは ssh 1.2.12 でした。1999 年初頭、Björn Grönvall がこのリリースを OSSH として復活させました。その後、OpenBSD team が OSSH を fork して OpenSSH を作成し、1999 年 12 月 1 日に OpenBSD 2.6 とともにリリースしました。OpenBSD では、base system に無制限のライセンスで提供され、監査済みのコードが必要でした。この 2 つの条件があったため、他のすべての operating system も portable branch を通じて同じ実装をリリースできました。

初めて接続するときに SSH がホスト鍵について尋ねるのはなぜですか。

クライアントはそのサーバーをまだ認識しておらず、鍵と比較できる情報を持っていないためです。暗号化だけでは、正規のサーバーと通信経路の途中にあるマシンを区別できません。そのため SSH は鍵でサーバーを識別し、確認した内容を ~/.ssh/known_hosts に記録します。初回接続時だけは、確認対象となる保存済みの値がありません。これが、クライアントが代わりにユーザーへ確認する理由です。フィンガープリントを、provider console またはサーバー自体から取得したものと比較してください。その後に REMOTE HOST IDENTIFICATION HAS CHANGED というメッセージが表示された場合は、説明できるまで実際の事象として扱ってください。

アップグレード後に古い SSH 鍵が使えなくなるのはなぜですか。

OpenSSH が公開されたスケジュールに従ってアルゴリズムを廃止するためです。DSA(ssh-dss)鍵は、2015 年の OpenSSH 7.0 でデフォルト無効になり、2025 年 4 月 9 日の OpenSSH 10.0 で完全に削除されました。RSA 鍵は引き続き使用できます。ただし、SHA-1 で作成された署名は 2021 年 9 月の OpenSSH 8.8 でデフォルト無効になりました。古いサーバーへ接続すると、この問題は sign_and_send_pubkey: no mutual signature supported として表示されます。2014 年 1 月の OpenSSH 6.5 以降で利用できる Ed25519 鍵を使えば、両方の問題を回避できます。