🔐

Certbot公式に従ってNginxを常時SSL化

2022/08/16に公開

認証局といえばLet's encrypt、Let's encryptといえばCertbot。今回はCertbot公式にしたがって常時SSL化していく。

環境は以下の通り。

VPS: Vultr
OS: RHEL9
Web Server: nginx-1.23.0

下準備

FirewallでHTTPSと443番ポートの通信を許可する

$ sudo firewall-cmd --permanent --add-service=https --zone=public
$ sudo firewall-cmd --reload

Nginxインストール

$ sudo dnf install nginx

バージョン確認する。

$ nginx -v

nginx.confを編集する。

$ sudo vi /etc/nginx/nginx.conf
nginx.conf
~前略~
    
    server {
        listen       80;
        listen       [::]:80;
        server_name  excample.com; # ドメイン名を記載
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
    }

~後略~

Nginxを起動する。

$ systemctl start nginx

設定してあるURLを見に行き、デフォルトページが表示されていればOK。

RHEL9ではこんなページが表示される。

Certbot

Certbot公式サイトでは、親切なことに、よくある環境で手順を検索できるようになっている。

あいにくRHELはなかったので、Nginx × CentOS8に設定する。
ここからは、サイトの手順をたどりながら設定していく。

1. サーバにSSH接続

これは既に接続済みなので割愛する。
当時の備忘録はこれ。
https://zenn.dev/hitoshiro/articles/20443bcda5d7f9

2. snapdをインストール

snapdとはなんぞや?

クロスプラットフォームなパッケージ管理ツールのようだ。パッケージ管理ツールは、RHEL系ならyumとかdnf、Ubuntuならaptと分かれていたが、snapdは現在21種類のLinuxプラットフォームで使えるらしい。ほー。

Certbotはsnapd経由で配布しているようなので、インストールする。案内にしたがい、snapd公式のインストール手順を読む。

https://snapcraft.io/docs/installing-snap-on-red-hat

RHEL8までの記載しかないが、まあRHEL9でもいけるでしょう(フラグ)。

2-1. EPELリポジトリをインストール

snapdはEPELリポジトリで配布されているので、インストールする。EPEL公式にRHEL9向けのクイックスタートが記載されているので、そのまま使う。
https://docs.fedoraproject.org/en-US/epel/#_el9

sudo subscription-manager repos --enable codeready-builder-for-rhel-9-$(arch)-rpms
sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm

2-2. snapdをインストール

sudo dnf install snapd # snapdインストール
sudo systemctl enable --now snapd.socket  # snapd有効化

3. snapdのバージョンが最新であることを確認する

$ sudo snap install core # snapdでcoreをインストール
2022-08-16T15:54:59+09:00 INFO Waiting for automatic snapd restart...
core 16-2.56.2 from Canonical** installed
$ sudo snap refresh core # coreを最新版にアップデート
snap "core" has no updates available # アップデートするものがないよ

4. certbot-autoおよびすべてのCertbot OSパッケージを削除する

要はほかのパッケージ管理ツール(yumとか)からCertbotをインストールしているなら削除してね、ということだ。まっさらなRHELからのスタートなので、この手順は飛ばす。

5. Certbotをインストール

$ sudo snap install --classic certbot
error: cannot install "certbot": classic confinement requires snaps under /snap or symlink from
       /snap to /var/lib/snapd/snap

error: cannot install "certbot": classic confinement requires snaps under /snap or symlink from /var/lib/snapd/snap.
/を /var/lib/snapd/snap にシンボリックリンクする必要があります。

Certbotはsnapdのクラシックモード(セキュリティ制限なし)でインストールしないとエラーが出るようだが、そもそもクラシックモードを使うためにシンボリックリンクを作成する必要があるようだ。
snapd公式ガイドで、クラシックモードを有効にするための説明がある。

To enable classic snap support, enter the following to create a symbolic link between /var/lib/snapd/snap and /snap:

$ sudo ln -s /var/lib/snapd/snap /snap

この通りにして、再度Certbotをインストールする。

$ sudo snap install --classic certbot
certbot 1.29.0 from Certbot Project (certbot-eff**) installed

成功した。

6. Certbotコマンドの準備

certbotファイルのシンボリックリンクを作成する。

sudo ln -s /snap/bin/certbot /usr/bin/certbot

7. Certbotの実行

$ sudo certbot --nginx

このコマンドを実行すると、

  • 証明書の取得
  • Certbotがnginxの設定を自動的に編集して証明書を提供
  • ワンステップで HTTPS アクセスを有効

以上をまとめて実施してくれる。なんて便利なんだ。ありがたく実行する。

$ sudo certbot --nginx
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices) # 緊急の更新やセキュリティのお知らせのため、メールアドレスを入力。空欄でもよい。
 (Enter 'c' to cancel):12345@mail.com
 
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y # 証明書自動更新に必要なサーバへの利用規約に同意する

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, 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 # Certbotの運営団体にメアドを教えていい? ニュースとか送ります。とある。好きなように答える。

Account registered.
Please enter the domain name(s) you would like on your certificate (comma and/or
space separated) (Enter 'c' to cancel):example.com
# 証明書に記載するドメイン名を入力する。カンマやスペース区切りで複数個記載できる。

8. 自動更新のテスト

The Certbot packages on your system come with a cron job or systemd timer that will renew your certificates automatically before they expire. You will not need to run Certbot again, unless you change your configuration. You can test automatic renewal for your certificates by running this command:

あなたのシステムのCertbotパッケージには、証明書が期限切れになる前に自動的に更新するcronジョブまたはsystemdタイマーが付属しています。設定を変更しない限り、Certbot を再度実行する必要はありません。このコマンドを実行することで、証明書の自動更新をテストすることができます。

ありがたすぎる。ということで、さっそくテストする。

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

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/excample.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Simulating renewal of an existing certificate for dev.variants-saga.net

Certbot failed to authenticate some domains (authenticator: nginx). The Certificate Authority reported these problems:
  Domain: excample.com
  Type:   unauthorized
  Detail: 45.76.97.87: Invalid response from http://excample.com/.well-known/acme-challenge/sC8xuUk4kr19nO5okzXpiQTG6xx5NddiZcOM6GKxF6A: 404

Hint: The Certificate Authority failed to verify the temporary nginx configuration changes made by Certbot. Ensure the listed domains point to this nginx server and that it is accessible from the internet.

Failed to renew certificate dev.variants-saga.net with error: Some challenges have failed.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
All simulated renewals failed. The following certificates could not be renewed:
  /etc/letsencrypt/live/dev.variants-saga.net/fullchain.pem (failure)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1 renew failure(s), 0 parse failure(s)
Ask for help or search for solutions at https://community.letsencrypt.org. See the logfile /var/log/letsencrypt/letsencrypt.log or re-run Certbot with -v for more details.

更新に失敗している。
エラー文から怪しそうなところを探す。

Certbot failed to authenticate some domains (authenticator: nginx). The Certificate Authority reported these problems:
  Domain: excample.com
  Type:   unauthorized
  Detail: 45.76.97.87: Invalid response from http://excample.com/.well-known/acme-challenge/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX: 404

excample.com/.well-known/acme-challenge/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXにアクセスできないことが原因のようだ。
どうやら証明書の更新のとき、/.well-known/acme-challengeディレクトリに一時的なファイルを作っているらしい。
Webのrootパスがどこかを指定すると無事にいくそうなので、指定して再実行する。

$ sudo certbot certonly --nginx -w /usr/share/nginx/html -d example.com
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Certificate not yet due for renewal

You have an existing certificate that has exactly the same domains or certificate name you requested and isn't close to expiry.
(ref: /etc/letsencrypt/renewal/dev.variants-saga.net.conf)

What would you like to do?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: Keep the existing certificate for now
2: Renew & replace the certificate (may be subject to CA rate limits)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2 # 再発行するので2番を選ぶ
Renewing an existing certificate for example.com

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/dev.variants-saga.net/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/dev.variants-saga.net/privkey.pem
This certificate expires on 2022-11-14.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

うまくいったようだ!

9. Certbotが動作したことを確認する

さっそくブラウザにURLを入力し、確認する。

鍵マークをクリックして確認した

やった~!!!

Discussion