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からの転送、証明書の模擬更新まで確認できれば、一連の設定を検証できます。