この記事は 慶應義塾大学SFC村井&徳田研 Advent Calendar 2015 の6日目の記事です。
2日前に無料TLS証明書プロジェクトの Let's Encrypt がパブリックベータに移行し、独自ドメイン所有者であれば自由に利用できるようになりました。
個人WEBサイトのhttps化に励んでおられる方も多いと思いますが、同時にWebSocketのwss化も行っちゃいましょう。
Let's Encryptの導入
Let's Encrypt の使い方(日本語) に従って作業すれば、簡単に導入できます。
なお、私のさくらVPS環境ではletsencryptクライアントの初回実行時に証明書サーバーにアクセスできない旨のエラーが出ましたが、再度実行すると特に問題なく証明書が作成されました。
今回の記事では触れませんが、Apache環境のhttps化は、以下の記事が参考になります。
無料SSL証明書の Let's Encrypt が公開されたので実際に試してみた
これで、念願のTLS証明書を個人サーバーに導入し、https通信を実現することが出来ました
しかし、https環境下では暗号化されていないWebSocketが使えなくなります。こちらも暗号化しましょう。
Wss通信 (Node.js Ws)
wssとは、暗号化されたWebSocket通信のためのURIスキームです。
今回は websocket.io ではなく ws (以下、node-ws)を用いてwss通信をしてみます。
通常のnode-wsでは、var wss = new ws.Server({ port: 8080 });
等でWebSocketサーバーを立てられますが、WSSサーバーの場合は一旦httpsサーバーを作成してから立ち上げます。
import https = require("https");
import fs = require("fs");
import ws = require("ws");
// 中略
let app = https.createServer({
key: fs.readFileSync("/etc/letsencrypt/live/example.com/privkey.pem"),
cert: fs.readFileSync("/etc/letsencrypt/live/example.com/cert.pem")
}, (req, res) => {
// ダミーリクエスト処理
res.writeHead(200);
res.end("All glory to WebSockets!\n");
}).listen(8080);
let wss = new ws.Server({ server: <any>app });
クライアント側は、今までのws://
をwss://
に書き換えるだけです。
var ws = new WebSocket("wss://example.com:8080");
ws.open = function() {
console.log("open");
ws.send("hello wss!");
ws.close();
}
サンプルコードの全文は github に掲載しています。
seibe/typescript-wss-sample
終わりに
Let's Encryptは単なるドメイン認証であり、実在証明ではないため、なりすましや通信傍受・改竄に対して絶対に安全というわけではありません。
あくまで「通信が暗号化されている」だけという認識であるべきだと思います。
とはいえ、ChromeがgetUserMediaをhttp環境で無効化する等、徐々に増えている暗号化が必須の流れに対しては非常に有効です。
ぜひとも積極的に使っていきましょー。