2026年5月20日
2026年5月20日
NginxでHTTPからHTTPSにリダイレクトする設定|return 301の書き方と確認
サイトを HTTPS に対応させたら、http:// で来たアクセスを https:// の同じ URL へ転送(リダイレクト)します。古いリンクやブックマークから来た訪問者も HTTPS で表示され、検索エンジンにも HTTPS の URL が正しい URL だと伝わります。
Nginx では、80番ポート(HTTP)を受ける server ブロックに return 301 を1行書くのが基本の方法です。この記事の設定は、Nginx 1.24 と 1.30 で動作を確かめました(2026年11月時点)。
前提: HTTPS で表示できること
リダイレクトの前に、https:// でサイトが表示できる状態にしておきます。証明書が無いまま転送すると、訪問者にはエラー画面が出ます。Let's Encrypt の証明書の取得は「Certbot で Nginx に Let's Encrypt の証明書を設定する」を参照してください。
Certbot を使う場合
Certbot の Nginx プラグインで証明書を取るときに --redirect を付けると、HTTP から HTTPS への転送の設定も自動で追加されます。
sudo certbot --nginx --redirect -d example.com -d www.example.com
Certbot が追加した設定には # managed by Certbot という印が付きます。そのまま使ってかまいません。自分で書く場合は次の節の設定にします。
自分で設定を書く
80番ポートの server ブロックで、すべてのリクエストを HTTPS に転送します。443番ポートの server ブロックは、サイトを表示する設定です。example.com と証明書のパスは自分の環境に置き換えます。
# HTTP: すべて HTTPS へ転送する
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
# HTTPS: サイトを表示する
server {
listen 443 ssl;
listen [::]:443 ssl;
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;
root /var/www/example.com;
# 以下、既存の設定(index、location など)
}
return 301: 「恒久的に移動した」という意味の 301 の応答で転送します。正規表現を使うrewriteより処理が単純で、読みやすい書き方です。$host: リクエストのホスト名です。example.comで来ればhttps://example.com、www.example.comで来ればhttps://www.example.comに転送されます。$request_uri: パスとクエリ文字列(?以降)をそのまま引き継ぎます。http://example.com/about/?ref=1はhttps://example.com/about/?ref=1に転送されます。
設定ファイルの場所は、Ubuntu・Debian では /etc/nginx/sites-available/(sites-enabled/ にリンクを置いて有効化)、RHEL 系や nginx.org のパッケージでは /etc/nginx/conf.d/ が一般的です。
443番ポート側に転送を書かない
return 301 https://... を 443番ポートの server ブロックや、80番と443番の両方を listen する server ブロックに書くと、HTTPS のアクセスもまた HTTPS に転送され、転送が終わらなくなります(ブラウザに「リダイレクトが繰り返し行われました」と出ます)。転送は 80番ポートだけの server ブロックに書きます。
設定を反映する
sudo nginx -t
sudo systemctl reload nginx
nginx -t で test is successful が出てから reload します。
転送を確かめる
ブラウザは 301 の転送を覚えるため、設定を試すときは、ブラウザの記憶に左右されない curl で確かめます。
curl -I "http://example.com/about/?ref=1"
次のように 301 と、Location に https:// の同じ URL が出れば成功です(必要な行だけ抜き出しています)。
HTTP/1.1 301 Moved Permanently
Location: https://example.com/about/?ref=1
www あり・なしの両方、トップページと下の階層のページの両方で確かめておきます。
設定に自信が無い間は return 302(一時的な転送)で試し、動作を確かめてから 301 に変える方法もあります。301 はブラウザに長く残るため、間違えたまま公開すると、直しても訪問者のブラウザでは古い転送先に飛び続けることがあります。
WordPress 側の設定
Nginx の転送だけでは、WordPress が出力するリンクや画像の URL は http:// のまま残ることがあります。次の2つも直します。
- 管理画面の「設定」→「一般」で、「WordPress アドレス (URL)」と「サイトアドレス (URL)」を
https://に変える - 投稿本文などに書かれた
http://の URL をhttps://に置き換える(WP-CLI のwp search-replaceなどを使う。実行前にデータベースのバックアップを取る)
詳しくは「WordPress を HTTPS で常時表示する設定」を参照してください。
うまくいかないとき
- 転送がループする: Cloudflare の SSL/TLS の設定が「Flexible」だと、Cloudflare からサーバーへは HTTP で接続するため、Nginx が HTTPS に転送し続けます。Cloudflare 側を「Full (strict)」にするなどの対処は「リダイレクトが繰り返し行われましたの原因と直し方」で説明しています。
- 転送されない:
sudo nginx -T | grep -n "listen 80"で、80番ポートを listen している server ブロックがほかに無いか確かめます。別の server ブロック(たとえば Ubuntu のdefault)が応答していることがあります。
まとめ
- 80番ポートの server ブロックに
return 301 https://$host$request_uri;を書く - 転送は 443番ポートの server ブロックには書かない(ループする)
sudo nginx -tの後にsudo systemctl reload nginxで反映し、curl -Iで301とLocationを確かめる- WordPress の「設定」→「一般」の URL も
https://にする
www あり・なしの統一、不正なホスト名への対策、HSTS など、もう一歩進んだ設定は「Nginx の HTTPS リダイレクトの推奨設定」で説明しています。