Node-v0.12のTLSを256倍使いこなす方法
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

Node-v0.12のTLSを256倍使いこなす方法

  • 393 views
Uploaded on

new TLS feature in Node-v0.12

new TLS feature in Node-v0.12

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment

Views

Total Views
393
On Slideshare
316
From Embeds
77
Number of Embeds
2

Actions

Shares
Downloads
2
Comments
0
Likes
3

Embeds 77

https://twitter.com 72
http://nodejs.connpass.com 5

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Node-v0.12のTLSを 256倍使いこなす方法 大津 繁樹 (@jovi0608) 株式会社インターネットイニシアティブ(IIJ) 東京Node学園祭2014 2014年11月15日
  • 2. 自己紹介 • 名前: 大津 繁樹 • 所属: 株式会社インターネットイニシアティブ(IIJ) アプリケーション開発部 • Twitter: @jovi0608 • ブログ: ぼちぼち日記 http://d.hatena.ne.jp/jovi0608/ • GitHub: https://github.com/shigeki/ • 新技術の検証・評価を行ってます。 (Node.js, SPDY, HTTP/2,HTML5) • iij-http2の開発を通じてIETFのHTTP/2標準化作業に参画中 • Node-v0.11.x へのパッチ提出はわずか。でもほとんどTLS関連です。
  • 3. TLS (Transport Layer Security)の利用状況 TLS通信 認証、暗号化、 改ざん防止 図参照 https://plus.google.com/+IlyaGrigorik/posts/7VSuQ66qA3C GoogleによるChromeの統計調査 から、ここ2年間でhttpsサイトへ のナビゲーションは28%から58% に増加
  • 4. IAB(Internet Architecture Board)からインターネッ トの信頼性に関する声明 https://www.iab.org/2014/11/14/iab-statement-on-internet-confidentiality/ IABは、現在プロトコル設計者・開発者・運用者がインターネットトラフィックの 標準として暗号化を行うことが重要であると信じている。できる限り認証と共に暗 号を使うべきだが、認証なしの機密性を持つプロトコルでもRFC7258で記載された 「広範囲な盗聴行為」に対して有用となりえる。
  • 5. 発表内容 • NodeのTLSモジュール大改造 • TLSSocket • AES-NI • PFS (Perfect Forward Secrecy) • TLS False Start • TLS Ticket • OCSP Stapling • TLS Dynamic Record • SPDY, HTTP/2 • SPDYのメリットが一番よくわかるデモ Node-v0.12でTLSを使うために有用な情報をお伝えします。 (でも256個もないです) (注1: Node-v0.12はまだ未リリースですが、2014/11/10時点のv0.12ブランチHEADを対象としています。) (注2: Node-v0.11.xはまだPOODLE対策がされていません。SSLv3を無効化するために、 secureOptions: require(‘constants’).SSL_OP_NO_SSLv3) をサーバオプションに追加しましょう。)
  • 6. 目指せ A+ のTLSサーバ ソースはこちら https://gist.github.com/shigeki/986c53242f5bd3d78609 https://www.ssllabs.com/ssltest/index.html
  • 7. Node TLSモジュールの大改造 Node-v0.10の問題:パフォーマンスが悪い、API が扱いづらい • 受信した暗号文をnetモジュールで受けてから SecurePair オブジェクトで復号化 • 送信する平文もSecurePairオブジェクトで暗号 化してからnetモジュールで送信 • C++ → JS → C++ → JS のオーバヘッドが大きい • 平文のCleartextStreamはnet.Socketと似て非な るもの。 Node-v0.10のTLS処理概要 C++ JS C++ JS SecurePair openssl 暗号文 平文 平文 暗号文 暗号文 net module libuv CleartextStream CryptoStream
  • 8. Node TLSモジュールの大改造 C++C++ JS tls_wrap libuv openssl Node_BIO TLSSocket 平文 平文 暗号文 Node-v0.12のTLS処理概要 Node-v0.12でパフォーマンスを改善、APIを統一 • opensslとlibuvでデータと共有する Node_BIO を作成 → 両者の処理を一体化 • netモジュールのハンドルをtls_wrapが横取り → C++の処理だけで平文データを生成 • net.Socketを継承するTLSSocketを新設 → イン ターフェイスを統一 C++
  • 9. TLSSocket • Node-v0.10までの CleartextStream の替わり • CleartextStreamのAPIの互換保持 • ちゃんと net.Socketを継承し、APIを完備 • TLS周りの通信に関する新規機能のAPIを追加 より直観的でわかり易くなった。 EventEmitter Stream Readable Writable Duplex Socket TLSSocket
  • 10. AES-NI (Advanced Encryption Standard New Instructions) • Intel, AMDのCPUに搭載されているAES暗号の処理機能 • 最近のモデルには多く搭載されている。/proc/cpuinfo で確認 • openssl-1.0系に実装済。Node-v0.10.x, v0.11.xでも使える • 環境変数でAES-NIの有効・無効化してNodeのcryptoのベンチ比較 AES-NI有効時 AES-NI無効時 22.8469 Gbit/sec 9.51245 Gbit/sec AES-NI付きCPUのサーバを選んで使いましょう AES-NIで2.4倍に性能向上!
  • 11. PFS(Perfect Forward Secrecy) • セッション毎に一時的に有効な公開鍵を交換して暗号鍵を共有す る方式 • 証明書の秘密鍵が危殆化しても過去の通信データを復号化できな い。今後主流となる鍵交換方式。 • Node-v0.12から ECDHE, DHE の2種類が利用可能 • ECDHEの方が性能が良いのでそっちを優先指定(デフォルト) • ECDHEはデフォルトで何もせず利用できる。(prime256v1) • DHEの利用dhparamファイルを生成と指定が必要。現状十分な強 度を持つには2048bit長以上で生成すること。
  • 12. TLS False Start ClientHello ServerHello Certificate ServerHelloDone ServerKeyExchange ChangeCipherSpec Finished ハンドシェイク完了前に 暗号化したアプリデータ をフライングで送信 application data ClientKeyExchange ChangeCipherSpec Finished • TLS接続を高速化する技術 (2RTT→1RTT) • TLSハンドシェイク完了直前に暗号化したアプリケー ションデータをフライングで送信 • Chromeで2010年より先行実装、でも想定外の挙動の ため問題頻発。 • TLSハンドシェイク完了前なのでダウングレード攻撃の リスクもあり一旦中止。 • NPNでプロトコル指定、PFS利用で利用可能に。 • IEやSafariなどは別の条件。
  • 13. NodeでTLS False Startを使うには NodeはデフォルトでNPN拡張を付与するのでPFSを利用すればク ライアントはTLS False Startになる(*) PFS利用していない時(AES128-GCM-SHA256) PFS利用している時(ECDHE-RSA-AES128-SHA256) TLS False Start によ るTLSハンドシェイ クの高速化 1RTT分 (*) IE, Safariは条件が違います
  • 14. TLS Ticket • サーバからクライアントにTLS再接続時に利用する CipherSuite/MasterSecretが含まれた設定データ(チ ケット)を暗号化して渡す。 • 渡したチケット情報はサーバ側では保持しない。 • クライアントは再接続時にチケットをサーバに送信。 サーバはチケットデータを復号化し、中のTLS設定 情報を利用して通信を再開する。 • チケット鍵が複数のサーバ間で共有できていれば別 サーバに行っても大丈夫。(ただし鍵管理が大変) ClientHello Sesstion Ticket Ext ServerHello SessionTicket Ext Certificate ServerHelloDone ServerKeyExchange NewSessionTicket ChangeCipherSpec Finished ClientKeyExchange ChangeCipherSpec Finished
  • 15. NodeでTLS Ticketを使う • Node-v0.10で既に使えるが、単一プロセスのみ。 • Node-v0.12ではクラスタの複数プロセス間でチケット鍵が共有可 • Cluster でTLSを使っている方は、今すぐNode-v0.12へ Node-v0.10.33 のTLSクラスター Node-v0.12-pre のTLSクラスター
  • 16. OCSP Stapling • OCSP (Online Certificate Status Protocol): • 証明書が失効していないか確認するプロトコル • TLS初期接続時にクライアントが認証局サーバに確認。オーバヘッド • OCSP Stapling: • TLSサーバがOCSPレスポンスを証明書とともにクライアントに送信 • クライアントが認証局に確認する必要がない。Web表示の高速化 OCSP Response 証明書+OCSP Response ClientHello + status_request_v2 ext.
  • 17. NodeでOCSP Staplingを使う • Node-v0.12では OCSPRequest イベントを新設 • コールバックの引数にOCSPレスポンスデータ を渡し、クライアントに送信 • 認証局のOCSPサーバにリクエストするのは結 構面倒なので、opensslで事前にリクエスト データを作成すると良い • OSCPレスポンスデータのキャッシュ管理も必 要。更新日時を取得するasn.1パーサも必要。 エラー時の処理判断も大切。 • 別途cronでOCSPレスポンスデータを管理する 手もある server.on('OCSPRequest', function(cert, issuer, cb) { var now = Date.now(); if (now > cache.nextUpdate && !cache.lock) { cache.lock = true; cache.der = null; HandleOCSPrequest(cb); } else { var msg = cache.der ? 'cache hit!': 'terminated'; console.log( 'OCSP Response:', msg); cb(null, cache.der); } }); ソースは、https://gist.github.com/shigeki/de5748cc0deb980bcb35 結果は openssl s_client –status –connect site:443 で確認
  • 18. Dynamic TLS record (setMaxSendFragment) • GoogleのIlya Grigorik氏が推奨しているTLSパラメータのチューニング手法 • 通常TLSに書き込まれるデータ長は、レコードサイズ最大の16Kであることが多い。 • 最初のレスポンスデータの取得は、16Kバイトを受信してからになる。 • 最初のデータを復号化するには10個のTCPパケット(1.5K)を受信が必要。 • TLSのレコードサイズをTCPの1セグメントのサイズに収まるように小さくすれば受信した1個目か らデータの復号化が可能になる。 • よって受信したデータの1バイト目が表示される時間の短縮が図られる。 1.5K 1.5K 16K これ一つで 復号可能よ 16K全部受信しな いと復号できない
  • 19. NodeでTLS Dynamic Recordをやるには • Googleサーバでのチューニング方法(ATSで採用済) • 最初は 1.3Kのレコードサイズ (1500 - 40 (IP) - 20 (TCP) - 40 (TCP options) - TLS overhead (60-100)) • 1Mバイト送信したらデフォルトの16Kに変更。 • 書き込みのアイドルが1秒以上になったら1.3Kに戻す。 • Nodeでは自動的にレコードサイズをチューニングする方法は不採用に • 替わりに固定的に変更するAPI(setMaxSendFragment)を新設 • 1.3Kで固定すると大きいデータで分割オーバヘッドが高くなる可能性も。 server.on('secureConnection', function(tlsSocket) { tlsSocket.setMaxSendFragment(1300); });
  • 20. 小さいTLS Record Sizeの効果(rtt=1000msec時) MaxSendFragment 16K default MaxSendFragment 1.3K Time To First Byte の高速化 requestStart responseStart responseStartrequestStart
  • 21. SPDY, HTTP/2 • SPDY • Googleが開発したWebの表示を高速化するプロトコル(TLSのみ) • Google/Twitter/Facebook/Yahoo.comで使用中 • Chrome/Firefox/IE10/Safari 多数のブラウザでサポート中 • Nodeで使うなら node-spdy を使いましょう • HTTP/2 • SPDYをベースとした次期HTTP仕様(TLS利用が中心) • HTTP/1.1のセマンティクスを互換保持 • 現在仕様化作業の大詰め。来年前半には完了予定 • 現在Firefoxとのテストで利用中のnode-http2が使える • 注意事項: • node-v0.10で利用するとTLS要求仕様(AEAD+PFS)が合わず接続できない場合があります。node-v0.12を使いま しょう。 • ただ開発は0.10系でやっているので未サポート • ALPNはまだopensslのベータなためnodeでは使えません。 • 使う場合には私のfork版があります。 https://github.com/shigeki/node/tree/alpn_support Ethernet IP(v4/v6) TCP TLS HTTP/2 Frame Layer HTTP/1.1 Semantics
  • 22. クライアント サーバ 1つの TCP接続 ストリーム(id:1) フレーム フレーム ストリーム(id:3) フレーム フレーム ストリーム(id:5) フレーム フレーム HTTP リクエスト レスポンス HTTP リクエスト レスポンス HTTP リクエスト レスポンス SPDY, HTTP/2の全二重多重化通信 仮想的なストリームチャンネルを生成して多重化を実現
  • 23. HTTP Head of Line Blockingを回避 HTTP/2クライアント 画像サーバA 画像サーバB Reverse Proxy HTTP/2 多重化通信 レスポンス が速い レスポンスが 遅い HTTP/1.1クライアント TCPを6本張れるけど、1本中 に同時1リクエストの制限 1本のTCP
  • 24. SPDYのメリットが一番よくわかるデモ 多数の画像を表示して見え方に違いがあるのか? (SPDY vs HTTP/1.1) 1. 少数画像 vs 多数画像。 2. 3枚目の画像毎に3秒のレスポンス遅延を入れる。
  • 25. まとめ Node-v0.12でTLS通信を最適化する方法はいろいろあります。 用法用量を守って正しくお使いください。 (special thanks to http://www.irasutoya.com/)