【Ubuntu】Let’s Encrypt+nginxでSSL/TLS(https接続)を設定する方法

検証環境

下記の環境でLet's EncryptでSSL/TLS証明書を発行して、nginxでhttps通信ができるまでの手順を解説していきます。

  • OS:Ubuntu Server 20.04
  • nginx:1.21.4
  • certbot(証明書発行用アプリ):0.40.0
  • certbotのnginx用プラグイン:python3-certbot-nginx 0.40.0
  • SSL/TLS証明書を取得するホスト名: ex.server-memo.net

SSL/TLS証明書を発行する前に必要なこと

SSL/TLS証明書を取得しようとしているサーバのホスト名が、インターネット上で名前解決できるようにDNSに登録しておく必要があります。

また、Let's Encryptからの連絡が受け取れるメールアドレスも必要となります。

作業手順

作業の大まかな手順は下記の通りとなります。

  • 80,443ポート通信許可設定
  • nginxインストール
  • certbotインストール
  • SSL/TLS証明書の取得

80,443ポート通信許可設定

ufwコマンドを使用して、webサーバで使用する80,443番ポートの通信をファイアウォールで許可します。

$ sudo ufw allow 80/tcp
$ sudo ufw allow 443/tcp

nginxインストール

nginxがインストールされていない場合はインストールを行います。

nginxをインストールする方法は下記のページで説明しているで参考にしてださい。

【Ubuntu】nginxリポジトリを使用してインストール
【Ubuntu Server 22.04】apt-key addの非推奨に関わるインストール手順変更 apt-key addが非推奨(廃止予定)となったので、Ubuntu Server 22.04からはnginx公式のリポジトリを使用したイ...

すでにインストール済みの場合はこの作業は必要ありません。

nginx設定

nginxの設定が完了していてhttpでの接続ができている状態であればこの作業は必要ありませんので、certbotインストールの工程に進んでください。

最初にhttpで接続できるようにnginxの設定ファイルを作成します。

今回はあとでwebサイトが増えても良いように、バーチャルホストとして設定を行っています。

$ sudo vi /etc/nginx/conf.d/ex.server-memo.net.conf

SSL/TLS証明書の取得するだけが今回の目的なので、サーバ名とドキュメントルートとインデックスファイル名といった最低限の項目だけ設定していきます。

server {
    server_name ex.server-memo.net;
    root /usr/share/nginx/ex;
    index index.html;
}

設定ファイルが完成したらの文法のチェックをします。

$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

問題がなければnginxを再起動して設定を反映させます。

$ sudo systemctl restart nginx

ドキュメントルートとindex.htmlファイルの作成

ドキュメントルートの作成とテスト表示用のindex.htmlファイルを作成します。

index.htmlファイルの中身はホスト名にしました。

$ sudo mkdir /usr/share/nginx/ex
$ echo ex.server-memo.net | sudo tee /usr/share/nginx/ex/index.html

あとはwebブラウザでアクセスできることを確認してください。

certbotインストール

Let's EncryptでSSL/TLS証明書を取得するためのクライアントである、certbotとnginx用のプラグインであるpython3-certbot-nginxをインストールします。

python3-certbot-nginxはnginxに対応しているプラグインで、certbotを実行する際に「-nginx」オプションを指定すると、nginx用の設定を自動的に追加してくれるという機能があります。

$ sudo apt update
$ sudo apt install certbot python3-certbot-nginx

Daemonの再起動確認画面(Ubuntu 22.04)

Ubuntu Server 22.04 にはneedrestartがインストールされているため、パッケージをインストールすると、デーモンの再起動を確認する画面が表示されることがあります。

この画面が表示されたら「OK」を選択して「Enter」キーを押下してください。

SSL/TLS証明書の取得

certbotコマンドを実行してSSL/TLS証明書の発行作業を行います。

$ sudo certbot --nginx -d ホスト名 -m メールアドレス --agree-tos

オプションの説明

certbot実行時に指定しているオプションを説明します。

--nginx

nginx用のプラグインを使用します。

このプラグインを使用すると、証明書の発行以外にもnginxの設定ファイルにhttps通信用の設定も追加してくれます。

-d ホスト名

証明書の発行依頼を行うホスト名をFQDN形式で指定します。

-m メールアドレス

Let's Encryptからの通知を受取メールアドレスを指定します。

LetsEncryptからのお知らせや、証明書の更新期限が近くなると、ここで指定したメールアドレスに通知してくれます。

--agree-tos

利用規約に同意します。

利用規約は下記のURLにあるので、確認しておいてください。

https://letsencrypt.org/repository/

実行時にされる質問

certbotを実行すると途中で質問がありますので解答する必要があります。

メールアドレスの共有許可

初回登録時にメールアドレスをElectronic Frontier Foundationと共有しても良いかという質問があります。

Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o:

共有を許可すると、Electronic Frontier Foundationからのニュースやキャンペーン等の情報が送られてくるようです。

共有しても、しなくてもどちらを選んでも証明書の発行には問題がないので、どちらかを入力して下さい。

  • 許可する場合「y」を入力
  • 許可しない場合「n」を入力

httpsへのリダイレクト設定

certbot 1.21.0で確認したところ、このリダイレクトさせるという設定がデフォルトで有効となっていました。

リダイレクトの設定を自動で追加させないようにするためには、「--no-redirect」というオプションを指定する必要があります。

httpでアクセスがあった場合に、httpsへリダイレクトさせるかどうかの質問があります。

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel):

どちらかを選んで番号を入力してください。

  • リダイレクトさせない場合は「1」を入力
  • リダイレクトさせる場合は「2」を入力

最近はhttps接続が当たり前になってきているので、特に問題がある場合以外はhttpsへリダイレクトさせるのがおすすめです。

実行例

以下の内容でSSL/TLS証明書の発行処理を取得した際のログとなります。

  • ホスト名 ex.server-memo.net
  • メールアドレス tamohiko@server-memo.net
$ sudo certbot --nginx -d ex.server-memo.net -m tamohiko@server-memo.net --agree-tos
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: n   # メールアドレスの共有は許可しないのでnを入力
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for ex.server-memo.net
Waiting for verification...
Cleaning up challenges
Deploying Certificate to VirtualHost /etc/nginx/conf.d/ex.server-memo.net.conf

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2  # リダイレクトさせたいので2を入力
Redirecting all traffic on port 80 to ssl in /etc/nginx/conf.d/ex.server-memo.net.conf

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://ex.server-memo.net

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=ex.server-memo.net
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/ex.server-memo.net/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/ex.server-memo.net/privkey.pem
   Your cert will expire on 2022-03-06. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

証明書の取得が成功すると「Congratulations! You have successfully enabled https://ホスト名」といったようなメッセージが表示されます。

これでhttpsの通信を行うことができるようになっているので、ウェブブラウザで実際にアクセスして動作確認を行ってください。

ngixに追加される設定

certbotでnginx用のプラグインを使った場合、https通信に関わる設定と、証明書取得時にhttpへの通信をhttpsへリダイレクトさせる設定にした場合は、その設定が追加されます。

追加された設定には「# managed by Certbot」と記述されているので、一目でどの設定が追加されたのかがわかるようになっています。

$ sudo cat /etc/nginx/conf.d/ex.server-memo.net.conf
server {
  server_name ex.server-memo.net;
  root /usr/share/nginx/ex;
  index index.html;


  listen 443 ssl; # managed by Certbot
  ssl_certificate /etc/letsencrypt/live/ex.server-memo.net/fullchain.pem; # managed by Certbot
  ssl_certificate_key /etc/letsencrypt/live/ex.server-memo.net/privkey.pem; # managed by Certbot
  include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
  ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot


}
server {
  if ($host = ex.server-memo.net) {
      return 301 https://$host$request_uri;
  } # managed by Certbot


  server_name ex.server-memo.net;
  listen 80;
  return 404; # managed by Certbot


}

SSL/TLS証明書の更新について

今回の手順でインストールしたcertbotはsystemdのcertbot.timerで、1日2回証明書の更新処理が実行されようにスケジューリングされていて、証明書の有効期限が30日以内になった場合に証明書が自動更新される仕組みになっています。

certbot.timerが正常に動作しているかは、下記のコマンドで確認することができます。

$ sudo systemctl status certbot.timer
 ● certbot.timer - Run certbot twice daily
      Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; vendor preset: enabled)
      Active: active (waiting) since Mon 2021-11-29 17:40:04 JST; 1 weeks 4 days ago
     Trigger: Sat 2021-12-11 21:29:16 JST; 10h left
    Triggers: ● certbot.service
 
 Nov 29 17:40:04 118-27-116-228 systemd[1]: Started Run certbot twice daily.

Activeの項目がactiveになっていれば問題ありません。

systemctl list-timers certbot.timerコマンドを実行すると、NEXTの項目で次回の更新処理実行日時、LASTの項目で前回の更新処理実行日時を確認することができます。

$ sudo systemctl list-timers certbot.timer
NEXT                        LEFT     LAST                        PASSED       UNIT          ACTIVATES      
Sun 2021-12-12 08:55:47 JST 14h left Sat 2021-12-11 13:34:32 JST 4h 59min ago certbot.timer certbot.service

更新のテスト

自動更新はcertbot.timerでスケジュールされていますが、実際に更新が正常に行われるかの事前にテストを行っておきましょう。

証明書の更新作業はcertbot renewで行うのですが、その際に--dry-runを指定すると更新テストを行うことができます。

$ sudo certbot renew --dry-run
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/ex.server-memo.net.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert not due for renewal, but simulating renewal for dry run
Plugins selected: Authenticator nginx, Installer nginx
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for ex.server-memo.net
Waiting for verification...
Cleaning up challenges

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
new certificate deployed with reload of nginx server; fullchain is
/etc/letsencrypt/live/ex.server-memo.net/fullchain.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/ex.server-memo.net/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

IMPORTANT NOTES:
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.

実行結果にエラーが無ければ、更新テストは問題なく完了となります。

証明書等の保管場所について

発行された証明書等は下記の場所に保管されます。

  • 証明書 /etc/letsencrypt/archive/ホスト名/cert[数字].pem
  • 証明書+中間CA証明書 /etc/letsencrypt/archive/ホスト名/fullchain[数字].pem
  • 秘密鍵 /etc/letsencrypt/live/archive/privkey[数字].pem
  • 中間CA証明書 /etc/letsencrypt/archive/ホスト名/chain[数字].pem

各ファイルの数字部分は、新規発行時は1が割り振られて、更新が行われるたびに数字が増えたファイルが作成されていきます。

$ sudo ls -l /etc/letsencrypt/archive/ex.server-memo.net
total 40
-rw-r--r-- 1 root root 1850 Dec  6 17:25 cert1.pem
-rw-r--r-- 1 root root 1850 Dec  6 17:31 cert2.pem
-rw-r--r-- 1 root root 3750 Dec  6 17:25 chain1.pem
-rw-r--r-- 1 root root 3750 Dec  6 17:31 chain2.pem
-rw-r--r-- 1 root root 5600 Dec  6 17:25 fullchain1.pem
-rw-r--r-- 1 root root 5600 Dec  6 17:31 fullchain2.pem
-rw------- 1 root root 1704 Dec  6 17:25 privkey1.pem
-rw------- 1 root root 1704 Dec  6 17:31 privkey2.pem

一度更新を行ってみたので、ファイル名の数字部分が1から2へと増えたファイルが作成されています。

証明書の使用方法

発行された証明書等を使用する場合、実ファイルの方を指定すると証明書の更新が行われる毎に、数字の部分が異なる新しいファイルが作成されるため、証明書を指定している設定でファイル名の編集が必要になってしまいます。

それはとても面倒なので、下記のシンボリックリンクを指定するようにしましょう。

  • 証明書 /etc/letsencrypt/live/ホスト名/cert.pem
  • 証明書+中間CA証明書 /etc/letsencrypt/live/ホスト名/fullchain.pem
  • 秘密鍵 /etc/letsencrypt/live/ホスト名/privkey.pem
  • 中間CA証明書 /etc/letsencrypt/live/ホスト名/chain.pem

このシンボリックリンクは、証明書が更新された際に最新のファイルをリンクするように設定されているため、証明書を指定している設定ファイルの編集を行う必要が無くなります。

$ sudo ls -l /etc/letsencrypt/live/ex.server-memo.net
total 4
lrwxrwxrwx 1 root root  42 Dec  6 17:31 cert.pem -> ../../archive/ex.server-memo.net/cert2.pem
lrwxrwxrwx 1 root root  43 Dec  6 17:31 chain.pem -> ../../archive/ex.server-memo.net/chain2.pem
lrwxrwxrwx 1 root root  47 Dec  6 17:31 fullchain.pem -> ../../archive/ex.server-memo.net/fullchain2.pem
lrwxrwxrwx 1 root root  45 Dec  6 17:31 privkey.pem -> ../../archive/ex.server-memo.net/privkey2.pem
-rw-r--r-- 1 root root 692 Dec  6 17:25 README

コメント

  1. ワサビ より:

    質問失礼します。
    当方v6plus環境なので80,443を直接開放ができなく、ASUSのルータのポートフォワーディングで別の番号に設定しました。ufwコマンドも設定した別の2つのポートを追加しました。
    そして、listenの部分も設定したものに変更して取得コマンドを実行したのですが、Timeout during connect (likely firewall problem)とでてきました。
    どのようにすればいいのでしょうか。お力添えいただけますと幸いです。

    • tamohiko より:

      ワサビさん
      コメントありがとうございます。

      質問頂いた件ですが、Let’s EncryptでSSL/TLSの証明書を取得・更新する場合(HTTP-01チャレンジ)は、80(http)または443(https)番ポートを使用します。

      そのため、80、443番ポートを使用できないv6プラス環境では、Let’s EncryptのHTTP-01チャレンジを使用しての証明書を取得・更新を行うことは出来ないみたいです。

      ですが、DNS-01チャンレンジを使用すると、Let’s EncryptでSSL/TLSの証明書を取得・更新することが出来るかもしれません。

      下記コマンドを実行するとDNSのTXTレコードに登録する情報が表示されるので、その情報をDNS登録したあとに処理を実行することで証明書を取得することが出来るようです。

      $ sudo certbot certonly –manual –preferred-challenges dns-01 -m メールアドレス -d ホスト名

      ### 中略 ###

      Please deploy a DNS TXT record under the name
      _acme-challenge.ホスト名 with the following value:

      with the following value:
      TXTレコードに設定する値が表示される

      Before continuing, verify the record is deployed.
      – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
      Press Enter to Continue

      私は実際に試したことはないので、詳しい手順を説明することが出来ませんが、以下のサイトが参考になると思いますので、こちらの情報を参照して試してみてはいかかでしょうか?

      あまりお力になれず、すいませんです。

      https://www.tama-negi.com/2024/02/11/lets-encrypt-dns/
      ※DNS-01 challengeでSSL証明書発行の部分

      https://blog.peddals.com/lets-encrypt-for-apache-dev-site-on-ubuntu/

      • ワサビ より:

        ご返事ありがとうございます。
        ご教授いただいたとおりに設定をしてみたところ無事証明書の取得に成功いたしました。ありがとうございました。

        • tamohiko より:

          ワサビさん

          証明書取得できたとのことで何よりです。
          ご連絡ありがとうございました。

タイトルとURLをコピーしました