2026年10月15日
2026年10月15日
NginxでSSL/TLSを設定してHTTPS化する方法:証明書の指定から安全な設定値、WordPress側の切り替えまで
Nginx を HTTPS に対応させるには、443番ポートで待ち受ける server ブロックに証明書と秘密鍵を指定し、TLS のバージョンと暗号スイートを現在の推奨に合わせるのが基本です。この記事では、証明書ファイルの正しい指定方法、設定値ごとの意味、WordPress の URL を HTTPS に切り替える手順、そして設定が正しく効いているかを確かめる方法までを順に説明します。
HTTP から HTTPS への転送(301 リダイレクト)の詳しい書き方と、Let's Encrypt 証明書の自動更新は別記事で扱います。ここでは「443番で正しく TLS を話せる状態を作る」ことに集中します。
作業前の準備
始める前に次の3点を確認します。
- 証明書と秘密鍵が手元にあること。Let's Encrypt なら Certbot で取得した
fullchain.pemとprivkey.pem、商用証明書なら発行元から受け取ったサーバー証明書と中間証明書 - ファイアウォールで 443/tcp が開いていること(
ufwやfirewalld、クラウドのセキュリティグループ) - 設定とデータベースのバックアップ
sudo cp -a /etc/nginx /etc/nginx.bak-$(date +%Y%m%d)
nginx -v # バージョンにより書き方が変わる項目があるため確認しておく
基本の server ブロック
まず動く最小構成を示し、その後に各行の理由を説明します。パスやドメインは自分の環境に置き換えてください。
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on; # Nginx 1.25.1 以降の書き方
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
root /var/www/example.com;
index index.php index.html;
# 以降に WordPress 用の location を書く
}
証明書は「中間証明書つき」を指定する
ssl_certificate には、サーバー証明書の後ろに中間証明書を連結したファイルを指定します。Let's Encrypt の fullchain.pem はすでに連結済みですが、cert.pem を指定してしまうと中間証明書が欠けます。この状態でも PC のブラウザでは表示できてしまうことがあり、スマートフォンや API クライアント、検索エンジンのクローラーだけが証明書エラーになる、という分かりにくい不具合になります。
商用証明書で別々のファイルを受け取った場合は、サーバー証明書、中間証明書の順に連結します。
cat server.crt intermediate.crt > /etc/nginx/ssl/example.com.fullchain.crt
秘密鍵は Nginx のマスタープロセス(root)が読めれば足ります。権限は 600 程度にして、他のユーザーから読めないようにします。
HTTP/2 の書き方はバージョンで異なる
Nginx 1.25.1 以降では http2 on; を独立したディレクティブとして書きます。それより古い版では listen 443 ssl http2; の形でした。新しい版で古い書き方を使うと非推奨の警告が出るため、nginx -v で確かめてから選んでください。同じ IP とポートを使う複数の server ブロックがある場合、HTTP/2 の有効・無効は揃えておくと混乱しません。
TLS のバージョンと暗号スイート
TLS 1.0 と 1.1 は主要ブラウザで無効化されており、新規に有効にする理由はほとんどありません。ssl_protocols TLSv1.2 TLSv1.3; を明示しておけば、Nginx の既定値が版によって違っても挙動を固定できます。
ssl_ciphers は TLS 1.2 で使う暗号スイートの指定です(TLS 1.3 の暗号はこの行では変わりません)。上の例は、Mozilla が公開している「SSL Configuration Generator」の Intermediate 相当を参考にしたものです。推奨は時間とともに更新されるため、設定時点のジェネレーターの出力と見比べてください(2026年10月現在)。古い端末への対応が必要かどうかで、どの水準を選ぶかが変わります。
ssl_prefer_server_ciphers off; は、今の推奨スイートがどれも十分強いため、クライアント側の選択(端末に合った高速な暗号)を優先させる設定です。
セッションの再利用
ssl_session_cache は、TLS の握手(ハンドシェイク)の結果をワーカー間で共有し、再接続を速くするための設定です。10m で数万セッション程度を保持できるとされます。ssl_session_tickets off; は、チケット用の鍵を定期的に入れ替える仕組みを用意していない環境で、前方秘匿性が弱まるのを避けるための推奨設定です。
OCSP stapling について
以前は ssl_stapling on; を入れる設定例が一般的でしたが、Let's Encrypt は2025年に OCSP の提供を終了し、証明書失効の確認を CRL に移しています。Let's Encrypt の証明書では stapling を有効にしても効果がなく、警告の原因になることがあります。商用証明書で OCSP を使う場合だけ、発行元の案内に従って設定してください。
反映と HTTP 側の扱い
sudo nginx -t && sudo systemctl reload nginx
nginx -t は証明書ファイルが読めるか、鍵と証明書の組み合わせが正しいかも検査します。「cannot load certificate」や「key values mismatch」が出たら、パスの誤りか、別の証明書の鍵を指定していないかを見直します。
443番が動いたことを確認してから、80番の server ブロックで HTTPS へ転送します。順番を逆にすると、証明書がない状態で利用者を HTTPS に送ってしまいます。HSTS(Strict-Transport-Security ヘッダー)を付ける場合も、全ページとサブドメインが HTTPS で問題なく表示できることを確認したうえで、短い max-age から試すのが安全です。
WordPress 側を HTTPS に切り替える
Nginx が HTTPS を話せても、WordPress の URL 設定が http:// のままだと、リダイレクトの往復や混在コンテンツ(Mixed Content)が起きます。
- 管理画面の「設定」→「一般」で、WordPress アドレスとサイトアドレスを
https://に変更する(画面の表記は版によって多少異なります) - 本文や設定に残った
http://example.comを置き換える。WP-CLI を使う場合は、先に--dry-runで件数を確認する
wp db export before-https.sql
wp search-replace 'http://example.com' 'https://example.com' --all-tables --dry-run
wp search-replace 'http://example.com' 'https://example.com' --all-tables
search-replace はシリアライズされたデータも正しく扱えるため、SQL で直接 UPDATE するより安全です。
ロードバランサや CDN で TLS を終端し、Nginx には HTTP で届く構成では、WordPress が「HTTPS でのアクセス」と判定できずにリダイレクトがループすることがあります。この場合は Nginx で fastcgi_param HTTPS on; を渡すか、信頼できるプロキシからの X-Forwarded-Proto を見て wp-config.php で $_SERVER['HTTPS'] = 'on'; を設定します。後者は、そのヘッダーを外部から偽装できない構成であることが前提です。
設定を確認する方法
ブラウザで鍵マークが出るだけでなく、コマンドで中身を確かめておくと、端末差による不具合を事前に見つけられます。
# 証明書チェーンと有効期限を確認(-servername で SNI を指定)
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null
# 有効期限だけを見る
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates
# TLS 1.1 で接続できないことを確認(失敗すれば期待どおり)
openssl s_client -connect example.com:443 -servername example.com -tls1_1 </dev/null
# 応答ヘッダーを確認
curl -I https://example.com/
s_client の出力で「Verify return code: 0 (ok)」となっていれば、チェーンの検証は通っています。外部の検査サービス(Qualys SSL Labs の SSL Server Test など)を使うと、対応プロトコルや暗号スイートの一覧を第三者の視点で確認できます。
まとめ
- 443番の
serverブロックでssl_certificateに中間証明書つきのファイル(fullchain.pem)を指定する ssl_protocols TLSv1.2 TLSv1.3;を明示し、暗号スイートは Mozilla のジェネレーターなど最新の推奨と照らし合わせる- HTTP/2 の書き方は Nginx 1.25.1 を境に変わったため、バージョンを確認してから書く
- Let's Encrypt の証明書では OCSP stapling は不要になっている
- WordPress の URL を HTTPS に切り替え、
wp search-replaceで古い URL を置き換える openssl s_clientとcurl -Iで、チェーン・期限・プロトコルを確認する