🔒

Let's Encryptで証明書を発行・管理する(snap版)

2024/06/04に公開

はじめに

無料でSSL証明書を発行できるLet's Encryptですが、
最近だとsnapを用いた発行を推奨しているようです。(以前までの方法は利用できない)

ただ、ネットで検索するとあまりsnapを利用して証明書を発行・管理する手順が
そこまでまとまっていないので、自分で試してまとめてみました。

前提

・RHEL9
・Webサーバでapache、FTPサーバでvsftpdを利用する
→httpd,mod_sslはインストール済
・マルチドメインで発行
・Aレコードは登録済
・"/var/www/html/"をドキュメントルートにし、外部からアクセスできる状態(TCP80/443ともに)
・HTTP-01チャレンジで発行します
・メールアドレスを1個用意する

証明書発行手順

1.epelインストール
それぞれのOSでepelをインストールする方法が異なりますので、こちらを参照してください。

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

2.snapdインストール

dnf install snapd

3.snapd有効化

# systemctl enable --now snapd.socket

4.coreのインストール

# snap install core

以下、出力例です。

2024-XX-XXTXX:XX:XX+09:00 INFO Waiting for automatic snapd restart...
2024-XX-XXTXX:XX:XX+09:00 INFO Waiting for automatic snapd restart...
Warning: /var/lib/snapd/snap/bin was not found in your $PATH. If you've not restarted your session
         since you installed snapd, try doing that. Please see https://forum.snapcraft.io/t/9469
         for more details.

core XX-X.XX.X from Canonical✓ installed

また、稀に以下のようなメッセージが出て失敗するケースがありますが、
数分時間をおいて実行すれば、成功するかと思います。
(snapインストール後、coreをインストールしようとすると出るようです)

error: too early for operation, device not yet seeded or device model not acknowledged

5.coreのリフレッシュ

# snap refresh core

以下のように出力され、アップデートがないことを確認します。

snap "core" has no updates available

6.certbotコマンドの準備
6-1.certbotのアンインストール
既存のcertbotがインストールされている場合、アンインストールします。

# dnf -y remove certbot

6-2.certbotのインストール

# snap install --classic certbot

以下のように出力され、インストールが完了することを確認します。

Warning: /var/lib/snapd/snap/bin was not found in your $PATH. If you've not restarted your session
         since you installed snapd, try doing that. Please see https://forum.snapcraft.io/t/9469
         for more details.

certbot 2.9.0 from Certbot Project (certbot-eff✓) installed

6-3.シンボリックリンクの作成

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

7.証明書発行
7-1.テスト発行

# certbot certonly --webroot -w /var/www/html/ -d hoge.jp -d www.hoge.jp --dry-run

以下のようにエラーが無ければ問題ありません。

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Simulating a certificate request for hoge.jp and 1 more domains
The dry run was successful.

7-2.証明書発行
問題ない場合は、"--dry-run"をオプションから除き、実行します。

# certbot certonly --webroot -w /var/www/html/ -d hoge.jp -d www.hoge.jp

対話式で、情報を入力していきます。

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): (メールアドレス) ←証明書の有効期限切れのアナウンスなどを受け取るメールアドレスを入力します。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.pdf. You must
agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y ←使用許諾契約書になるため、"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 ←Let's Encryptのプロジェクトに参加するかの選択です。拒否しても特段問題ありません。
Account registered.
Requesting a certificate for hoge.jp and 1 more domains

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/(ドメイン名)/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/(ドメイン名)/privkey.pem
This certificate expires on 2024-06-26.
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
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

8.SSL設定
環境に合わせて、ApacheのSSL設定を行ってください。
※一例

SSLCertificateFile /etc/letsencrypt/live/(ドメイン名)/cert.pem	
SSLCertificateKeyFile /etc/letsencrypt/live/(ドメイン名)/privkey.pem	

証明書自動更新手順

1.手動更新確認
手動でコマンドを実行してみて、エラーがないか念のため確認しておきます。

# certbot renew --dry-run

以下のようにエラーが出なければ問題ないです。

IMPORTANT NOTES:
 - The dry run was successful.

2.更新タイミングの確認
snapd版では、1日2回ほど「ランダム」の時間で証明書の自動更新のチェックが走ります。
起源から30日を切った場合、自動的に証明書の更新がされるような形となります。
チェックのタイミングは、下記の「OnCalendar」に記載されている時間で行われます。

systemctl cat snap.certbot.renew.timer

以下が出力例です。

# /etc/systemd/system/snap.certbot.renew.timer
[Unit]
# Auto-generated, DO NOT EDIT
Description=Timer renew for snap application certbot.renew
Requires=var-lib-snapd-snap-certbot-3643.mount
After=var-lib-snapd-snap-certbot-3643.mount
X-Snappy=yes

[Timer]
Unit=snap.certbot.renew.service
OnCalendar=*-*-* 05:05
OnCalendar=*-*-* 15:38

[Install]
WantedBy=timers.target

また、以下のコマンドで前回の更新した時刻、次回の更新時刻も確認できます。

# systemctl list-timers

以下は出力例の抜粋です。

NEXT                        LEFT       LAST                        PASSED       UNIT                  >
Fri 2024-03-01 19:12:00 JST 8h left    Fri 2024-03-01 05:06:02 JST 5h 55min ago snap.certbot.renew.timer

3.再起動スクリプトの配置
証明書の更新が走った際に、apacheをリロードしないと設定が反映しません。
そのため、証明書の更新が終わった後に、
自動的にリロードするために下記スクリプトを配置します。
"/etc/letsencrypt/renewal-hooks/deploy/"配下にスクリプトを配置すると、
証明書の更新が完了した後に、自動的にそのスクリプトを実行します。
※超簡易的なので、ログなどを出力したい場合は適宜カスタマイズしてください。

# vi /etc/letsencrypt/renewal-hooks/deploy/reload-services.sh

ファイルを新規作成し、以下内容を記載

reload-services.sh
#!/bin/bash
systemctl restart httpd

注意点として、前述したように更新時間はランダムになりますので、
予測できないタイミングでダウンタイムが発生する可能性が高いです。
このため、これを回避するのであれば、
cronで影響の少ない時間にスクリプトを動かしたほうが無難だと思います。

ただ、その場合は証明書の更新タイミングと連動しないため、
これについては予め認識する必要があります。

所感

意外とそこまで苦戦せずに対応できました。
ワイルドカード証明書も発行できるようですが、別の認証方法が必要となります。
また機会を見つけてやってみたいと思います。

Discussion