- はじめに — バグフィックスリリースに見える転換点
- 鍵交換側の話 — sntrup761からmlkem768デフォルトまで
- 10.1の警告 — WarnWeakCryptoが作った運用の現実
- 10.4 — 署名の戦線が開いた
- ドラフト-00の現状 — 数字が合わない
- 運用者を噛む変更たち — 10.0から10.4まで
- やってはいけないこと
- 実務チェックリスト
- おわりに
- 参考資料
はじめに — バグフィックスリリースに見える転換点
OpenSSH 10.4は2026年7月6日に出ました。リリースノートの自己紹介は控えめです — "a number of security fixes as well as general bugfixes and a couple of new features"。たいていの運用者はここまで読んでパッケージ更新のキューに入れ、先へ進むでしょう。
ところがその "a couple of new features" のひとつが、SSHプロトコルの次の5年を予告しています。ML-DSA-44とEd25519を束ねた耐量子複合署名が実験的に入りました。鍵交換の耐量子移行が事実上終わった時点で、いよいよ署名の番が始まったのです。
昨日上げたPQ証明書がまだ来ない理由の回では、TLS/WebPKI側の話を扱いました — あちらはML-DSA署名が大きすぎて、Merkle Tree Certificatesという迂回路を作っている最中です。SSH側は事情が違い、だから別の道を行きます。本稿はOpenSSH 10.0から10.4までのリリースノートを原文で突き合わせながらその道をたどり、途中で運用者を噛む非互換変更をあわせて整理します。
まずタイムラインを打ち込んでおきます。すべて公式リリースノート基準です。
9.0 2022-04 sntrup761x25519-sha512 がデフォルトKEXに (耐量子デフォルトの始まり)
9.9 2024-09-19 mlkem768x25519-sha256 を追加
10.0 2025-04-09 mlkem768x25519-sha256 がデフォルトKEXに。DSA削除。サーバーデフォルトからmodp DH削除
10.1 2025-10-06 非PQ鍵交換の警告を導入(WarnWeakCrypto)。XMSS削除。エージェントソケットが/tmpを脱出
10.2 2025-10-10 緊急バグフィックス (ControlPersistがセッションを使えなくする問題、bz3872)
10.3 2026-04-02 証明書の空principalsの意味が反転。rekey非対応実装との互換コード削除
10.4 2026-07-06 実験的な複合署名 ssh-mldsa44-ed25519@openssh.com。seccomp失敗の致命化
鍵交換側の話 — sntrup761からmlkem768デフォルトまで
OpenSSHの耐量子ページによれば、耐量子鍵交換がデフォルトになったのは2022年4月の9.0からです。当時はNISTの標準化が終わる前だったので、NTRU Prime系の sntrup761x25519-sha512 を選びました。9.9でNIST標準(FIPS 203)ベースの mlkem768x25519-sha256 が追加され、10.0でデフォルトになりました。
10.0のリリースノートがデフォルト交代の根拠として挙げたのは4つです — 量子コンピュータ攻撃に対して安全とみなされること、既存のcurve25519-sha256より弱くならないことが保証されること、NISTが標準化したこと、そして以前のデフォルト(sntrup761)よりかなり速いこと("considerably faster than the previous default" — プロジェクト自身の説明であり、リリースノートにベンチマークの数値が別途提示されているわけではありません)。
ここで「弱くならないことが保証」がハイブリッド構造の核心です。mlkem768x25519-sha256 はML-KEM-768と古典的なx25519 ECDHの両方を実行し、2つの共有秘密を連結してハッシュします。IETF文書(draft-ietf-sshm-mlkem-hybrid-kex、本稿執筆時点で-10リビジョンがRFCエディタキューに入っています)の定義ではこうです。
K = HASH(K_PQ || K_CL)
K_PQ: ML-KEM-768 のカプセル化で得た共有秘密 (FIPS 203)
K_CL: x25519 ECDH で得た共有秘密 (RFC 8731)
ML-KEMが将来の暗号解析で崩れてもx25519が残り、量子コンピュータがx25519を壊せばML-KEMが防ぎます。なぜこんな保険までかけて今急ぐのかというと、"store now, decrypt later" — 今行き交うトラフィックを保存しておいて後で量子コンピュータで解く攻撃のためです。鍵交換が破られればセッション全体が復号されるので、暗号学的に意味のある量子コンピュータ(CRQC)が存在しない今日でも、鍵交換だけは先に変えておかねばならないという論理です。OpenSSHのPQページはCRQC到来の見通しを5〜20年の範囲とし、多くの観測者の期待を2030年代半ばと書いています。
プロトコルレベルの背景 — KEXがどこに挟まり何に署名するのか — はSSHプロトコル ディープダイブの回を参照してください。
10.1の警告 — WarnWeakCryptoが作った運用の現実
デフォルトを変えることと、エコシステムを動かすことは別の問題です。10.1(2025-10-06)はもっと直接的な手段を持ち出しました。クライアントが耐量子でない鍵交換で折衝を終えると、こんな警告を出します。
** 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. See https://openssh.com/pq.html
この警告はデフォルトで有効で、新しいssh_configオプション WarnWeakCrypto で制御します。運用の観点でこの警告の意味は単純です — クライアントを10.1以上に上げた瞬間、組織内の古いSSHサーバーがすべてユーザーの目の前にさらけ出されます。古いネットワーク機器、ベンダーが放置したアプライアンス、KexAlgorithms を昔の値で固定してあるゴールデンイメージが、そろって警告を出します。
正しい解法はサーバーを上げることです。sntrup761は9.0から、mlkem768は9.9からサポートされているので、サーバーがすでにそのバージョン帯なら、設定が KexAlgorithms でPQアルゴリズムを切ってしまっていないかをまず確認すればよいです。どうしてもサーバーを上げられない場合のためにPQページが勧めるのは、ホスト単位での選別的な沈黙です。
Match host unsafe.example.com
WarnWeakCrypto no-pq-kex
グローバルに WarnWeakCrypto no を打ち込みたい誘惑があるでしょうが、リリースノートはこのオプションが今後ほかの弱い暗号の警告にも使われると予告しています。グローバルに切るのは、未来の警告まで前もって切ることになります。警告を無視するようユーザーを訓練してしまうのが最悪の結果だと考えれば、沈黙は狭くかけるほうが正しいです。
10.4 — 署名の戦線が開いた
鍵交換と違い、署名は "store now, decrypt later" の対象ではありません。署名の偽造は接続が生きているその瞬間にやり遂げねばならない仕事なので、今日保存したトラフィックの認証を10年後にさかのぼって破ることはできません。OpenSSHのPQページもこの点を明示したうえで、署名側の唯一の緊急性はCRQCが現実になる前に古典的な署名鍵を引退させることだけだと書いています。だから署名の移行は鍵交換より数年遅れて出発してよいレースであり、実際そのように進んでいます。
前兆は10.1にありました。実験的に入っていたハッシュベース署名XMSSを削除しながら、リリースノートにこう書いています — "We expect to implement a new post-quantum signature scheme in the near future."。その near future が10.4です。
10.4はdraft-miller-sshm-mldsa44-ed25519-composite-sigsに規定された複合署名 ssh-mldsa44-ed25519@openssh.com を実験サポートします。ドラフトの著者はOpenSSHのDamien Miller本人です。構造は鍵交換のハイブリッドと同じ哲学です — 耐量子のML-DSA-44と古典的なEd25519で同じメッセージをそれぞれ署名し、検証は両方通って初めて有効です。ドラフトのセキュリティ考慮事項そのままに、偽造するには2つのアルゴリズムを両方とも破らねばなりません。
M' = Prefix || Label || len(ctx) || ctx || SHA512(M)
Prefix = "CompositeAlgorithmSignatures2025"
Label = "COMPSIG-MLDSA44-Ed25519-SHA512"
mldsa_sig = ML-DSA-44.Sign(mldsa_sk, M', ctx=Label)
ed25519_sig = Ed25519.Sign(ed25519_sk, M')
composite_signature = mldsa_sig || ed25519_sig
デフォルトではないので、使うには両端で HostKeyAlgorithms、PubkeyAcceptedAlgorithms などに直接追加せねばならず、鍵の生成はこうします。
ssh-keygen -t mldsa44-ed25519
サイズの感覚をつかんでみると — Ed25519は公開鍵32バイトに署名64バイトです。FIPS 204基準でML-DSA-44は公開鍵1,312バイトに署名2,420バイトです。複合公開鍵は2つの公開鍵を連結した1,344バイトで、複合署名は2,484バイトになります。昨日扱ったTLS側ではハンドシェイク1つが署名を複数と公開鍵を複数運ぶので、このサイズが耐えられずMerkle Tree Certificatesという迂回路を掘っている最中ですが、SSHのハンドシェイクはホスト鍵1つと署名1つだけを運びます(RFC 4253のKEX構造)。接続あたり4KB足らずの追加コストなので、SSHは迂回路なしにアルゴリズムをそのまま入れ替える正攻法が可能なのです。
ドラフト-00の現状 — 数字が合わない
ここで「実験的」というラベルを真面目に受け取るべき理由をひとつお見せします。ドラフト-00(2026年6月2日付)の本文は、複合署名のサイズをこう書いています。
byte[3309] mldsa_sig
byte[64] ed25519_sig
This 3373-byte combination is henceforth referred to as
"composite_signature".
ところがFIPS 204が定めたML-DSA-44の署名は2,420バイトです。3,309バイトはひとつ上のML-DSA-65の署名サイズです。実際のOpenSSH 10.4のソース(タグV_10_4_P1のcrypto_api.h)は MLDSA44_SIGBYTES 2420 でFIPS 204と一致するように実装しているので、ドラフト本文のほうが誤記に見えます。同じ文書の署名コンテキストの節には "TODO TODO TODO" がそのまま残っていたりもします。
これはドラフトを嘲笑しようというのではありません — -00の個人提出(individual submission)文書とはもともとこういう状態であり、だからこそまだワーキンググループに採択もされていない文書だという事実自体が情報です。ワイヤーフォーマットと鍵フォーマットがリビジョンごとに変わりうる段階だという意味であり、OpenSSHが "experimental" と釘を刺したのと正確に同じことを、文書の状態が語っているのです。
運用者を噛む変更たち — 10.0から10.4まで
耐量子の話に隠れて見えにくいですが、このリリーストレインは廃止(deprecation)の連続でもありました。失敗が現れ方ごとに束ねてみます。
接続の時点で失敗するもの。 10.0がDSA署名アルゴリズムを完全に削除しました(2015年にデフォルト無効化で始まった廃止手続きの完結です)。同じリリースでサーバーデフォルトの有限体DH — diffie-hellman-group* と diffie-hellman-group-exchange-* — が外れました。ECDHもPQもできない古いクライアントは、10.0以上のサーバーのデフォルト設定に接続できません(クライアント側のデフォルトは維持されたので、新しいクライアントが古いサーバーに付く方向は引き続き可能です)。またmoduliファイルが存在するのに要求範囲の値がないとき、コンパイル済みのグループへ静かにフォールバックしていた動作もなくなったので、手で編集したmoduliファイルが今では接続失敗につながりえます。
セッションの途中で死ぬもの。 こちらのほうがデバッグははるかに厄介です。10.3(2026-04-02)はrekeyをサポートしない実装とのバグ互換コードを削除しました — 接続は正常に結ばれ、転送量が積もって再キーイングが必要になる時点になって初めて失敗します。10.4は認証後の再キーイング中にKEX以外のメッセージを送るピアを即座に切るようプロトコルを厳格化しました(RFC 4253の7.1節を守らない実装が対象です)。どちらも噛むのは最新のOpenSSHではなく、反対側のレガシーな組み込み機器です。「つながるにはつながるけれど、大きなファイルを送ると切れます」というチケットが上がってきたら、これを疑ってください。
自動化とツーリングが壊れるもの。 10.1がエージェントソケットを/tmpから ~/.ssh/agent の下へ移しました。/tmpアクセスが制限されたプロセスがエージェント鍵をつかめないようにするセキュリティ改善ですが、/tmp/ssh- のパスをグロブしていた監視・整理スクリプトはすべて無効になります。副作用もあります — OSの/tmp掃除がもう古いソケットを片付けてくれないので、ssh-agentが自前の整理機能とフラグ(-U、-u、-uu、そして/tmpへ戻す-T)を新たに得て、NFSホームのためにソケットパスにホスト名のハッシュが入ります。10.4では sshd -G の設定ダンプが小文字一色から大文字小文字混在("PubkeyAuthentication")に変わりました — 小文字を前提にgrepしていたコンプライアンススクリプトが静かに空の結果を出しはじめます。10.1のIPQoS刷新により、lowdelay、throughput、reliability といったToSキーワードは今では無視され、システムデフォルトのQoSに落ちます。
認証の動作が変わったもの。 10.3の変更のうち最も味わうに値するもの — 以前はprincipalsセクションが空である証明書が、authorized_keysの principals= オプション経路でワイルドカードとして、つまりどのprincipalにもマッチするものとして扱われていました。意図された動作でしたが、CAが誤ってprincipalsが空の証明書を発行すると、使い物にならない証明書になるどころか、そのCAを信頼するすべてのアカウントでログイン可能な万能鍵になるという罠でした。10.3から空のprincipalsは何にもマッチしません(TrustedUserCAKeys経路にはもともとこの問題はありませんでした)。逆にこのワイルドカード動作に頼っていた環境があれば、アップグレード直後に認証が壊れます — その依存がそもそも危険だったという意味ですが、壊れるものは壊れるのです。10.1のssh-addは証明書をエージェントに入れるとき、失効を証明書の失効時刻+5分の猶予で自動設定するようになり(-Nで無効化)、長寿命のエージェントに短命の証明書を入れておいて「ずっとあるだろう」としていたパイプラインは、今では失効後に失敗します。
ビルドとデプロイ環境。 10.4からLinuxでseccompサンドボックスやNO_NEW_PRIVSの有効化に失敗すると致命的エラーになります。以前はログだけ残して動き続けましたが、今やそういうシステムはconfigureの時点でサンドボックスを明示的に切らねばなりません。非常に古いカーネルや変わったコンテナランタイムの上にsshdを載せる場合が対象です。
予告された次の打者。 10.1と10.2のリリースノートはSHA1 SSHFP DNSレコードの廃止を予告しています — 将来のリリースでSHA1 SSHFPは無視され、ssh-keygen -r はSHA256レコードだけを生成するようになります。SSHFPをDNSに植えてある組織なら、今再生成しておくほうが安上がりです(SHA256 SSHFPは2012年の6.1からサポートされています)。
加えて10.4には、アップグレード自体の動機になるセキュリティ修正もいくつもあります — 悪意あるサーバーが sftp host:/path . のダウンロードを見当違いの場所に書かせられた問題、リモート間のscpコピーで対象ディレクトリの親にファイルを書けた問題、internal-sftpのコマンドラインが9番目の引数以降で静かに切られてセキュリティオプションが捨てられうる問題、GSSAPI認証を有効にしたときの事前認証DoS、再キーイング中にサーバーがホスト鍵を変えたときのクライアントのuse-after-freeといったものです。
やってはいけないこと
複合署名を本番で有効にしないでください。 上で見たとおり仕様は-00の個人提出ドラフトであり、本文にTODOとサイズの誤記が残り、OpenSSH自身がexperimentalと呼んでいます。ワイヤー/鍵フォーマットが変われば、今作った鍵とデプロイ設定が負債になります。ラボで鍵を作ってみて相互運用を観察するところまでが、今の段階に合った行動です。
署名のためにホスト鍵を今ひっくり返さないでください。 署名にはさかのぼる脅威がないというのがOpenSSH自身の説明です。今必要なのはPQホスト鍵の配布ではなく、CRQCが可視化されたときに組織全体のホスト鍵とCA鍵をどれだけ速く替えられるか — その回転の筋肉です。インベントリなしには回転もありません。
警告をグローバルに切らないでください。 WarnWeakCrypto は今後ほかの弱い暗号の警告まで管轄する予定のオプションです。Matchブロックでホスト単位でだけ沈黙させ、沈黙させたホストの一覧そのものを技術的負債の一覧として管理してください。
KexAlgorithmsをゴールデンイメージに固定して忘れないでください。 昔の機器の互換のために一度固定したアルゴリズムの一覧は、PQデフォルトも、未来の削除も、すべてすり抜けさせてしまいます。固定が本当に必要なら、失効日を一緒に書いておくほうがましです。
実務チェックリスト
# 1) クライアントが実際に折衝するKEXの確認 — 先頭項目がmlkem768x25519-sha256か
ssh -G host.example.com | grep -i kexalgorithms
# 2) 設定のどこかでアルゴリズムを固定してある箇所を探す
grep -riE 'kexalgorithms|hostkeyalgorithms|pubkeyacceptedalgorithms' /etc/ssh/
# 3) /tmp下のエージェントソケットを前提にしたスクリプトを探す (10.1で~/.ssh/agentへ移動)
grep -rn 'tmp/ssh-' /opt/scripts/
# 4) sshd -G の出力を小文字でgrepしていた箇所を探す (10.4で大文字小文字混在に変更)
grep -rn 'sshd -G' /opt/scripts/ | xargs -r grep -l 'grep [a-z]'
# 5) レガシー機器のrekey生存テスト — 閾値を下げて強制的に再キーイングを誘発
ssh -o RekeyLimit=1M legacy-appliance 'dd if=/dev/zero bs=1M count=16' > /dev/null
これに加えて、SSH証明書を使う組織なら、CAの発行パイプラインがprincipalsの空な証明書を作りうるか(10.3より前のサーバーが残っていれば、それが万能鍵になります)、authorized_keysの principals= オプションを使う箇所がどこかを、今のうちに一覧化しておいてください。耐量子移行の全体像 — SSHの外のTLS、VPN、コード署名まで — は耐量子暗号化移行:Q-Dayに対する70億ドルの競争の回と重ねて見るとよいです。
おわりに
OpenSSHの耐量子移行は教科書的な順序で進んでいます。さかのぼる脅威のある鍵交換から — 標準化の前にsntrup761で出発(9.0)、標準が出るとmlkem768へ交代(10.0)、警告でエコシステムを押し込む(10.1) — そしてさかのぼる脅威のない署名は、標準文書と実験実装で今まさに出発したところ(10.4)。急ぐものから強く、急がないものは慎重に。この順序の感覚は、昨日見たTLS側の話と正確に同じ原理で動きながら、SSHの軽いハンドシェイクのおかげでずっと単純な経路をたどります。
同時にこのリリーストレインは、古いものを着実に片付けてきました。DSA、modp DHのサーバーデフォルト、/tmpのエージェントソケット、rekeyできない実装への忍耐、空のprincipalsのワイルドカード。それぞれは合理的な削除ですが、噛む時点が接続時、再キーイング時、アップグレード直後、スクリプト実行時とばらばらなので、インベントリなしに食らうと痛いです。リリースノートの "Potentially-incompatible changes" セクションをリリースごとに精読すること — 結局それが本稿全体の要約です。
参考資料
- OpenSSH 10.4 リリースノート (2026-07-06)
- OpenSSH 10.3 リリースノート (2026-04-02)
- OpenSSH 10.1 リリースノート (2025-10-06)
- OpenSSH 10.0 リリースノート (2025-04-09)
- OpenSSH: Post-Quantum Cryptography — 警告文とFAQ
- draft-miller-sshm-mldsa44-ed25519-composite-sigs — ML-DSA 44/Ed25519複合署名の仕様
- draft-ietf-sshm-mlkem-hybrid-kex — mlkem768x25519-sha256の仕様 (RFCエディタキュー)
- NIST FIPS 204 — ML-DSA標準 (鍵・署名サイズの表)
- openssh-portable V_10_4_P1 — crypto_api.hのMLDSA44定数とssh-mldsa-eddsa.c
- PQ証明書がまだ来ない理由 — TLS/WebPKI側の同じ話 (関連記事)
현재 단락 (1/77)
[OpenSSH 10.4](https://www.openssh.com/txt/release-10.4)は2026年7月6日に出ました。リリースノートの自己紹介は控えめです — "a numb...