Socket.IO の HTTP リクエストで、URI スキーマとして HTTPS が socket.io-spec で推奨されている理由はなんでしょうか

372 views
Skip to first unread message

mori dev

unread,
Dec 7, 2013, 9:48:44 AM12/7/13
to node...@googlegroups.com
はじめまして。
ハンドルネーム mori-dev と申します。Node 歴は 3週間ほどです。

Socket.IO の HTTP リクエストで、URI スキーマとして HTTPS が socket.io-spec で推奨されている理由はなんでしょうか。

socket.io-spec ( https://github.com/LearnBoost/socket.io-spec#uri-scheme ) というページで、Socket.IO の HTTP リクエストで、URI スキーマとして HTTPS が socket.io-spec で推奨されています。

    URI scheme
       The URI scheme is decided based on whether the client requires a secure
       connection or not. Defaults to http, but https is the recommended one.

この根拠は何でしょうか。とくにふかよみするようなところではなく、本文から読み取れるとおり、通信が暗号化されていて HTTP よりセキュアだから、ということでしょうか。
publich key の 「SPDYやQUIC登場の背景。Webの進化がプロトコルを変えつつある。HTML5 Conference 2013 ( http://www.publickey1.jp/blog/13/spdyquicwebtcphtml5_conference_2013.html )」という記事には「HTTPSではTCPコネクションを複数張っているので、1つが欠損してもほかのTCPコネクションは関係なくデータを送れます。」とあります。これも推奨する根拠と関係があるのでしょうか。

Socket.IO の v0.9.16 を、xhr-polling, jsonp-polling で利用する予定で、調査していて、疑問に思い、質問しました。
たとえば、以下のような http リクエストではなく

   http://localhost:8081/socket.io/1/xhr-polling/sIp1vNChR6RLWu74equ1?t=1386426845697

https モジュールを使った結果に対し、socket モジュールを使い、

   https://localhost:8081/socket.io/1/xhr-polling/sIp1vNChR6RLWu74equ1?t=1386426845697

といったふうにするのが推奨されているようだ、という認識です。


関連リンク

  * https://github.com/LearnBoost/socket.io-spec#uri-scheme
  * https://github.com/Jxck/socket.io-spec#uri-%E3%82%B9%E3%82%AD%E3%83%BC%E3%83%9E

Koichi Kobayashi

unread,
Dec 7, 2013, 11:00:00 AM12/7/13
to node...@googlegroups.com
小林 (koichik) です。

トランスポートの一つであるWebSocketは、最初HTTP(S)で
接続してからUpgrade:によってプロトコルを変更します。
しかしHTTPだと、途中のProxyなどによってはUpgrade: が
通らなかったりするかもしれません。

HTTPSにすれば、途中のProxyなどでは通信の中身が
見えないため、トラブルが少なくなると期待して
推奨しているのかなと推測してみました。

もっとも、AWSのELBのようにSSLターミネータな
ところで弾かれるケースもあるわけですが。。。

この理由はトランスポートにXHR等を使う場合は
関係なさげですね。

Socket.IOの中の人の意図はわかりませんが、
可能性の一つということで。


On Sat, 7 Dec 2013 23:48:44 +0900, mori dev <mori.d...@gmail.com> wrote:

> はじめまして。
> ハンドルネーム mori-dev と申します。Node 歴は 3週間ほどです。
>
> Socket.IO の HTTP リクエストで、URI スキーマとして HTTPS が socket.io-spec
> で推奨されている理由はなんでしょうか。
>
> socket.io-spec ( https://github.com/LearnBoost/socket.io-spec#uri-scheme )
> というページで、Socket.IO の HTTP リクエストで、URI スキーマとして HTTPS が socket.io-spec
> で推奨されています。
>
> URI scheme
> The URI scheme is decided based on whether the client requires a
> secure
> connection or not. Defaults to http, but https is the recommended
> one.
>
> この根拠は何でしょうか。とくにふかよみするようなところではなく、本文から読み取れるとおり、通信が暗号化されていて HTTP
> よりセキュアだから、ということでしょうか。
> publich key の 「SPDYやQUIC登場の背景。Webの進化がプロトコルを変えつつある。HTML5 Conference 2013 (
> http://www.publickey1.jp/blog/13/spdyquicwebtcphtml5_conference_2013.html)」という記事には「HTTPSではTCPコネクションを複数張っているので、1つが欠損してもほかのTCPコネクションは関係なくデータを送れます。」とあります。これも推奨する根拠と関係があるのでしょうか。
>
> Socket.IO の v0.9.16 を、xhr-polling, jsonp-polling
> で利用する予定で、調査していて、疑問に思い、質問しました。
> たとえば、以下のような http リクエストではなく
>
>
> http://localhost:8081/socket.io/1/xhr-polling/sIp1vNChR6RLWu74equ1?t=1386426845697
>
> https モジュールを使った結果に対し、socket モジュールを使い、
>
>
> https://localhost:8081/socket.io/1/xhr-polling/sIp1vNChR6RLWu74equ1?t=1386426845697
>
> といったふうにするのが推奨されているようだ、という認識です。
>
>
> 関連リンク
>
> * https://github.com/LearnBoost/socket.io-spec#uri-scheme
> *
> https://github.com/Jxck/socket.io-spec#uri-%E3%82%B9%E3%82%AD%E3%83%BC%E3%83%9E
>
> --
>
> ---
> このメールは Google グループのグループ「Node.js 日本ユーザグループ」の登録者に送られています。
> このグループから退会し、メールの受信を停止するには、nodejs_jp+...@googlegroups.com にメールを送信します。
> その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。


--
{
name: "Koichi Kobayashi",
mail: "koi...@improvement.jp",
blog: "http://d.hatena.ne.jp/koichik/",
twitter: "@koichik"
}

mori dev

unread,
Dec 7, 2013, 8:57:19 PM12/7/13
to node...@googlegroups.com
小林 (koichik) さん、
森(mori_dev) です。

HTTPだと、途中のProxyなどによってはUpgrade: が通らない可能性があるため、
HTTPを推奨しているのかもしれない。だから、xhr-polling で使う場合、WebSocket への
Upgrade: 処理は行わないのだし、HTTP でよさそうだとのこと。

わかりました。ありがとうございました。

私の方でさらに調べたところ、 RFC6455 WebSocket ( http://tools.ietf.org/html/rfc6455 )
に、ハンドシェイク時の仕様で、以下のような関係がありそうな記述をみつけたのですが、

    4.2.2. Sending the Server's Opening Handshake


       When a client establishes a WebSocket connection to a server, the
       server MUST complete the following steps to accept the connection and
       send the server's opening handshake.

       1.  If the connection is happening on an HTTPS (HTTP-over-TLS) port,
           perform a TLS handshake over the connection.  If this fails
           (e.g., the client indicated a host name in the extended client
           hello "server_name" extension that the server does not host),
           then close the connection; otherwise, all further communication
           for the connection (including the server's handshake) MUST run
           through the encrypted tunnel [RFC5246].

"otherwise, all further communicatio for the connection (including the server's handshake) MUST run
through the encrypted tunnel [RFC5246]." だと何か困るのか?だから HTTPS 推奨なのか、
といったところまではたどり着きませんでした。

socket-spec を書いた人が HTTPS を推奨する理由を説明している資料を見つけたら、
この ML で報告しようと思います。

ありがとうございました。



2013年12月8日 1:00 Koichi Kobayashi <koi...@improvement.jp>:

Shigeki Ohtsu

unread,
Dec 8, 2013, 8:34:19 PM12/8/13
to node...@googlegroups.com
大津です。

もう一つ SSL が推奨されている可能性としては、歴史的な経緯もあるのもしれません。

これ書かれたのが commit ログの日付を見ると 2011-03-15 です。 2010年の11月末に
WebSocket draft76 の脆弱性が報告され、当時 FirefoxやOperaなどが default で
WebSocket を無効化し、Chromeなどはそのまま使えるような状況だったと思います。

SSLを利用すればキャッシュ汚染の脆弱性は回避できるので、当時 draft76 のWebSocket
が利用されることが念頭にあって推奨と書かれてたのかもしれません。(あくまで可能性ですけど)

その後 2011の7月にデータをマスクして脆弱性対応したWebSocket仕様が出て、今の RFC6455 に
なっているので現在は問題ないのですが、koichik さんの返事にあるよう Upgrade の問題
もあり、特に修正されずそのままになっているのではないかと思います。
(単に気づかず放置されているだけかも)

> "otherwise, all further communicatio for the connection (including the server's handshake) MUST run
> through the encrypted tunnel [RFC5246]." だと何か困るのか?だから HTTPS 推奨なのか、

この部分は、

「TLSハンドシェイクに失敗したら接続を切りなさい、そうでなければ引き続き暗号化通信上で
WebSocketのハンドシェイク を含む全ての通信を継続しなさい。」

ということを書いてあります。「otherwise:そうでなければ」は、TLSのハンドシェイクに
成功して暗号化通信が行える状況を指しているので、それに続くWebSocketが非暗号化であ
ると困るでしょう、だから(先のTLSハンドシェイクで確立した)暗号化通信を継続して使
いなさい(MUST)というこです。

WebSocketのHTTPS利用を推奨しているわけではないです。
> 2013年12月8日 1:00 Koichi Kobayashi <koi...@improvement.jp <mailto:koi...@improvement.jp>>:
> <mailto:nodejs_jp%2Bunsu...@googlegroups.com> にメールを送信します。
> > その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。
>
>
> --
> {
> name: "Koichi Kobayashi",
> mail: "koi...@improvement.jp <mailto:koi...@improvement.jp>",
> blog: "http://d.hatena.ne.jp/koichik/",
> twitter: "@koichik"
> }
>
> --
>
> ---
> このメールは Google グループのグループ「Node.js 日本ユーザグループ」の登録者に送られています。
> このグループから退会し、メールの受信を停止するには、nodejs_jp+...@googlegroups.com <mailto:nodejs_jp%2Bunsu...@googlegroups.com>

mori dev

unread,
Dec 8, 2013, 10:06:57 PM12/8/13
to node...@googlegroups.com
大津さん
森です。

ご回答ありがとうございます。
調べるなかで、文書の作成/更新日時までは確認しておりませんでした。。
歴史的な経緯を把握しました。
それから、RFC6455 の私が引用した部分の解説も、ありがとうございました。



2013年12月9日 10:34 Shigeki Ohtsu <oh...@iij.ad.jp>:

Jxck

unread,
Dec 8, 2013, 10:38:37 PM12/8/13
to node...@googlegroups.com
Jxck です。


(この投稿は、昨日の夜中(AM1 or 2)くらいに投稿したつもりだったんですが、操作ミスで mori-dev さんに直で送られていたことを mori-dev さんが教えてくれたので、そのまま再掲します。)


多分 koichik さんの読みであってると思います。
というのも、 socket.io はかなり前ですが、 FW 周りの疎通テストをやっています。
結果はこちら。

https://github.com/LearnBoost/socket.io/wiki/Socket.IO-and-firewall-software

"Some networks also interrupt WebSocket traffic over port 80 -- we've found several schools (even ones that don't filter Facebook) having trouble with WebSockets. Moving WebSocket traffic to port 443 (with and without SSL) fixed the problem."

とあるので、やはり 443 ポートが空いてることが多く、そこが都合良く通るようです。
しかし、 with and without ssl なので、 443 を平文で通しても大丈夫そうという意味では、暗号化云々よりは単にそのポートである意味があるみたいですね。(で、 HTTPS は普通 443 なので、 HTTPS 推奨という意味かと)

ちなみにですが。


> publich key の 「SPDYやQUIC登場の背景。Webの進化がプロトコルを変えつつある。HTML5 Conference 2013 (
http://www.publickey1.jp/blog/13/spdyquicwebtcphtml5_conference_2013.html)」という記事には「HTTPSではTCPコネクションを複数張っているので、1つが欠損してもほかのTCPコネクションは関係なくデータを送れます。」とあります。これも推奨する根拠と関係があるのでしょうか。

これは、今回の件とは本質的には関係ないです。
上記の話は、 SPDY が単一の TCP コネクションで全てをまかなおうとしているのに対し、通常の HTTP と HTTPS では、ブラウザが同時に 6 本まで TCP コネクションを張るという違いのことです。
SPDY は、 1 本なのでそこが詰まったり切れたりしたら影響がでかいですが、 HTTP / HTTPS ではあと 5 本あるよという話で、ここで 「HTTPS では」と言っているのは、「接続が 6 本」という意味で、「暗号化されている」は直接関係ありません。


一方で、 SPDY が SSL 選ぶ理由の 1 つに、暗号化してしまうことで Intermediaries (間にある FW など) が変にパケットをいじったり落としたりしないようにするというのはあり、これは koichik さんが言っている upgrade 通らない問題の解決と通じています。(それは上とは関係ない点で、若干話がややこしいですが。)

暗号化しちゃえば途中のだれもが中見れないから便利だよね(開発者はw) という発想は、新しいプロトコルを通す(通したい開発者)場合の上等手段なので、
その意味でも HTTPS にしてしまうのは、暗号化のコストと origin が変わったりという部分が許容できるなら安全なので、いいと思います。
(そうでなくても、 SSL なしで許されるのは個人が趣味でやってるサイトまでだよねーー、と個人的には思っていたりします。し、たぶん徐々にそうなっていくと思ってます。SPDY 関係なく。)


まとめると

- 443 は暗号化してもしてなくても通りやすいらしい
- 暗号化してるとなおのこと通りやすい
- (暗号化必須だろ JK)

なので、 HTTPS を推奨という意味かと。

Jxck
>      > このグループから退会し、メールの受信を停止するには、nodejs_jp+unsubscribe@googlegroups.com
>     <mailto:nodejs_jp%2Bunsu...@googlegroups.com> にメールを送信します。
>      > その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。
>
>
>     --
>     {
>        name: "Koichi Kobayashi",
>        mail: "koi...@improvement.jp <mailto:koi...@improvement.jp>",
>        blog: "http://d.hatena.ne.jp/koichik/",
>        twitter: "@koichik"
>     }
>
>     --
>
>     ---
>     このメールは Google グループのグループ「Node.js 日本ユーザグループ」の登録者に送られています。
>     このグループから退会し、メールの受信を停止するには、nodejs_jp+unsubscribe@googlegroups.com <mailto:nodejs_jp%2Bunsu...@googlegroups.com>
>     にメールを送信します。
>     その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。
>
>
> --
>
> ---
> このメールは Google グループのグループ「Node.js 日本ユーザグループ」の登録者に送られています。
> このグループから退会し、メールの受信を停止するには、nodejs_jp+unsubscribe@googlegroups.com にメールを送信します。

> その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。

--

---
このメールは Google グループのグループ「Node.js 日本ユーザグループ」の登録者に送られています。
このグループから退会し、メールの受信を停止するには、nodejs_jp+unsubscribe@googlegroups.com にメールを送信します。
その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。

mori dev

unread,
Dec 8, 2013, 10:56:11 PM12/8/13
to node...@googlegroups.com
Jxck さん、
森です。

ご回答、ありがとうございます。
はっきりと疑問を解消することができました。
Socket.IO and firewall software( https://github.com/LearnBoost/socket.io/wiki/Socket.IO-and-firewall-software )
へのリンク、SPDY に関連した補足も役立ちました。
ありがとうございました。



2013年12月9日 12:38 Jxck <block.rxc...@gmail.com>:
このグループから退会し、メールの受信を停止するには、nodejs_jp+...@googlegroups.com にメールを送信します。
その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。

Reply all
Reply to author
Forward
0 new messages