NginxをHTTPS化する方法|UbuntuでLet’s EncryptとCertbotを使う


HTTPで公開しているサイトをHTTPSに切り替えると、ブラウザーとNginxの間の通信をTLSで暗号化できます。この記事では、UbuntuのNginxで、Let’s Encryptの証明書をCertbotで取得し、HTTPからHTTPSへの転送と証明書の自動更新まで確認します。

Nginxのインストールやサイト設定から始める場合は、先にNginx入門を参照してください。入門の実習はポート8080を使いますが、今回のドメイン確認ではインターネットからポート80に接続できる必要があります。

1. ドメインとポートを確認する

UbuntuにパッケージでNginxを導入済みで、インターネットからNginxへ直接接続できる構成を想定します。example.com は説明用です。以降の設定とコマンドでは、DNSを管理できる自分のドメイン名に置き換えてください。

  • DNSの A レコードをサーバーの公開IPv4アドレスに向けます。AAAA を登録している場合は、そのIPv6アドレスでも同じサイトに接続できるようにします。
  • ホスティング側のファイアウォールとUbuntu側のファイアウォールで、必要な受信TCPポートを許可します。80番は証明書の発行・更新時のHTTP-01認証とHTTPからの転送に、443番はHTTPSに使います。
  • Nginxの server_name に証明書を発行するドメイン名を指定します。www 付きの名前も使う場合は、そちらのDNSとNginxの設定も用意し、発行時に -d を追加します。

HTTP-01では、Let’s Encryptが公開URLの /.well-known/acme-challenge/ 以下にアクセスしてドメインの管理を確認します。80番を公開できない環境やワイルドカード証明書では、DNS-01を検討してください。Let’s Encryptの認証方式

2. HTTPで対象のサイトが表示されることを確認する

既存のサイト設定を編集する前に、Nginx入門の第5節を参考に、読み込み対象外へバックアップを取ります。対象ドメインでHTTP配信できている場合は、設定例を追加せず、server_name と外部からの表示を確認してください。

新しく静的サイトを用意する場合の server ブロック例です。root は index.html を配置したディレクトリに合わせます。listen [::]:80; はIPv6でも公開する場合に使用します。

server {
    listen 80;
    listen [::]:80;
    server_name example.com;

    root /var/www/nginx-demo;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

この例を新規に追加する場合は、/etc/nginx/sites-available/https-demo に保存し、次のコマンドで有効化します。Ubuntu ServerのNginx設定ガイド

sudo ln -s /etc/nginx/sites-available/https-demo /etc/nginx/sites-enabled/https-demo

設定を追加・変更した場合は、構文チェックが通ったら再読み込みします。

sudo nginx -t && sudo systemctl reload nginx

サーバーの外にある端末から次のコマンドを実行します。静的サイトのトップページなら、200 が返り、ブラウザーで開くと対象のページが表示されることを確認します。

curl -I http://example.com/

3. Certbotをインストールする

ここでは、snap が利用できるUbuntuにCertbotを初めて入れる手順を使います。すでに別の方法で導入している場合は既存のCertbotと更新設定を確認し、インストールを重ねないようにします。Certbot公式のインストール手順

sudo snap install --classic certbot
/snap/bin/certbot --version

4. 証明書を発行してHTTPSに切り替える

--nginx は、Nginxプラグインでドメインを認証し、発行した証明書をサイト設定へ組み込みます。--redirect は、そのサイトのHTTPリクエストをHTTPSへ転送する設定を追加します。

sudo /snap/bin/certbot --nginx --redirect -d example.com

初回は案内に沿って連絡先メールアドレスなどを入力します。発行後に sudo nginx -t で設定を検査し、sudo /snap/bin/certbot certificates で対象ドメイン、期限、証明書の保存先を確認します。Nginxの ssl_certificate は証明書チェーン、ssl_certificate_key は秘密鍵を参照します。秘密鍵を公開ディレクトリに置かないでください。NginxのTLS設定リファレンス

5. HTTPSとリダイレクトを外部から確認する

curl -I https://example.com/
curl -I http://example.com/
  • HTTPS側は証明書エラーが出ず、対象のページの応答が返ることを確認します。静的サイトのトップページなら通常は 200 です。
  • HTTP側は 301 などの転送応答が返り、Location が同じドメインの https:// を指すことを確認します。
  • ブラウザーでも実際のページを開き、画像やスクリプトが表示されるか確認します。ページ内に http:// の参照が残っている場合は、開発者ツールで混在コンテンツのエラーを確認します。

6. 証明書の自動更新をテストする

発行できたら、Certbotの更新を模擬実行します。--dry-run はテスト用の認証局で更新処理を試し、公開サイトの証明書は置き換えません。

sudo /snap/bin/certbot renew --dry-run
systemctl list-timers --all | grep -i certbot

模擬更新が成功したことと、snap版の更新タイマーに次回実行予定が表示されることを確認します。HTTP-01での更新を続ける間は、転送を有効にした後も80番への外部接続を維持します。DNSやファイアウォールを変更した場合は、更新テストもやり直します。

7. HTTPS化でつまずいたときの確認箇所

症状確認すること
ドメイン認証がタイムアウトする対象ドメインのDNS、外部からのTCP 80への接続、ホスティング側とUbuntu側のファイアウォールを確認します。
認証で404が返るDNSが別のサーバーを向いていないか、server_name と対象サイトの有効化を確認します。IPv6を登録している場合は AAAA の向き先も確認します。
HTTPSに接続できないTCP 443が許可されているか、sudo nginx -t が成功するか、Nginxが443番で待ち受けているかを確認します。
証明書の名前が一致しないアクセスしたホスト名が certbot certificates の対象に含まれているか、同じ443番で別のサイト設定が選ばれていないかを確認します。

まとめ

外部からHTTPで対象サイトに到達できることを確認してから、Certbotで証明書を発行します。HTTPSでの表示、HTTPからの転送、証明書の模擬更新まで確認できれば、一連の設定を検証できます。

参考資料


コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です