SSL TLSセッションチケット
SSL TLSセッションチケット(TLS session ticket) とは、セッションリサンプションの実装の1つで、ハンドシェイクの負荷を下げます。サーバ側でセッションステートを管理する必要がありませんが、複数のサーバで運営している場合には、鍵を管理しなければなりません。
読み方
- SSL TLSセッションチケット
- えすえすえる てぃーえるえす せっしょんちけっと
目次
概要
SSLとセッションリサンプションを簡単に説明します。
- SSL通信では、サーバとクライアントの間で、SSLのハンドシェイクを行い、暗号化に必要な通信を行います。
- 暗号通信をするための前処理は、CPUやネットワークに負荷を与えます。
- SSLハンドシェイクが完了した時に、次回以降はそのセッションを使いまわすことで、ハンドシェイクを省略します。これは、SSLセッションキャッシュです。このとき、セッションIDを発行します。
- SSLセッションキャッシュは、サーバ側でセッションIDのステートを管理する必要があります。
- ステートをクライアントに渡すSSLセッションチケットは、サーバ側でセッションのステートを管理する必要はありません。
- 複数のサーバがある場合は、SSLセッションチケットを発行するための鍵をサーバ間で共有していれば、複数のサーバで構成される環境においても利用できます。
セッションリサンプション
セッションリサンプションは、新規接続のハンドシェイクを短縮するための仕組みです。 実装には、以下の方法があります。
- セッションID
- セッションチケット
セッションID
セッションIDを使用する場合、サーバは、ステートを保持しなければなりません。 クライアントは、サーバから受信したセッションIDを再接続時に送信し、対応するステートを再利用します。
セッションチケット
SSLセッションチケットは、サーバ側で、セッションのステートを管理する必要がありません。セッションステートは、サーバで暗号化し、セッションチケットとしてクライアントに送信します。
セッションチケットの暗号化に使用した鍵は、サーバ側で管理しなければなりません。
セッションチケットに対応しているサイト
以下の例から、TLS session ticket(TLSセッションチケット)が渡されているのがわかります。
$ openssl s_client -connect www.google.com:443 -tls1 CONNECTED(00000003) depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA verify error:num=20:unable to get local issuer certificate verify return:0 --- Certificate chain 0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=www.google.com i:/C=US/O=Google Inc/CN=Google Internet Authority G2 1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2 i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA 2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority --- Server certificate -----BEGIN CERTIFICATE----- 省略 -----END CERTIFICATE----- subject=/C=US/ST=California/L=Mountain View/O=Google Inc/CN=www.google.com issuer=/C=US/O=Google Inc/CN=Google Internet Authority G2 --- No client certificate CA names sent --- SSL handshake has read 3713 bytes and written 338 bytes --- New, TLSv1/SSLv3, Cipher is ECDHE-RSA-RC4-SHA Server public key is 2048 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE SSL-Session: Protocol : TLSv1 Cipher : ECDHE-RSA-RC4-SHA Session-ID: E360BCED9C9B884D9C3253A1D8C664841A69245FE07E65DF4C94658FA633A74A Session-ID-ctx: Master-Key: 23038F705404F29C7071B07EC8805730EC849578F194FA01 F865612E12A7279D9443B70A9B236B4BCBAD13D104A4C49B Key-Arg : None PSK identity: None PSK identity hint: None SRP username: None TLS session ticket lifetime hint: 100800 (seconds) TLS session ticket: 0000 - dd e7 f8 d6 5c 6d 5c e8-fd 00 06 9c e6 2c 4d cb ....\m\......,M. 0010 - af 18 24 31 ba ac 25 e5-27 25 05 03 c2 db db fe ..$1..%.'%...... 0020 - cb dc 84 8b e2 19 84 2f-18 21 7d 2e 02 08 bc 9e ......./.!}..... 0030 - cc 71 c2 b5 fc 44 96 40-1e b5 64 e7 8e 53 5e 6e .q...D.@..d..S^n 0040 - da 03 6d b5 c1 68 76 da-20 a4 45 af ec 7d 81 fc ..m..hv. .E..}.. 0050 - a9 3d f2 f3 75 48 d1 46-19 59 54 41 26 8d cd 02 .=..uH.F.YTA&... 0060 - 3e 75 eb 27 17 0a e8 06-c4 9e bc f1 2d 8e 0c 01 >u.'........-... 0070 - 3f 4c 65 46 69 d8 a1 01-f8 5d ac 04 40 4a 37 25 ?LeFi....]..@J7% 0080 - ea 15 93 94 30 b7 e2 48-a3 f1 ea 32 99 d6 a1 52 ....0..H...2...R 0090 - 1b 70 a6 2f 1c d5 0c c9-16 ae ab d0 82 f8 49 8c .p./..........I. 00a0 - 97 c2 21 96 ..!. Start Time: 1423323894 Timeout : 7200 (sec) Verify return code: 20 (unable to get local issuer certificate)
セッションがreuseできるか確認する方法
OpenSSLコマンド reconnect を使用して、調べてみました。 2回目以降は、セッションを使いまわしていることがわかります。
$ openssl s_client -reconnect -host www.google.com -port 443 \ |grep -e "\(Reuse\|New\)" depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA verify error:num=20:unable to get local issuer certificate verify return:0 New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256 Reused, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256 Reused, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256 Reused, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256 Reused, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256 Reused, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
こちらの例では、毎回、新しいチケットになっているようです。
$ openssl s_client -reconnect -host login.yahoo.co.jp -port 443 \ 2>&/dev/null |grep -e "\(Reuse\|New\)" New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256 New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256 New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256 New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256 New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256 New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
何度もやっていると、時々、同じサーバに接続されるのか、Reusedされることがあります。
$ openssl s_client -reconnect -host login.yahoo.co.jp -port 443 \ 2>&/dev/null |grep -e "\(Reuse\|New\)" New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256 New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256 New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256 Reused, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256 Reused, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256 New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
node.jsのTLSサーバのセッションチケット
- Node v0.10では、単一プロセスのみのサポートでした。
- Node v0.12では、クラスタの複数のプロセス間で鍵を共有可能です。
node.jsのTLSサーバの実装の例
/* * https_ssl_session_ticket.js * Copyright (C) 2015 kaoru <kaoru@bsd> */ var https = require('tls'); var fs = require('fs'); var ssl_server_key = 'server_key.pem'; var ssl_server_crt = 'server_crt.pem'; var port = 8443; var options = { key: fs.readFileSync(ssl_server_key), cert: fs.readFileSync(ssl_server_crt) }; var tls = https.createServer(options, function (socket) { socket.write("Hello, world\n"); }).listen(port);
このように、Reused となっています。
$ openssl s_client -reconnect -host localhost -port 8443 |grep -e "\(Reuse\|New\)" depth=0 C = JP, ST = Tokyo, L = Musashino-shi, O = Foo, OU = Bar, CN = foo.bar.com verify error:num=18:self signed certificate verify return:1 depth=0 C = JP, ST = Tokyo, L = Musashino-shi, O = Foo, OU = Bar, CN = foo.bar.com verify return:1 New, TLSv1/SSLv3, Cipher is AES256-GCM-SHA384 Reused, TLSv1/SSLv3, Cipher is AES256-GCM-SHA384 Reused, TLSv1/SSLv3, Cipher is AES256-GCM-SHA384 Reused, TLSv1/SSLv3, Cipher is AES256-GCM-SHA384 Reused, TLSv1/SSLv3, Cipher is AES256-GCM-SHA384 Reused, TLSv1/SSLv3, Cipher is AES256-GCM-SHA384
Apache TrafficServer(ATS)
Apache TrafficServerは、TLSセッションチケットに対応しています。ATSクラスタを通して、TLSセッションチケットをサポートしています。 ssl_multicert.configに設定します。
ssl_ticket_enabled=1|0 ticket_key_name=<filename>
関連項目
ツイート