Advertisement
Advertisement

More Related Content

Similar to Node-v0.12のTLSを256倍使いこなす方法(20)

Advertisement
Advertisement

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

  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/)
Advertisement