2026年5月17日

2026年5月17日

NginxのSSLセッションキャッシュ設定|ssl_session_cacheの書き方と再開の確認方法

Nginx の SSL セッションキャッシュは、一度 TLS の接続を確立したブラウザーが再び接続してきたときに、前回の鍵交換の結果を使い回して接続を短い手順で再開(セッションレジューム)させるための仕組みです。設定は ssl_session_cache と ssl_session_timeout の 2 行が中心で、http ブロックに書けばすべての HTTPS サイトに効きます。

先に結論です。

http {
    ssl_session_cache   shared:SSL:10m;
    ssl_session_timeout 1h;
    # ssl_session_tickets は既定で on
}
  • shared:SSL:10m は、全ワーカープロセスで共有する 10MB のキャッシュです。公式ドキュメントでは 1MB でおよそ 4,000 セッションを保存できるとされています。
  • ssl_session_timeout の既定は 5 分です。再訪問の間隔に合わせて延ばします。
  • Nginx 1.23.2 以降は、共有キャッシュを設定すると TLS セッションチケットの鍵もその中で生成・保存・定期的に更新されます。設定を再読み込みしてもチケットが無効になりません。
  • 再開できているかは、openssl s_client の出力が Reused になるか、アクセスログの $ssl_session_reused が r になるかで確認します。

この記事の動作確認には Nginx 1.30.6(OpenSSL 3.5.7)を使いました(2026年11月時点)。

セッション再開の 2 つの方式

TLS のセッション再開には、サーバーが情報を持つ方式と、クライアントに持たせる方式があります。

方式 仕組み Nginx の設定
セッション ID(キャッシュ) サーバーがセッション情報をキャッシュに保存し、クライアントは ID を送って再開する ssl_session_cache
セッションチケット サーバーがセッション情報を暗号化してクライアントに渡し、クライアントがそれを提示して再開する ssl_session_tickets、ssl_session_ticket_key

TLS 1.3 では、再開の情報はハンドシェイク後にサーバーから送られる「チケット」の形で渡されます。Nginx(OpenSSL)では、ssl_session_tickets off にしても共有キャッシュがあれば、サーバー側に情報を置く形のチケットで TLS 1.3 の再開ができました(後述の確認手順で検証)。

各ディレクティブの意味と既定値

公式ドキュメント(ngx_http_ssl_module)の内容を整理します。いずれも http か server ブロックに書けます。

ssl_session_cache

書式は ssl_session_cache off | none | [builtin[:size]] [shared:name:size];、既定は none です。

値 意味
off キャッシュの使用を明示的に禁止し、セッションを再利用できないとクライアントに伝える
none(既定) 再利用できるとクライアントには伝えるが、実際にはキャッシュに保存しない
builtin[:size] OpenSSL 内蔵のキャッシュ。ワーカープロセスごとに別で、サイズはセッション数(省略時 20480)。メモリの断片化を招くことがある
shared:name:size 全ワーカーで共有するキャッシュ。サイズはバイト数で、1MB でおよそ 4,000 セッション。同じ名前を複数の server で使える

公式ドキュメントでは、builtin と shared の併用もできるものの、shared だけを使うほうが効率がよいとされています。キャッシュ名(例の SSL)は任意の文字列です。

ssl_session_timeout

クライアントがセッションを再利用できる時間です。既定は 5m(5 分)。値を延ばすと再訪問時に再開できる割合は上がりますが、その分キャッシュに残るセッションが増えるので、キャッシュの大きさも合わせて見直します。キャッシュがいっぱいになると古いものから捨てられます。

ssl_session_tickets

セッションチケットによる再開を有効にするかどうかで、既定は on です。共有キャッシュがない場合でも、チケットが有効なら再開はできます。ただしその場合のチケットの鍵は起動時に無作為に作られるため、設定の再読み込み(reload)や再起動のたびに鍵が変わり、それ以前のチケットは使えなくなります。共有キャッシュを設定すると(1.23.2 以降)、鍵がキャッシュの中に保存され、定期的に更新されながら reload 後も引き継がれます。

ssl_session_ticket_key

チケットを暗号化する鍵をファイルで指定します。複数のサーバーで同じ鍵を共有する必要があるときに使うもので、1 台構成なら設定は不要です。ファイルは 80 バイト(AES256)か 48 バイト(AES128)の乱数で、次のように作ります。

sudo openssl rand 80 | sudo tee /etc/nginx/ticket_current.key > /dev/null
sudo chmod 600 /etc/nginx/ticket_current.key

複数書いた場合、暗号化に使うのは最初の鍵だけで、残りは復号にだけ使われます。これを利用して鍵を入れ替えます。

ssl_session_ticket_key /etc/nginx/ticket_current.key;
ssl_session_ticket_key /etc/nginx/ticket_previous.key;

この鍵が漏れると、その鍵で暗号化されたチケットを使った通信の安全性が損なわれます。鍵ファイルは root だけが読めるようにし、自分で定期的に入れ替える運用ができない場合は、このディレクティブを使わずに共有キャッシュによる自動更新に任せます。

推奨の設定例

1 台の Web サーバーで WordPress などを動かす場合の例です。/etc/nginx/nginx.conf の http ブロック(または conf.d 内のファイルの先頭)に書きます。

http {
    # 全ワーカー共有のセッションキャッシュ(10MB でおよそ 4 万セッション)
    ssl_session_cache   shared:SSL:10m;
    # 再利用できる時間(既定は 5 分)
    ssl_session_timeout 1h;

    server {
        listen 443 ssl;
        server_name example.com;
        ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
        # ...
    }
}

書いたら構文を確認してから再読み込みします。

sudo nginx -t
sudo systemctl reload nginx

ssl_session_cache を server ブロックごとに書く場合、同じ IP とポートで複数のサイトを動かしていると、既定のサーバー(default server)の値が使われることがあります。全サイトで同じ値にするなら、http ブロックに 1 回だけ書くのが分かりやすい方法です。

古い記事でよく見る設定との違い

  • ssl_stapling on; などの OCSP ステープリングは、証明書の失効確認の仕組みで、セッションキャッシュとは関係ありません。また Let's Encrypt は 2025年8月に OCSP の提供を終了しており、同社の証明書では ssl_stapling は働きません。
  • ss -tan などの接続一覧からセッションキャッシュの状態は分かりません。確認は次の章の方法で行います。

セッション再開を確認する

openssl s_client で確認する(TLS 1.2)

-reconnect を付けると、同じセッションで 5 回再接続します。1 回目が New、2 回目以降が Reused なら再開できています。

echo | openssl s_client -connect example.com:443 -servername example.com -tls1_2 -reconnect 2>/dev/null | grep -E '^(New|Reused),'
New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Reused, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Reused, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
(以下略)

openssl s_client で確認する(TLS 1.3)

TLS 1.3 では、再開用のチケットがハンドシェイクの後に届くため、-reconnect ではすべて New と表示されました。1 回目の接続でセッションをファイルに保存し、2 回目にそれを使って接続します。sleep 1 | は、チケットを受け取る前に接続が閉じないようにするためのものです。

sleep 1 | openssl s_client -connect example.com:443 -servername example.com -sess_out /tmp/tls13.sess > /dev/null 2>&1
sleep 1 | openssl s_client -connect example.com:443 -servername example.com -sess_in /tmp/tls13.sess 2>/dev/null | grep -E '^(New|Reused),'

Reused, TLSv1.3, … と出れば再開できています。

アクセスログで確認する

実際の訪問者で再開できているかは、変数 $ssl_session_reused(再開なら r、そうでなければ .)をログに出すと分かります。

http {
    log_format tls '$remote_addr [$time_local] "$request" $status '
                   '$ssl_protocol $ssl_session_reused';

    server {
        # ...
        access_log /var/log/nginx/tls.log tls;
    }
}
# 再開された接続の割合をおおまかに見る
awk '{print $NF}' /var/log/nginx/tls.log | sort | uniq -c

なお、ブラウザーは同じ接続(keep-alive、HTTP/2)を使い回すため、この値が r になるのは新しく TLS 接続を張り直したときだけです。

検証で確かめた動作

Nginx 1.30.6 で、設定の組み合わせごとに再開できるかを確かめた結果です。

設定 TLS 1.2 TLS 1.3 reload 後の再開
キャッシュなし・チケット既定(on) 再開する 再開する 再開しない(鍵が作り直される)
キャッシュなし・ssl_session_tickets off 再開しない 再開しない —
shared:SSL:10m・チケット既定(on) 再開する 再開する 再開する
shared:SSL:10m・ssl_session_tickets off 再開する 再開する —

既定の状態でもチケットによる再開は働きますが、共有キャッシュを設定しておくと、reload のたびに再開が途切れることがなくなります。

複数台の構成での注意

ロードバランサーの後ろに Nginx を複数台置く場合、セッションキャッシュは各サーバーの中にしかありません。

  • 同じクライアントの接続が別のサーバーに振り分けられると、キャッシュでもチケットでも再開できず、通常のハンドシェイクになります(接続はでき、少し遅くなるだけです)。
  • 全台で再開させたい場合は、ssl_session_ticket_key で全台に同じ鍵ファイルを置き、入れ替えも全台で同時に行います。
  • ロードバランサーで HTTPS を終端している構成では、TLS のセッション再開はロードバランサー側の設定になり、Nginx のこの設定は関係しません。

よくある質問

キャッシュの大きさはどれくらいにすればよいですか

1MB でおよそ 4,000 セッションが目安なので、ssl_session_timeout の間に新しく接続してくる訪問者の数から見積もります。一般的なサイトでは 10m で足りることが多く、メモリの使用量も 10MB です。

ssl_session_tickets は off にすべきですか

チケットの鍵が長く変わらないと、鍵が漏れたときに過去の通信まで影響を受けるという理由で、off を勧める設定例があります。Nginx 1.23.2 以降で共有キャッシュを設定していれば、鍵は自動で更新されます。off にしても、検証のとおり共有キャッシュがあれば TLS 1.2・1.3 とも再開できます。

証明書を更新したらキャッシュを消す必要がありますか

不要です。証明書の更新後は nginx -t と systemctl reload nginx を行えば、新しい接続から新しい証明書が使われます。

まとめ

  • http ブロックに ssl_session_cache shared:SSL:10m; と ssl_session_timeout を書くのが基本で、既定の 5 分は必要に応じて延ばします。
  • チケットの鍵は、共有キャッシュがあれば Nginx 1.23.2 以降で自動的に保存・更新されます。ssl_session_ticket_key は複数台で鍵を共有するときに使います。
  • 確認は、TLS 1.2 は openssl s_client -reconnect、TLS 1.3 は -sess_out と -sess_in、実際の訪問者は $ssl_session_reused で行います。

関連記事:

参考: nginx – ngx_http_ssl_module、OpenSSL – openssl-s_client、Let's Encrypt – Ending OCSP Support in 2025

更新履歴: 2026-11-10 全面改訂(存在しない用途の説明、セッションキャッシュと無関係な ssl_stapling の手順、ss による誤った確認方法を削除し、各ディレクティブの既定値、チケット鍵、検証した再開の確認手順に置き換え)。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲