Litmus — 話題のニュースを、深く読み解く。 RSS
ソフトウェア

OpenSSH 10.6p2、Alpine Linuxなどの認証すり抜けを修正

OpenSSHは10.6p2で、musl libcを使うAlpine LinuxなどのSSHサーバーが抱えていた認証バイパスを修正した。原因の仕組みと対象条件をまとめた。

データセンターのパッチパネルに規則正しく並んだ水色の光ファイバーケーブル

イメージ写真 記事の内容を撮影したものではありません。Photo by Brett Sayles on Pexels

この記事には Amazon アソシエイトのリンクを含みます。

Alpine LinuxでDockerコンテナを運用していて、SSHは鍵認証だけを許可し、パスワード欄は使わない印の「*」にしてある。そう設定していれば、パスワードを知らない相手はログインできない。はずだった。OpenSSHは2026年11月5日公開の10.6p2で、この前提が崩れる条件があったと明らかにし、修正した。256バイトを境にした、ある長さのパスワードを送ると、パスワード欄が「*」のアカウントにもログインが通ってしまう経路があったという。何が起きていて、どういう条件で、どう直ったのかを順に追う。

「*」アカウントに通ったログイン

Alpine Linux公式のセキュリティアドバイザリは、この問題をこう説明している。sshdには、ハッシュ用の「salt(ソルト)」を別アカウントから借りてしまう処理がある。この処理のせいで、長いパスワードを送ると、パスワード欄が「*」のアカウント(鍵認証専用のユーザーなど)にも認証が通ってしまう。攻撃者はパスワードを知らなくても、1回の接続でログインできる。

発見者のÖzgün Kültekin氏は自身の技術公開ページで、再現条件を示している。257〜1,024バイトの範囲で、中身を問わない任意の文字列を送るとこの現象が再現するという。普段使うパスワードよりずっと長い、半角で300文字前後の文字列を送るだけで、本来は拒否されるはずのログインが通る。

OpenSSHの開発チームはこれを認めた。公式リリースノートには「PAMサポートを無効にしてビルド・実行された一部のLinuxシステムにおけるパスワード認証バイパスを回避する」とある。この修正を10.6p2に含めたと記している。Alpine Linuxも同日、各バージョン系列向けの修正パッケージを公開している。

なお、国内の一部報道はこの問題に「CVE-2026-123158」という番号を充てて紹介している。だがOpenSSHの公式リリースノートにもAlpine公式のアドバイザリにも、この番号の記載はない。NVDの該当ページを確認しても詳細は表示されなかった。Alpine公式は「執筆時点でCVE識別子は未割り当て」と明言している。番号そのものより、現象と修正バージョンを基準に読み進めたほうが確実だ。

では、パスワードの中身を1文字も比較しないまま、なぜログインが通ってしまうのか。

「*」と「*」が一致してしまう仕組み

答えは、sshdが実際に比較している値が、入力したパスワードではなく別の記号だったという点にある。発見者の解説と、musl libc・OpenSSHそれぞれの公開情報をたどると、次の4つの設計判断が順につながっていた。

4つの設計判断が順につながった

  1. パスワード欄の「*」は、そのアカウントがパスワードではログインできないという印になる。鍵認証専用のユーザーや、LDAPで管理しているユーザーに使われる
  2. sshdは本来、入力されたパスワードをcrypt()という関数でハッシュ化し、その結果を保存されている値と文字列として比較する。「*」が保存値なら、どんなパスワードをハッシュ化してもまず一致しない
  3. ところがmusl libc(Alpine Linuxなどが使うCライブラリ)のcrypt()には、SHA-512方式で256バイトを超えるパスワードを渡すと処理に失敗するという制限がある。失敗したとき、musl libcは2012年の変更以降、NULLではなく文字列"*"を返す。本来呼び出し側がクラッシュしないための配慮だった
  4. 2016年、OpenSSHは「存在しないユーザー名を応答時間の差で当てられる」問題(CVE-2016-6210)への対策を入れた。有効なハッシュを持たないアカウント宛てにも、他の実在アカウントのsaltを借りてダミーのcrypt()計算を行い、応答時間を揃える処理だ。この対策は、パスワード欄が「*」の実在アカウントにも適用される

257バイトを境に何が起きるか

257バイト以上のパスワードを「*」のアカウントに送ると、4の処理でmuslのcrypt()が呼ばれ、3の上限に引っかかって失敗し、"*"を返す。sshdが比較するのは、保存値の「*」と、crypt()が返した「*」になる。比較の両側がどちらも同じ記号になれば、sshdにはパスワードの中身を見分ける手がかりがない。

パスワードの長さという、本来は無関係なはずの条件が、2つの独立した設計判断の組み合わせを抜け穴に変えていた。自分はこの説明を読んで、「*同士が一致する」という一文の意味が分かるまで2回読み返した。2016年の対策は当時それ単体で正しく、muslのエラー処理も単体では妥当な配慮だ。10年後に別のライブラリと組み合わさって抜け穴になるとは、どちらの変更時点でも想定しづらい。

この仕組みが分かったところで、自分の環境がこの条件に当てはまるかどうかが気になる。

自分の環境は対象か

Alpine公式アドバイザリは、影響を受ける条件を次のように挙げている。次のすべてに当てはまる環境だけが対象になる。

  • sshdが、PAMを使わずにビルド・実行されている(Alpine Linuxのopenssh-serverは既定でこの状態)
  • PasswordAuthenticationが有効になっている(OpenSSHの既定)
  • パスワード欄が「*」のアカウントが存在する(鍵認証専用のユーザー、LDAPユーザー、Alpineのrootなど)
  • $5$または$6$形式のパスワードハッシュを持つ、実在するローカルアカウントが他に1つ以上ある

この条件が示すとおり、影響はmusl libcを使うLinuxに限られる。代表例はAlpine Linuxで、発見者はOpenWrt・Buildroot・Yoctoでも同様の構成があり得ると説明している。Debian・Ubuntu・Fedoraなどglibcを使うディストリビューションや、PAM経由でログインする環境は対象外になる。自宅サーバーやVPSの大半を占めるこれらの環境であれば、今回の問題そのものは当てはまらない。

rootアカウントへのパスワードログインは、OpenSSHの既定で禁止されている。直接rootを乗っ取られるにはPermitRootLogin yesなどの設定も必要だ。ただしAlpine公式の構築済みクラウドイメージには注意点がある。既定のalpineユーザーはパスワードなしでdoasを使え、root相当の権限を持つ場合があるとアドバイザリは述べている。

対象になる条件が分かったら、次にすべきことは何か。

今すぐすべきこと

  1. Alpine Linuxであればapk upgrade -U -aでパッケージを更新し、rc-service sshd restartでsshdを再起動する。パッケージを更新しただけでは、動作中のsshdプロセスには反映されない
  2. すぐに更新できない場合は、/etc/ssh/sshd_config.d/にPasswordAuthentication noを設定したファイルを置き、sshdを再起動する。実施前に、鍵認証でのログインが問題なく動くことを確認しておく
  3. OpenWrt・Buildroot・Yoctoなど他のmusl採用環境を使っている場合は、各プロジェクトが配布するOpenSSHパッケージが10.6p2相当に更新されているかを確認する

Alpine公式アドバイザリには、修正済みパッケージのバージョンがリリース系列ごとに示されている。

Alpineのバージョン系列修正済みのopenssh-server
edge10.6_p2-r0
3.2410.3_p1-r2
3.2310.2_p1-r1
3.2210.0_p1-r11
3.219.9_p2-r1
3.209.7_p1-r6
3.199.6_p1-r3
3.189.3_p2-r4
3.179.1_p1-r7
3.169.0_p1-r6

表の行が示すとおり、サポートが終了した古い系列(3.16〜3.20)にも修正パッケージが用意されている。apk upgradeで入るopenssh-serverのバージョンが、使っている系列の行以上になっているかを確認すれば、更新できたかどうかが分かる。

まとめ

OpenSSHは10.6p2で、musl libcを使いPAMを無効にしたLinux(Alpine Linuxなど)で起きていた認証すり抜けを修正した。原因は2つあった。1つは、2016年のなりすまし対策が「*」のアカウントにもcrypt()計算を強制すること。もう1つは、muslのcrypt()が256バイトを超える入力で"*"を返して失敗することだ。この2つが重なり、比較の両側が同じ記号になっていた。Debian・Ubuntu・Fedoraなどglibcを使う環境やPAM経由のログインは対象外になる。Alpineを使っている場合は、パッケージの更新とsshdの再起動で塞げる。

この記事の先を読む本を探す

特定の本を勧めるものではありません。検索結果から、いまの版と目次を確かめて選んでください。

コメント

気づきや感想をどうぞ

記事への補足や、読んで考えたことをお寄せください。個人情報や、他の人を傷つける内容の投稿はお控えください。

コメントを読み込んでいます…

    ほかの記事

    最新の記事 →