質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.61%

  • Node.js

    1806questions

    Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

  • Socket.IO

    187questions

    Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。

Socket.IOサーバーと外部のWebサーバーでSSL通信するには?

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 3,536

buibui80

score 943

Socket.IOサーバーとWebサーバーを2台のサーバーで個別に動作させているのですが、
Socket.IOサーバーとSSL通信する方法が分かりません。
構成は以下の通りです。

Socket.IOサーバー
 自宅PCにてSocket.IOサーバーを動作させています。
 サンプルによくあるWebサーバーとの組み合わせでなくSocket.IO単体で動作しています。

Webサーバー
 レンタルサーバー(ロリポップ)にてHTTPSでWebページを表示しています。
 Webページ内にSocket.IOサーバーに接続するコードが書かれています。

Webサーバー側がHTTPSで表示されていれば
Socket.IOサーバーは特に何もせずともSSL通信になるなら問題ないですが、
そうでない場合どのようにすればSocket.IOサーバーとSSL通信できるかご教授頂けないでしょうか?

SSLを使用しない場合に問題なく動作していることは確認しています。
どうぞ宜しくお願い致します。
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

WebSocketのセキュリティ面での質問かと思います。
WS(ws://)プロトコルでなく、WSS (wss:// WebSocket secure: WS over SSL/TLS)でコネクションを確立する。これはHTTPに対するHTTPSと同じです。WebSocketの接続を確立するまえにハンドシェイクが必要ですが、これはHTTPでハンドシェイクを行った場合であっても、 WSS、WS いずれのプロトコルも利用できるようです。

ただし、HTTPSでハンドシェイクを行った場合は、WSS(WebSocket secure)しか利用できません。セキュリティレベルの格下げができないためです。

最近のバージョンのsocket.ioではデフォルトでWSSを利用するようになっているようです。以前はセキュアオプション{secure: true}がありましたが廃止されています。

そのため、HTTPSでハンドシェイクを行う場合は下記でWSSを利用できます。

var socket = io.connect('//localhost');

// あるいは
var socket = io.connect('https://localhost');

▼参考
node.js, socket.io with SSL

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/12/31 15:12

    ご回答ありがとうございます!
    ・クライアント(Webページ)がHTTPの時、WSS、WSのどちらも利用できる。
    ・クライアント(Webページ)がHTTPSの時、WSSのみ利用できる。
    と理解しました。

    ということは、
    「WebページがHTTPSで表示されていればSocket.IOサーバーは特に何もせずともSSL通信になる」という認識は誤りで、
    WSSを使用するにはSocket.IOサーバ側での作業が必須となり、
    その作業が「Socket.IOサーバー起動時にSSL証明書を設定」ということで良いでしょうか?

    よろしくお願いいたします。

    キャンセル

  • 2015/12/31 21:11

    Socket.IOサーバー(自宅)、Webサーバー(ロリポッップ)という環境でのセキュアな接続という点が質問内容のポイントみたいですね。少し興味があって調べてみましたが、ここから先は私の推測も含みますので、その点ご了承ください。

    私の認識では以下のとおりです。

    ※SSLサーバ証明書の有無が、WebSocketプロトコルのセキュアな通信には関係ない。
     つまり、SSL証明書の鍵を利用してWebSocketのセキュアな通信を行うわけではない。
     ハンドシェイクがHTTPであってもWebSocket通信はセキュアになる。

    以下がその説明部分になります。

    1. WebSocketの接続の確立はクライアント(Webページに限らず)からのハンドシェイクで始まる

    Client Handshake Request==========
    GET /chat HTTP/1.1
    Host: example.com:8000
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    Sec-WebSocket-Version: 13
    ==============================


    2. WebSocket(socket.io)サーバからのレスポンスにはSec-WebSocket-Acceptという形でサーバ証明書によるところの鍵を載せてレスポンスを返す

    ※WebSocketサーバーはクライアントから送られてきたSec-WebSocket-Key(dGhlIHNhbXBsZSBub25jZQ==)と"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"(これはマジックナンバーらしい)を文字連結してSHA-1 hashを取り、base64 エンコーディングして Sec-WebSocket-Accept を生成する、らしいです。

    Server Handshake Response========
    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
    ==============================


    3. Sec-WebSocket-Acceptのキーを使い、WSSの暗号化通信を行う(下記参考リンクRFC6455 — The WebSocket Protocolの5からが詳しい感じ)
    ちなみに、WebSocketでのセキュアな接続は同一生成元を前提としている。WebSocketサーバは自分と異なる生成元からのリクエストには拒否すべき。


    ※ 以上から、buibui80さんのケースでは、WebSocket通信のセキュリティという観点だと、SSL証明書の有無よりも、Socket.IOサーバー(自宅)の 同一生成元ポリシーに、Webサーバー(ロリポップ)socket.ioクライアントからの接続を許可してあげることが必要になるかと思います。また、ハンドシェイクを確立する際(暗号化キーのやり取り)もHTTPSであれば、よりセキュリティは高いと言えます。


    詳しい内容はRFC6455のドキュメントを読み込んでもらった方が早いかもしれないです。

    //////////
    ▼参考
    ・RFC6455 — The WebSocket Protocolの日本語ドキュメントが存在しています
    http://www.hcn.zaq.ne.jp/___/WEB/RFC6455-ja.html#section-4.2.2

    ・Writing WebSocket servers こちらが分かりやすいです
    https://developer.mozilla.org/ja/docs/WebSockets-840092-dup/Writing_WebSocket_servers

    キャンセル

  • 2015/12/31 21:34

    あともう一つ、Webサーバー(ロリポップ)がどのような構成かわかりませんが、WebSocketの接続を確立するまで、こちらをsocket.ioサーバとして利用する方法もありそうですね。


    Socket.IOサーバー(自宅)

    ↓Socket.IOサーバはクライアントとしてHTTPSで接続しにいく

    Webサーバー(ロリポップ) ※Node.js + socket.ioとかでコネクション確立まで担う
    ==========
    Webサーバー(ロリポップ)

    ↓↑ WebSocketによるコネクション確立後はSocket.IOサーバが本来の役割を担う
       Socket.IOサーバはWebサーバと確立したコネクションを利用してデータを流す

    Socket.IOサーバー(自宅)

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.61%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Node.js

    1806questions

    Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

  • Socket.IO

    187questions

    Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。