爆速SSH3登場!HTTP/3で接続確立が高速化 高遅延にも強い次世代セキュアシェルとは?
引用元:https://news.ycombinator.com/item?id=45395991
従来のSSHより速いっていう主張には懐疑的だったけど、README見たら接続確立は速いけど、アクティブな接続の速度は同じって書いてあったよ。これはすごく納得できるし、妥当な主張だね。
とは言え、賭けてもいいけど、このツール/プロトコルは高遅延リンクではSSHよりずっと速いはず。だってUDPを使ってるからね。もっとデータを送る前にACKを待たないことで、世界のあちこちにscpでデカいファイルを送るみたいな場合に、かなりのブーストになると思うな。
SSHが高遅延リンクでスループットが低いのはTCPのせいじゃなくて、SSHプロトコルがTCPのウィンドウサイズに加えて、小さすぎる最大ウィンドウサイズをハードコードしてるからだよ。このSSHのウィンドウサイズ制限はSSHストリームごとだから、多くの並列ストリームを使えば克服できるけど、ほとんどのプログラム(scp、rsync、sshコマンド経由でデータをパイプする)はそれを利用しないんだ。だからiperf3で測ると普通のTCPよりずっと遅い。こんなものが存在するなんて馬鹿らしいし、TCPに任せとけばいいのにね。
あんまり関係ない話だねー。だって高遅延リンクでSSHを定期的に使う人は、もうとっくにSSH+moshを使ってるからね。
そういう意味では速くないんだ。でもSSH接続は複数のサブストリームを持てるよね、特にポートフォワーディングの場合。一つの古典的な接続だと、一つのストリームの問題が全体を遅くするヘッドオブラインブロッキングを引き起こすことがあるけど、QUIC/HTTP/3プロトコルならこれを解決できるんだよ。
moshの超デカい欠点は、独自のレンダリングをしてスクロールバックバッファを破壊することだね。(tmuxを挟めば中間策になるって知ってるよ)でもここは関係ない話。READMEにもはっきり書いてあるし「実行中のセッションでのキーストロークの遅延は変わらない」ってね。
そりゃもちろんACKはあるよ。ACKがないプロトコルもあるけど、それは特殊なやつでHTTP/3はそうじゃないんだからね。
「超デカい欠点」(tmuxを使えば完全に解決できるのに)YouTubeとかSNSの時代って、みんな大げさになりすぎだよね :/ moshは問題を解決する。tmuxは、一部のユーザーワークフローに影響を与える設計上の決定を解決する「ソリューション」を提供するんだ。要するに、moshが必要ならtmuxを使うのも別に難しいことじゃないって言いたいのさ。
彼が言ってたのは「ACKを待たない」ってことだよ。
「TCPだけでいい」って意見あるけど、SSHが独立したストリームを多重化するには必要だよ。
一つのストリームが詰まると、他のストリームもヘッドオブラインブロッキングで止まっちゃうんだ。TCPとは別のウィンドウベースフロー制御とかが必要で、HTTP/2も似たことしてるよ。俺も昔、これに気づかずに困った経験あるから。
ちょっとした豆知識だけどさ、SSHも複数ストリームに対応してるんだぜ。多重化(multiplexing)ってやつね。
どのプロトコルもウィンドウ制御使うし、ACK待ちはリンク障害検出に必要だろ。HTTP/3もそれがある。
TCPと比べてどうかはまだ分からん。SSHとQUICのユースケースは違うしね。
SSHのバッファが足りないなら「long fat links」ってやつ。LinuxのチューニングやHPN-SSHプロジェクトも見てみろよ。
https://fasterdata.es.net/host-tuning/linux/
だからmoshがあるんだよ。あれは高遅延や高パケットロスのリンク上でのターミナル用に作られてるからね。
TCPみたいにSSHでも設定オプションで調整できるようにしてくれよ。2MBのハードコードはマジでアホ。
自分のネットワークでSSHがTCPより遅いのはおかしいだろ。TCPみたいにデータ破棄と再送も実装しろよ。多重化するなら必要な機能は全部やれ。
「接続が1000倍速くなってもスケールするか?」って設計時にまず考えるべきだろ。
tmuxだけじゃmoshの全てをカバーできないよ。moshは高遅延・パケットロスやローミングでの切断対策が主な用途だろ。
特に高遅延だと、mosh+tmuxのスクロールバックバッファは最悪。俺は高遅延での読み込みが多いなら、キー入力が遅くてもSSHを選ぶね。「大きなデメリット」ってのは全然大げさじゃないよ。
SSHって高遅延・高帯域幅リンクだとマジで遅いんだよ。HPN-SSHがこれを直してくれるんだ。
大陸間のデータセンターでrsync試せばすぐわかるよ。HTTP/3(とこのプロジェクト)は、この問題がないことを期待してるよ。
https://www.psc.edu/hpn-ssh-home/hpn-ssh-faq
これ読んで「誰が気にするんだ?」って思ったね。
俺は20年間毎日200回以上SSHセッションを張ってきたけど、接続確立がもっと速ければって思ったことなんて一度もないぞ。
この実装って、あることをするの?それとも単にH3ストリームを一つ使うだけ?
moshって使いこなすのが大変だよね。細かいバグも多いし、LC_ALL変数がズレてると接続できないこともあるんだ。開発も止まってるみたいだし、ターミナルマルチプレクサで使うと予測システムがパネルを壊して集中できないのが困るね。参照:https://github.com/mobile-shell/mosh/issues/98
接続の意図によって考えは変わると思うな!記事の最後の段落にある”For read-heavy, reconnectable workloads”って箇所、まさにそれだよ。俺がmoshを使ったのは、接続が悪いルーターやDDoS中のサーバーでの素早い操作が主だから、”huge downside”は全然気にならなかったな。
scpの代わりに、SSHで設定してQUICで大量のデータを転送するツールがあるんだよ。高遅延のパスでもずっと速いんだ。これ見てみて:https://github.com/crazyscot/qcp
それってよくあるTCPの問題じゃないんだよな。ACKメカニズムがTCPを制限するのは、戻りパスがめちゃくちゃ非対称だったり混雑してて、ACKが落ちるようなマジで変な状況の時だけなんだ。HTTP/3も当然何らかのACKを使ってるはずで、公平性のためだけでも輻輳制御メカニズムを実装しないわけにはいかないからね。QUIC/HTTP/3の真の強みは、アプリケーション層がOSのTCPより新しい”独自のTCP”を提供できる点にあるんだよ。
俺はよく’rclone’を使ってるよ。SSHも対応してるし、’–transfers’引数を使えば複数のファイルも楽に扱えるんだ。でも、一つだけだと並列化されないって聞いた気がするな。
SSHは複数のチャネルを同じTCP接続で多重化するから、ヘッドオブラインブロッキングの問題が起きるんだ。記事の”Should you find yourself limited by the default buffering of SSH (10+Gbit intercontinental links)”って箇所だけど、それは違うな。OpenSSHは2MBのウィンドウサイズを持っていて、ギガビット級の速度でも10~20ミリ秒の遅延があればBDPで制限され始めるんだよ。
うん、対応してるかどうかの情報、ここでまとめてるよ:https://github.com/libfuse/sshfs/issues/300
アプリケーション層の多重化とトランスポート層の多重化を混同してるよ。トランスポート層なしでアプリケーション層だけを使うと、帯域幅やレシーバが制限されてる場合に必ずヘッドオブラインブロッキングの問題が起こるんだ。もちろん全てのSSHユーザーがプロトコル多重化を使うわけじゃないけど、多くの人が使うのはCPU性能やログの量を減らせるからだよ。
もっとコメントを表示(1)
訂正ありがとう!さっきの投稿を587に直したよ。僕が言いたいのは、なんで全部のポートをブロックするのかってこと。開けといて、ユーザーが使いたいかどうか決めればいいじゃん。Linuxユーザーはufwを使えば安全だしね。昔はTelnetも使われてたけど、SSHに変わったよね。送られてるリクエストの種類(ストリームか非ストリームかとか)を検知するのが難しいからなのかな?
すべてのプロトコルが同じに見えると、トラフィックシェーピングが難しくなるんだ。新しいプロトコルを開発するなら、目立たないようにすべきだよ。何もいいことないからね。理想としては、すべてのプロトコルは特徴のないランダムなバイトストリームに見えるべきだね。
アウトバウンドのポート25をブロックするのは完全に合理的だよ。インバウンドのポート80や443をブロックするのと同じだね(もしインバウンド接続が選択肢になるならだけど、ほとんどのネットワークではIPv4では無理だけどね)。ポート587、993、995などをブロックするのは、確かにばかげてると思うよ。
それは、見当違いの企業セキュリティチームがすべてをブロックしたり傍受したりしてる結果、必要な悪になってるんだよ。ZscalerでTLS Man-in-the-Middle攻撃モードを有効にしてるチームのことだよ。
HTTPって呼び続ける限りは、ちょっと無理がある気がするな。接続初期化のベストプラクティスはすごく複雑になってて、多くのプロトコルが同じビルディングブロックを必要とするから、最もバトルテスト済みのプロトコルの一つであるHTTPのアプローチに乗っかるのは理にかなってるんだけど、もはやハイパーテキストを転送してるわけじゃないし、なんか変な感じだよね。
うん、QUICの上に構築するのは合理的だけど、SSHをHTTPのセマンティクスに無理やり押し込むのはバカげてるって感じるな。
それはHTTP CONNECTの上に構築されてて、既存のリクエスト(QUICストリーム)を透明なバイトストリームに変換するように意図されてるんだ。これでリクエスト\レスポンスのセマンティクスに対処する必要がなくなるよ。HTTP/3を直接QUICではなく使う理由は、ほとんどデメリットなしで理にかなってるんだ。標準的なHTTP/3リバースプロキシの背後で、好きなサブドメインやパスで実行できるし、ポートスキャナーにも目立たない。オブスキュリティによるセキュリティはセキュリティじゃないけど、多くのスキャナーがSSHサーバーを発見してログイン試行を繰り返すときに発生するCPUオーバーヘッドを減らせるのは間違いないね。
HTTP/3で動かすことにはもう一つメリットがある。ブロックされにくくなるんだ。SSHトラフィックが、まるでGoogle Meetみたいに大量のネットワークトラフィックがあるウェブサイトにいるように見えれば、HTTP/3経由のウェブトラフィック全体をブロックしない限り、ブロックするのがずっと難しくなるよ。たとえそうなっても、HTTP/1 CONNECT経由で機能するけど最適ではないエミュレーションは、おそらくまだできるだろうね。
HTTP/3を使うもう一つの利点は、OAuth 2、OIDC、SAMLなどで認証しやすくなることだね。通常のHTTPフローを使えるから、HTTPフローから別のフローにトークンをコピーする必要がないんだ。
Google CloudのIdentity Aware Proxyが、gcloud compute ssh
コマンドの基盤として、同じようにHTTP CONNECTアップグレードを使ってるよ。
これで認証済みのプロトコル層が2つになるから、彼らには助けになるんだ。ほとんどの標準プロトコルは複数の認証済みIDをサポートしてないしね。彼らのゼロトラストモデルは、接続するたびにクライアント証明書を使って、そのマシンがエンドポイントに接続する権限があるかを認証し、その後のプロトコル層でユーザーを認証するんだよ。
これ、マジでいいアイデアだね!理想的には、トラフィックシェーピングや検閲を難しくするために、すべてのプロトコルは同じに見えるべきだよ。ランダムなバイトストリームか、HTTPみたいにね。もしプロトコルを設計するなら、通信会社と裏取引がない限り、HTTPに偽装してトラフィックが遅くされないようにすることをおすすめするよ。
HTTPもスロットリングされるって知られてるよ。だから、爆速のHTTP SSH接続が、SSHをそのまま使うより遅くなる可能性もあるんだ。特にHTTPトラフィックが不審に見えたらね。独自のプロトコルなら、検閲を回避する戦略を立てられるメリットもあるよ。
いやいや、違うよ。HTTPSに偽装するなら、SNIをtrump.example.comとかrepublicans.example.comに設定すれば、誰もこのトラフィックを遅くするなんてできないはずだよ。もしカスタムで検出可能なプロトコルを使ってたら、その時点で負けだよ。検閲だけじゃなく、一部のアプリを早くするために他のアプリを遅くするトラフィックシェーピングもあるんだからね。プロトコルを識別可能にするのは、何のメリットもないよ。
わかるよ、何かおかしいって感じる気持ち。多様性の欠如はエコシステムの堅牢性を失ってる気がするよね。でも、良い面もあるんだ。多くのセキュリティ問題が一つのスタックに集中してて、それがしっかりメンテナンスされてるんだ。だから、その上に構築されたものすべてが同じ攻撃対象を共有することになる。確かに全部が一気にクラッシュする可能性はあるけど、多くの人が脆弱性を探してて、すぐ修正されるってことでもあるんだ。パフォーマンス最適化も共有されるし、人気が出るとハードウェアにまで組み込まれることもあるんだよ。世界がIPX/SPXやDECNet、X.25じゃなくてTCP/IPに同意したこととか、Linuxカーネルがどこにでもあることとかで、特にたくさんの欠点を見たわけじゃないしね。
これって採用される兆しとかあるの?リンクされてるIETFの提出物は、期限切れの個人ドラフト(誰でも送れるやつ)で、SSHの仕様ワーキンググループからのものじゃないんだよね。SSH3って名前を楽観的に使ってる研究者たちからのものって感じがするな。
あと、誰かがSSH3って呼ぶには、SSHに対する権利が必要なんじゃないかな?まるで、無関係な人がHacker News 2.0っていうウェブサイトを作ったみたいな話だよね。
QUICはもっとレイヤー4、つまりTCPの再実装に近いものだよ。HTTPのレイヤー7とはかけ離れてるね。
>SSHv2で新しいセッションを確立するには5~7回のネットワークRRTがかかり、ユーザーには簡単に気づかれる。SSH3は3回のRRTしか必要ない。実行中のセッションでのキーストロークの遅延は変わらない。
残念。ユーザー目線だと、魅力がわからないな。接続セットアップ時間が気になったことなんて一度もないし。SSHは実績があるしね。たとえ本番稼働可能になったとしても、これを信用するのはリスクを感じるよ。
その発言、本当に困惑するね。RFC 4253 (SSH Transport Layer Protocol)[1]には、「ほとんどの環境では、完全な鍵交換、サーバー認証、サービス要求、およびサービス要求の承認通知には2回のラウンドトリップしか必要ないと予想される。最悪の場合でも3回のラウンドトリップだ。」って書いてあるよ。
セッション初期化時間で問題を感じたことは一度もないし。それはサーバーとクライアント両方の設定に影響されるはずだよ。
[1]: https://datatracker.ietf.org/doc/html/rfc4253
キーストロークの遅延を早く感じさせたいなら、Mosh shellをチェックしてみて!これだよ:https://github.com/mobile-shell/mosh
UDPトンネルが主要な機能で、WireGuardよりずっと軽いんだ。それにOpenID認証もあるよ。
WireGuard(と注目すべきVPNプロトコルはどれも)UDPで動くんだよ。TCP-over-TCPなんて最悪で、まともな人はやらないよ。それにWireGuardより”軽い”ってどういうこと?あれはもうこれ以上ないくらいシンプルだよ(QUICよりは確実にシンプルだ)。
SSHは常にデプロイされてるけど、WireGuardは(追加で)デプロイする必要があるんだ。WireGuardはネットワークアドレスを提供するけど、SSHはネットワークポートを提供する、って違いがあるね。
> OpenID認証も
って、え、マジで?それ本当に動くの?もしそうなら、これはすごいことだよ!SSHの鍵や証明書管理のひどい混乱を解決できる可能性があるもんね。(ここでOpenIDが秘密鍵とどう連携するのかは分からないけど。)
もっとコメントを表示(2)
そうだね、この手の問題で苦労した人たちはその限界を知ってるはず。多重化を使った場合のHead-of-line blockingはまさにその一つだよ。これはすごく妥当な段階的改善だね。重要なのは、これでセキュリティ機構が変わるわけじゃないみたいだし、実装と仕様のドラフトの両方があるから、OpenSSHもいずれ採用する可能性があって、他の実装者を信用する必要がなくなるかもしれないってことだ。
> […] OpenSSHもいずれ採用する可能性があって […]
OpenSSHはOpenBSDだってことを忘れないでね。彼らは特定の技術を採用する際に、特にQUICのような複雑なスタックが絡む場合は、独自の意見と保守的なアプローチを取るんだ。”理解しやすいものでなければならない。さもないと、誰かが間違ったことをする可能性があって混乱するからだ。”ってスタンスだね。
Head-of-line blockingは、ssh3で完全に解決される可能性が高いよ。ssh3の1つの物理的な接続上で複数のポートや接続を多重化すれば、もっと速くなるはずだ。
ここで何かを”物理的”と呼ぶのは、僕には変だし紛らわしいな。まさかphysical layerのことじゃないよね?
なぜか通信プロトコルの文脈でそういう表現をよく見るんだ。たとえ誤用だと分かっていても、「非仮想化の」という意味で比較的はっきりしてるから使われてるんだと思う。例えばVRRPだと、みんなVIPじゃないアドレスを”物理IP”って言うよね。RFCでは”primary IP”って呼んでるのに。確かに”primary IP”の方がどっちを指してるのか紛らわしいかもしれないね、技術的には正確だけど。もちろん、誤用にならずに、もっと明確に全ての状況に当てはまる完璧な言葉が、単に僕が思いつかなかっただけなのかもしれないけどね :D。
接続設定時間は気にしたことないけど、ちょっと気になることはあったな。SSHでリモートコマンドを実行することもあるし。
もし同じホストに繰り返しコマンドを実行してるなら、SSHマルチプレキシングが役立つよ。SSHで入るとローカルのUnixドメインソケットが開いて、追加の接続は既存の接続を介して認証なしで使えるんだ。新しいTCP接続よりずっと速いよ。
なんでこのUDSを使うのがデフォルトじゃないの?どうやったら有効にできるの?
UDSがデフォルトじゃないのは、マルチユーザーシステムでは安全じゃないから。ローカルシステムのrootユーザーにリモートシステムへのアクセスを許しちゃうんだ。rootは君のUDSも読み書きできるしね。ユーザーとしては、許容できると思ったら明示的にオプトインする必要があるよ。
それが理由だとは思わないな。rootは理論的に何でもできるし、rootから守られてるものなんてほとんどないよ。rootは君のアカウントにsuして新しいSSH接続を作れるし、SSHコマンドを彼らの公開鍵をコピーしてからシェルを開くものに置き換えることもできるんだから。
OpenSSHのControlMaster、ControlPath、ControlPersistオプションについてドキュメントを見てみて。
もっとスムーズなUXが欲しいなら: https://mosh.org/
残念だけど、このプロジェクトはもう活動してないみたいだよ。
それでもまだすごくよく動くよ。何年も、いや何十年もアップデートされてないけど、素晴らしいソフトウェアはたくさんあるんだ。
それは死んだのか、それともただ成熟しただけなのか?
Moshはまだバグだらけでメンテナンスされてないみたいだね。後継プロジェクトもないし、例えばこのissueみたいに、問題が山積してるよ: https://github.com/mobile-shell/mosh/issues/1339。
uniwidth問題には、https://github.com/jdrouhard/mosh/ ってフォークがあるよ(もっと最適化できると思うけどね)。
MoshはFedoraとか主要なディストリビューションにも入ってるし、バグや悪用されるようなものだったらとっくに排除されてるはずだよ。
各ディストリビューションのパッケージメンテナーが、フォークでパッチを維持するのは自由だけど、その品質や寿命はアップストリームとの連携次第なんだよね。
Moshがメンテされてないってのは多分違うと思うよ。ディストリビューションが重要なパッチ、特にセキュリティ関連のものを自分たちだけで抱え込むわけないし、見捨てられたってのも誤解じゃないかな。
上の話は全部Moshプロジェクト本体のことで、個々のディストリビューションのパッケージとは別だよ。例えばmacOSで”brew install mosh”しても、Fedoraが適用したパッチなしの公式だけど3年前のリリースが手に入るし、GitHubから手動でダウンロードしても同じだよ。
GPLv3コードを”自分たちだけで抱え込む”のがどういう意味か100%は分からないけど、MoshのGitHubリンクを見れば、アップストリームプロジェクトは過去2.5年間コミットが一つもないのが分かるよ。
プロジェクトは死んでる。あとはあなたが使ってるバイナリにとって、それがどれくらい問題か、特定のダウンストリームパッケージを信用して検証するしかないんだ。一部のメンテナーはまだ気づいてないか気にしてないかもしれないし、一部は既知のCVEのセキュリティ修正しか提供しないかもしれない、あるいは完全にフォークを管理してるかもしれないね。平均的な読者は、Fedoraがまだダウンストリームバージョンをパッケージしてる(それが完全に違うかもしれないけど)ってことより、自分が使ってるバイナリがどうなってるかに注目すべきだよ。
SSH3って名前、俺も大嫌いなんだ。リポジトリのトップに「SSH3は多分名前を変えるよ。今もRFC4254のSSH接続プロトコルがHTTP/3 Extended connect上で動いてるけど、必要な変更が大きすぎて、人気のSSH実装に統合されるのは考えにくいからね。仕様ドラフトはもう”Remote Terminals over HTTP/3”に改名されたけど、いい永続的な名前を思いつくまでには時間がかかりそう」って書いてあってよかったよ。
HTTPSSH。QUICですでにできることに、HTTP/3レイヤーって何を追加してるの?
ほんとそれー!なんか「Windows 12」とか「Linux 7」って名前つける、適当なやつが作ったリポジトリって感じがするよね。