こういう仕組みですよ、というWeb上の記事を読んだだけでは納得できない!論より証拠だ!ということで論より証拠ツールその2であるtsharkを使ってTLS Session Ticketの動作を「なんとなく」覗いてみる。
ちなみに、クライアントは Google Chrome (49.0.2576.0 canary (64-bit)) 、サーバはh2o (1.6.0-beta1, LibreSSL 2.2.4) である。
まずはざっくり
sudo tshark -i eth0 -f "tcp port 443" -Y ssl
状態をクリアするためにh2oを再起動してからhttpsなリクエストを送ると以下の様なシーケンスになる。
4 0.013439 xxx.xxx.xxx.xxx -> yyy.yyy.yyy.yyy SSL 583 Client Hello
6 0.018197 yyy.yyy.yyy.yyy -> xxx.xxx.xxx.xxx TLSv1.2 2842 Server Hello
7 0.018254 yyy.yyy.yyy.yyy -> xxx.xxx.xxx.xxx TLSv1.2 2842 Certificate
8 0.018283 yyy.yyy.yyy.yyy -> xxx.xxx.xxx.xxx TLSv1.2 848 Certificate Status
11 0.032880 xxx.xxx.xxx.xxx -> yyy.yyy.yyy.yyy TLSv1.2 192 Client Key Exchange, Change Cipher Spec, Hello Request, Hello Request
12 0.033993 xxx.xxx.xxx.xxx -> yyy.yyy.yyy.yyy TLSv1.2 119 Application Data
13 0.034004 xxx.xxx.xxx.xxx -> yyy.yyy.yyy.yyy TLSv1.2 116 Application Data
14 0.034008 xxx.xxx.xxx.xxx -> yyy.yyy.yyy.yyy TLSv1.2 108 Application Data
15 0.034130 yyy.yyy.yyy.yyy -> xxx.xxx.xxx.xxx TLSv1.2 308 New Session Ticket, Change Cipher Spec, Hello Request, Hello Request
16 0.034270 yyy.yyy.yyy.yyy -> xxx.xxx.xxx.xxx TLSv1.2 125 Application Data
17 0.034589 xxx.xxx.xxx.xxx -> yyy.yyy.yyy.yyy TLSv1.2 425 Application Data
(以下略)
そこから一度タブ閉じて、もう一度リクエストを送ると以下の様なシーケンス。
3 0.014875 xxx.xxx.xxx.xxx -> yyy.yyy.yyy.yyy SSL 583 Client Hello
5 0.015423 yyy.yyy.yyy.yyy -> xxx.xxx.xxx.xxx TLSv1.2 216 Server Hello, Change Cipher Spec, Hello Request, Hello Request
7 0.042222 xxx.xxx.xxx.xxx -> yyy.yyy.yyy.yyy TLSv1.2 117 Change Cipher Spec, Hello Request, Hello Request
8 0.042255 xxx.xxx.xxx.xxx -> yyy.yyy.yyy.yyy TLSv1.2 119 Application Data
9 0.042262 xxx.xxx.xxx.xxx -> yyy.yyy.yyy.yyy TLSv1.2 116 Application Data
10 0.042266 xxx.xxx.xxx.xxx -> yyy.yyy.yyy.yyy TLSv1.2 108 Application Data
(以下略)
Certificate, Certificate Status, Server Key Exchange, Client Key Exchangeなどが省略され、Server Helloから一気にChange Cipher Specまで行っていることが分かる。
(注:tsharkの結果には出力されていないが、Server Key ExchangeはCertificate Statusと同じパケットに入っている)
もうちょっとだけ詳しく
以下のコマンドで見れば、
sudo tshark -i eth0 -f "tcp port 443" -Y ssl -O ssl
再起動後のシーケンスの最後、サーバからのChange Cipher Specと同じパケットにSession Ticketの値が含まれていることが分かる。
Secure Sockets Layer
TLSv1.2 Record Layer: Handshake Protocol: New Session Ticket
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 186
Handshake Protocol: New Session Ticket
Handshake Type: New Session Ticket (4)
Length: 182
TLS Session Ticket
Session Ticket Lifetime Hint: 3600
Session Ticket Length: 176
Session Ticket: fcf1faec48a3153aa98072c75e1aae922ebd76da303ea06e...
TLSv1.2 Record Layer: Change Cipher Spec Protocol: Change Cipher Spec
Content Type: Change Cipher Spec (20)
Version: TLS 1.2 (0x0303)
Length: 1
Change Cipher Spec Message
TLSv1.2 Record Layer: Handshake Protocol: Multiple Handshake Messages
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 40
Handshake Protocol: Hello Request
Handshake Type: Hello Request (0)
Length: 0
Handshake Protocol: Hello Request
Handshake Type: Hello Request (0)
Length: 0
以降、Client HelloにはSession Ticketが含まれ、それがvalidであった場合はもろもろが省略されてハンドシェイクがすぐ終わる。
Extension: SessionTicket TLS
Type: SessionTicket TLS (0x0023)
Length: 176
Data (176 bytes)