DELOGs
[サーバ構築編#7] Let's Encrypt の証明書を取得して、NginxでHTTPS を設定

サーバ構築編#7
Let's Encrypt の証明書を取得して、NginxでHTTPS を設定

Nginx1.28.0の設定の続きです。Let's Encryptの証明書の取得とHTTPSの設定を実施

初回公開日

最終更新日

サーバ構築編第7回からは、Nginx1.28.0の設定の続きです。 サーバ構築編第6回までの作業が終わった状態(httpでの接続までの設定を完了)を前提としています。

1.Let's Encrypt の管理モジュールcerbot最新版のインストール

Let's Encryptはcertbotというモジュールが管理を行なってくれるのですが、Ubuntuの標準リポジトリだとこのバージョンが下記のように古い。
bash
1apt-cache policy certbot 2certbot: 3 インストールされているバージョン: (なし) 4 候補: 2.9.0-1 5 バージョンテーブル: 6 2.9.0-1 500
2025年5月27日現在は、Certbot 4.0.0が最新です。 githubのcertbot公式ページ
なので、snapというUbuntu の「最新パッケージ管理システム」を利用してインストールを行います。
apt と snap の違い:
apt(従来のパッケージ管理)snap(最新のパッケージ管理)
パッケージの提供元Ubuntu のリポジトリ開発者が直接提供
バージョン古いことが多い常に最新版
依存関係システムのライブラリを使用独立した環境(コンテナ)で動作
更新方法手動で apt upgrade自動で最新バージョンに更新
  • apt upgradeで管理できない反面、基本自動でアップデートしてくれるのがsnapで、最新版を使えるメリットがあります。

snap を使って certbot をインストールする

bash
1sudo apt update 2sudo apt install snapd -y # snap をインストール 3sudo snap install core # snap の基本パッケージ 4sudo snap refresh core # snap を最新バージョンに更新 5sudo snap install --classic certbot # 最新の certbot をインストール 6sudo ln -s /snap/bin/certbot /usr/bin/certbot # certbot をシステムコマンドとして登録

snap の certbot が正しくインストールされたか確認

bash
1certbot --version
bash
1certbot 4.0.0
最新バージョンがインストールできました。 apt 版の certbot なら apt upgrade -y で更新されるが、snap 版の certbot は snap 独自の更新管理となります。

snap の自動更新スケジュールを確認

snap は デフォルトで1日4回(6時間ごと)に自動更新してくれます。したがって、原則はコマンドで更新作業をする必要はなくなります。 更新スケジュールを確認する方法:
bash
1snap refresh --time
出力例:
bash
1timer: 00:00~24:00/4 ← 6時間ごとに更新チェック 2last: n/a ← まだ一度も更新されていない(新規インストールしたばかり) 3hold: today at 19:52 JST ← 一時的に更新が保留されている 4next: today at 17:56 JST (but held) ← 次の更新予定だけど、保留状態
  • hold: が設定されているので、一時的に更新が止まっている可能性がある
certbot の更新が保留されていないかチェック:
bash
1snap refresh --list
All snaps up to date.と出力される場合は、問題なく次の更新時間で更新がなされます。
もし、hold状態が続くなら下記で保留を解除できます。
bash
1sudo snap refresh --unhold certbot
snap refresh --listの定期チェックが必要なので、これは別途クローンを設定してチェックするようにした方が良さそうです。

2.certbot を使って証明書を取得

まず、Nginx プラグインを使って証明書を取得&自動設定します。 基本的にドメイン毎に分けて取得する方法が運用を考えるとベストです。 もしexample.comhogehoge.comの2種類のドメインの設定したい時は、下記コマンドをそれぞれ別に実行しましょう。
bash
1sudo certbot --nginx -d example.com -d www.example.com 2 3# 複数のドメインをしたいときは上記の実行が終わってから下記を別途実行 4sudo certbot --nginx -d hogehoge.com -d www.hogehoge.com
sudo certbot --nginxでドメインを省略してまとめて実行して、適用するドメインの選択時にexample.com関連とhogehoge.com関連をまとめて実行すると、証明書ファイルがマージされた状態で発行されるので、運用時に面倒になるので、上記のようにドメイン毎に証明書取得する方が良いと思います。
実行すると、以下のような対話式の設定が始まります。各項目の入力例と解説を順番に見ていきましょう!
○管理者用のメールアドレス
bash
1Enter email address or hit Enter to skip. 2 (Enter 'c' to cancel): your-email@gmail.com
  • ここでは、管理者用のメールアドレスを入力します。
  • このメールアドレスは、証明書の期限が近づいたときの通知に使われます!
  • 何も入力せず Enter を押すと、期限切れの通知が届かないので注意!
○利用規約(ToS)への同意
bash
1- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2Please read the Terms of Service at: 3https://letsencrypt.org/documents/LE-SA-v1.5-February-24-2025.pdf 4You must agree in order to register with the ACME server. Do you agree? 5- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 6(Y)es/(N)o: Y
  • Let’s Encrypt の利用規約(ToS)に同意するか確認されます。
  • 証明書を発行するためには「Yes(Y)」を選択する必要があります!
○EFF(Electronic Frontier Foundation)からのメールを受け取るか
bash
1- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2Would you be willing, once your first certificate is successfully issued, to 3share your email address with the Electronic Frontier Foundation, a founding 4partner of the Let's Encrypt project and the non-profit organization that 5develops Certbot? We'd like to send you email about our work encrypting the web, 6EFF news, campaigns, and ways to support digital freedom. 7- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 8(Y)es/(N)o: N
  • これは EFF(Let’s Encrypt の開発元)のニュースや活動情報を受け取るかどうかの選択です。
  • これはどちらでもサーバーの SSL 設定には影響しません。
○SSL を適用するドメインの選択
bash
1Which names would you like to activate HTTPS for? 2We recommend selecting either all domains, or all domains in a VirtualHost/server block. 3- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 41: example.com 52: www.example.com 6- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 7Select the appropriate numbers separated by commas and/or spaces, or leave input 8blank to select all options shown (Enter 'c' to cancel): (例:何も入力せずに `Enter` を押す)
  • ここで HTTPS を有効化するドメインを選択します
  • www. あり・なしの両方を選択するのがオススメ!
  • そのまま Enter を押せば、すべてのドメインに SSL を適用できます。
  • 特定のドメインだけ選択する場合は1 2などブランク区切りで入力
○証明書の取得完了
bash
1Successfully received certificate. 2Certificate is saved at: /etc/letsencrypt/live/example.com/fullchain.pem 3Key is saved at: /etc/letsencrypt/live/example.com/privkey.pem 4This certificate expires on 2025-06-15. 5These files will be updated when the certificate renews. 6Certbot has set up a scheduled task to automatically renew this certificate in the background. 7 8Deploying certificate 9Successfully deployed certificate for example.com to /etc/nginx/conf.d/example.com.conf 10Successfully deployed certificate for www.example.com to /etc/nginx/conf.d/example.com.conf 11Congratulations! You have successfully enabled HTTPS on https://example.com, https://www.example.com 12 13- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 14If you like Certbot, please consider supporting our work by: 15 * Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate 16 * Donating to EFF: https://eff.org/donate-le 17- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  • 証明書 (fullchain.pem) と秘密鍵 (privkey.pem) は /etc/letsencrypt/live/ドメイン名/ に保存されます。
  • 証明書は90日間有効で、自動更新が設定されています。
  • Nginx に自動で SSL 設定が適用されます。

3. certbot の自動更新を確認

Let’s Encrypt の証明書は 90日ごとに更新が必要ですが、自動で更新してくれます。 certbot は systemd のタイマーで自動更新しますが、手動で確認することもできるので、しっかり動作するかを確認します。
bash
1sudo certbot renew --dry-run
成功例:
bash
1Congratulations, all renewals succeeded. The following certs have been renewed: 2 /etc/letsencrypt/live/example.com/fullchain.pem (success)
  • これが出れば 自動更新 OK

4.HTTPS が有効になったか確認

certbotがNginxの設定ファイルを書き換えてくれて、Nginxの設定をリロードしてくれていますので、すぐにブラウザで確認できます。 ブラウザで設定したドメインにアクセスして確認します。鍵マーク付きでサイトが表示できていればOKです。
サーバ構築編第6回のNginxのバーチャルホスト設定のconfファイルでwww.example.com=>example.comへのリダイレクト設定している場合は、httpsでもリダイレクトされることが確認できると思います。

5.自動更新時にNginxをリロードさせる

Certbot には「自動実行スクリプト用の公式ディレクトリ」が用意されています。各ディレクトリに実行可能なシェルスクリプトを置いておけば、それぞれのルールに従って実行してくれます。
ディレクトリ実行タイミング目的
/etc/letsencrypt/renewal-hooks/pre/更新の直前例えばバックアップとか
/etc/letsencrypt/renewal-hooks/deploy/証明書の更新直後Nginx再起動・通知・配布など
/etc/letsencrypt/renewal-hooks/post/すべての処理が終わった最後ログ整理・終了処理など
bash
1sudo vi /etc/letsencrypt/renewal-hooks/post/reload-services.sh
例):
bash : reload-services.sh
1#!/bin/bash 2{ 3 echo "[`date`] Reloading Nginx..." 4 5 echo "Reloading nginx..." 6 systemctl reload nginx && echo "✓ nginx reload OK" || echo "✗ nginx reload FAILED" 7 8 echo "" 9} >> /var/log/letsencrypt/reload-services.log 2>&1
専用ログを出力しておくと、確認がわかりやすくなります。
bash
1sudo chmod +x /etc/letsencrypt/renewal-hooks/post/reload-services.sh
○テスト実行
bash
1sudo certbot renew --dry-run
bash
1sudo cat /var/log/letsencrypt/reload-services.log 2[2025519日 月曜日 16:50:21 JST] Reloading Nginx... 3Reloading nginx... 4✓ nginx reload OK
上記のようにログが出てリロードが完了していることが確認できます。

6./etc/nginx/conf.d/*.confの修正

Certbotは自動でNginx側の設定を書き換えてくれますが、リダレクト設定については、私の環境では、少し変な記述になっていました。 /etc/nginx/conf.d/example.com.conf/etc/nginx/conf.d/hogehoge.conf の内容を確認がてら、修正したいところがあれば修正しておきます。
bash
1sudo vi /etc/nginx/conf.d/example.com.conf
bash : example.com.conf
1server { 2 server_name www.example.com; 3 4 return 301 http://example.com$request_uri; 5 6 listen 443 ssl; # managed by Certbot 7 ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot 8 ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot 9 include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot 10 ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot 11 12} 13 14server { 15 server_name example.com; 16 17 root /var/www/example.com/html; 18 index index.html; 19 20 location / { 21 try_files $uri $uri/ =404; 22 } 23 24 listen 443 ssl; # managed by Certbot 25 ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot 26 ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot 27 include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot 28 ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot 29 30} 31 32server { 33 if ($host = example.com) { 34 return 301 https://$host$request_uri; 35 } # managed by Certbot 36 37 38 listen 80; 39 server_name example.com; 40 return 404; # managed by Certbot 41 42 43}server { 44 if ($host = www.example.com) { 45 return 301 https://$host$request_uri; 46 } # managed by Certbot 47 48 49 listen 80; 50 server_name www.example.com; 51 return 404; # managed by Certbot 52 53 54} 55
上記のように# managed by Certbotと記述のある行がCertbotが追記・改変してくれた箇所になります。 また、http用の設定をなぞる形で、listen 433のエリアを作成してくれていることもわかります。
ただ、server_name www.example.com;のサーバブロックを見ると、return 301 http://example.com$request_uri;となっていて、 一度http://example.comへリダイレクト->https://example.comとリダイレクトする記述になっています。
該当のサーバブロックを下記のようにして直接https://example.comとリダイレクトするようにしておきます。
diff : example.com.conf
1server { 2 server_name www.example.com; 3 4- return 301 http://example.com$request_uri; 5+ return 301 https://example.com$request_uri; 6 7 listen 443 ssl; # managed by Certbot 8 ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot 9 ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot 10 include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot 11 ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot 12}
他、不要な改行などが気になる方は修正しておいても良いと思います。同様にhogehoge.com.confについても修正します。
修正が終わったら、Nginxを再起動しておきます。
bash
1sudo nginx -t 2sudo systemctl restart nginx

7.コマンドのまとめ(運用時用)

SSL 証明書の情報を確認

bash
1sudo certbot certificates
  • 現在発行されている証明書の一覧や、証明書の有効期限を確認できる。

ドメイン追加

bash
1sudo certbot --nginx -d hogehoge.com -d www.hogehoge.com
  • 新しいドメインを certbot で SSL 化する。Nginx の設定も自動で更新される!

ドメイン削除

bash
1sudo certbot delete --cert-name hogehoge.com
  • 不要になった SSL 証明書を削除し、自動更新の対象からも外す。
  • 削除後、sudo certbot certificates で対象の証明書が消えていることを確認!

certbotの自動更新のログ確認

bash
1sudo tail -n 50 /var/log/letsencrypt/letsencrypt.log
  • これで certbot の最近の動作(更新の実行履歴など)が確認できる!

certbotの更新スケジュール(systemd のタイマー)を確認

bash
1systemctl list-timers | grep certbot
  • 最初に表示される時間が次回更新の時間

もし、自動更新が失敗したら、

○certbot renew が手動で成功するかテスト
bash
1sudo certbot renew --dry-run
  • ログを調査して問題を解消
○強制更新するなら
bash
1sudo certbot renew --force-renewal
続きはこちら...
前回の確認はこちら...
この記事の執筆・編集担当
DE

松本 孝太郎

DELOGs編集部/中年新米プログラマー

ここ数年はReact&MUIのフロントエンドエンジニアって感じでしたが、Next.jsを学んで少しずつできることが広がりつつあります。その実践記録をできるだけ共有していければと思っています。