Open6

[WIP] QUIC-based UDP Transport for SSH雑まとめ

Yusuke SasakiYusuke Sasaki

免責事項

  • 本スクラップは該当トピックに対する筆者の技術的興味をまとめたものであり、その内容に正確性は保証されません

参考文献

Yusuke SasakiYusuke Sasaki

QUICハンドシェイクを直接用いない理由(推測)

SSHの公開鍵認証[1]では、クライアントは次のようなデータを自身の持つ秘密鍵を用いて署名し、サーバ側はそのsignatureを対応する公開鍵を用いて検証することでユーザ認証を実行する[2]

string    session identifier
byte      SSH_MSG_USERAUTH_REQUEST
string    user name
string    service name
string    "publickey"
boolean   TRUE
string    public key algorithm name
string    public key to be used for authentication

ここで session identifier と記載されている値はSSHコネクション毎に割り当てられる固有の識別子であり、初回の鍵交換時に求められる交換ハッシュの値が用いられる。この値は (EC)DH鍵共有によって導出された共有秘密(shared secret)から計算されるものであり[3]、通信路上に流れることのないクライアントとサーバのみが知り得る情報のひとつである。この値を署名するデータに含ませることでリプレイ攻撃への対策をすることが出来る。

(疑問: 通信路の暗号化が有効なのであればリプレイ攻撃すること自体が困難なのでは?) ※中間者攻撃

このsession identifierに相当する値がQUIC(あるいはその背後にあるTLS)のハンドシェイクで得ることが出来ないので鍵交換部分をSSHチックに行ってしまおうという考えかたっぽい…?

脚注
  1. https://tools.ietf.org/html/rfc4252#section-7 ↩︎

  2. サーバは署名を検証する前に、送られてきた公開鍵が受容できるものかどうか (例えばauthorized_keysに記載されているかなど)を確認する必要がある ↩︎

  3. 鍵交換で送受信したパケットのペイロードなどをshared secretと結合し、それらのハッシュを計算することで求められる ↩︎

flano_yukiflano_yuki

素晴らしいまとめありがとうございます!!

僕自身、SSHについては全然詳しくなくて恐縮ではありますが、著者の方に聞いてみたところ
「For the protocol to be widely used, existing SSH host key trust relationships have to work as currently configured. 」というふうに述べてました。さらに、TLSハンドシェイクに手を入れるよりかは、本仕様のように専用の仕組みのほうがクリーンとのことです。

Yusuke SasakiYusuke Sasaki

情報ありがとうございます。僕もSSHについては勉強し始めで正直自身がないので、今後地道に調査しつつ更新していけたらなぁと考えています…

TLS側を弄る方向にしなかったのはなぜなのかというのはちょうど疑問に思っていたところでした。なるほど確かに運用側や既存のSSH実装の移行コストを最小限に抑えたいというのは大事ですね。

Yusuke SasakiYusuke Sasaki

トランスポート以外のSSHプロトコルについて

  • Authentication Protocol[1]は確立されたQUICコネクションのStream 0で実行される
    • このときsession identifierの値が必要になることは先述の通り
  • Connection Protocol[2]はQUICのストリーム多重化を使用するよう修正される
    • チャンネルIDの割り当てやSSH_MSG_CHANNEL_CLOSEなど一部のメッセージの廃止など
脚注
  1. https://tools.ietf.org/html/rfc4252 ↩︎

  2. https://tools.ietf.org/html/rfc4254 ↩︎