このセクションでは、Let’s Encrypt で発行するSSL証明書の自動更新と更新した証明書の自動反映について紹介していきます。

今回の作業は、OS が AlmaLinux で Webサービスが Nginx 、OpenSSL が既にインストールされている環境で実施しています。OpenSSL がインストールされていない場合には、別途インストールが必要となります。

必要なパッケージのインストール

snapd(パッケージ管理ツール)をインストールします。

[user@pub-web ~]$ sudo dnf install snapd
Last metadata expiration check: 0:21:46 ago on Mon Aug 14 10:21:32 2023.
Dependencies resolved.
===============================================================================
 Package                         Arch      Version          Repository    Size
===============================================================================
Installing:
 snapd                           x86_64    2.58.3-1.el9     epel          15 M
Installing dependencies:
 bash-completion                 noarch    1:2.11-4.el9     baseos       291 k
 checkpolicy                     x86_64    3.5-1.el9        appstream    345 k
 libpkgconf                      x86_64    1.7.3-10.el9     baseos        35 k
 pkgconf                         x86_64    1.7.3-10.el9     baseos        40 k
 pkgconf-m4                      noarch    1.7.3-10.el9     baseos        14 k
 pkgconf-pkg-config              x86_64    1.7.3-10.el9     baseos       9.9 k
 policycoreutils-python-utils    noarch    3.5-1.el9        appstream     71 k
 python3-audit                   x86_64    3.0.7-103.el9    appstream     83 k
 python3-libsemanage             x86_64    3.5-1.el9        appstream     79 k
 python3-policycoreutils         noarch    3.5-1.el9        appstream    2.0 M
 python3-setools                 x86_64    4.4.1-1.el9      baseos       542 k
 snap-confine                    x86_64    2.58.3-1.el9     epel         2.5 M
 snapd-selinux                   noarch    2.58.3-1.el9     epel         192 k

Transaction Summary
===============================================================================
Install  14 Packages

Total download size: 21 M
Installed size: 70 M
Is this ok [y/N]: y
ーー(省略)ーー

Installed:
  bash-completion-1:2.11-4.el9.noarch                                          
  checkpolicy-3.5-1.el9.x86_64                                                 
  libpkgconf-1.7.3-10.el9.x86_64                                               
  pkgconf-1.7.3-10.el9.x86_64                                                  
  pkgconf-m4-1.7.3-10.el9.noarch                                               
  pkgconf-pkg-config-1.7.3-10.el9.x86_64                                       
  policycoreutils-python-utils-3.5-1.el9.noarch                                
  python3-audit-3.0.7-103.el9.x86_64                                           
  python3-libsemanage-3.5-1.el9.x86_64                                         
  python3-policycoreutils-3.5-1.el9.noarch                                     
  python3-setools-4.4.1-1.el9.x86_64                                           
  snap-confine-2.58.3-1.el9.x86_64                                             
  snapd-2.58.3-1.el9.x86_64                                                    
  snapd-selinux-2.58.3-1.el9.noarch                                            

Complete!
[user@pub-web ~]$ 

snapd.socket(スナップ通信ソケット)の自動起動を有効化します。

[user@pub-web ~]$ sudo systemctl enable --now snapd.socket
Created symlink /etc/systemd/system/sockets.target.wants/snapd.socket → /usr/lib/systemd/system/snapd.socket.
[user@pub-web ~]$ 

[user@pub-web ~]$ sudo systemctl is-enabled snapd.socket
enabled
[user@pub-web ~]$ 

snapd.socket(スナップ通信ソケット)が起動していることを確認します。起動状態でない場合には、起動します。

[user@pub-web ~]$ sudo systemctl status snapd.socket
● snapd.socket - Socket activation for snappy daemon
     Loaded: loaded (/usr/lib/systemd/system/snapd.socket; enabled; preset: disabled)
     Active: active (running) since Sun 2023-08-20 00:49:28 EDT; 10h ago
      Until: Sun 2023-08-20 00:49:28 EDT; 10h ago
   Triggers: ● snapd.service
     Listen: /run/snapd.socket (Stream)
             /run/snapd-snap.socket (Stream)
      Tasks: 0 (limit: 11125)
     Memory: 0B
        CPU: 449us
     CGroup: /system.slice/snapd.socket

Aug 20 00:49:28 pub-web systemd[1]: Starting Socket activation for snappy daemon...
Aug 20 00:49:28 pub-web systemd[1]: Listening on Socket activation for snappy daemon.
[user@pub-web ~]$ 

classic snap サポートを有効化するために、シンボリックリンクを作成します。
classic snapサポートは、システムレベルで動作するソフトウェアをインストールするときに必要になります。

[user@pub-web ~]$ sudo ln -s /var/lib/snapd/snap /snap
[user@pub-web ~]$ 

snapのバージョンを確認しておきます。snap コマンドが通っていれば問題ありません。

[user@pub-web ~]$ sudo snap --version
snap       2.58.3-1.el9
snapd      2.58.3-1.el9
series     16
almalinux  9.2
kernel     5.14.0-284.18.1.el9_2.x86_64
[user@pub-web ~]$ 

snap を使って、certbot パッケージをインストールします。

[user@pub-web ~]$ sudo snap install --classic certbot
[  429.511624] loop0: detected capacity change from 0 to 8
Mount snap "snapd" (19457)                                                     |[  444.360078] systemd-rc-local-generator[4454]: /etc/rc.d/rc.local is not marked executable, skipping.
Mount snap "snapd" (19457)                                                     /[  444.480371] loop0: detected capacity change from 0 to 109072
Setup snap "snapd" (19457) security profiles                                   /[  445.467938] loop1: detected capacity change from 0 to 8
2023-08-14T10:56:12-04:00 INFO Waiting for automatic snapd restart...
Mount snap "core20" (1974)                                                     /[  463.912643] systemd-rc-local-generator[4617]: /etc/rc.d/rc.local is not marked executable, skipping.
Mount snap "core20" (1974)                                                     -[  464.026355] loop1: detected capacity change from 0 to 129944
Mount snap "certbot" (3024)                                                    \[  475.028182] systemd-rc-local-generator[4717]: /etc/rc.d/rc.local is not marked executable, skipping.
Mount snap "certbot" (3024)                                                    |[  475.128110] loop2: detected capacity change from 0 to 90664
Copy snap "certbot" data                                                       /[  475.299124] systemd-rc-local-generator[4768]: /etc/rc.d/rc.local is not marked executable, skipping.
Start snap "certbot" (3024) services                                           \[  475.524481] systemd-rc-local-generator[4796]: /etc/rc.d/rc.local is not marked executable, skipping.
certbot 2.6.0 from Certbot Project (certbot-eff✓) installed
[user@pub-web ~]$ 

/snap/bin/certbotへのシンボリックリンクを作成します。

[user@pub-web ~]$ sudo ln -s /snap/bin/certbot /usr/bin/certbot
[user@pub-web ~]$ 

[user@pub-web ~]$ sudo ls -la /usr/bin/certbot
lrwxrwxrwx. 1 root root 17 Aug 14 11:05 /usr/bin/certbot -> /snap/bin/certbot
[user@pub-web ~]$ 

備考)Let’s Encrypt で SSL証明書を取得するのに必要なクライアントソフト certbot が既にインストールされた環境で作業した場合、/usr/bin/certbot には既にシンボリックリンクが作成されていて、下記のようにシンボリックリンクの作成がエラーとなります。

[user@pub-web ~]$ sudo ln -s /snap/bin/certbot /usr/bin/certbot
ln: failed to create symbolic link '/usr/bin/certbot': File exists
[user@pub-web ~]$ 
[yuji@pub-web ~]$ sudo ls -la /usr/bin/certbot
lrwxrwxrwx. 1 root root 35 May 22 13:48 /usr/bin/certbot -> ../../../../../../usr/bin/certbot-3
[yuji@pub-web ~]$

その場合には、一度現在のシンボリックリンクを解除してから再度シンボリックリンクを作成してみて下さい。

[user@pub-web ~]$ sudo unlink /usr/bin/certbot
[user@pub-web ~]$ 

証明書の自動更新(Let’s Encrypt)

まず、–dry-runオプションを使って証明書の自動更新が正常にいくかどうかテストします。このオプションでは、証明書は更新されずに動作確認のみ実施します。証明書の取得回数制限に引っ掛からないため、何度も試すことができます。

処理がエラーとなる場合には、こちらのトラブルシューティングのページをご確認ください。

[user@pub-web ~]$ sudo certbot renew --dry-run
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/(自ドメイン名).conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Simulating renewal of an existing certificate for (自ドメイン名)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations, all simulated renewals succeeded: 
  /etc/letsencrypt/live/(自ドメイン名)/fullchain.pem (success)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[yuji@pub-web ~]$ 

systemd timer(定期的・定時にコマンドを実行する timer という systemdの機能の一つ)に snap.certbot.renew.timer(証明書更新のための処理)が登録されていることを確認します。snap 版の certbot をインストールすると自動的に登録されるようです。

[user@pub-web ~]$ sudo systemctl list-timers | less

Sun 2023-08-20 12:31:50 EDT 12min left   Sun 2023-08-20 10:42:29 EDT 1h 36min ago dnf-makecache.timer          dnf-makecache.service
Sun 2023-08-20 13:10:33 EDT 51min left   Sun 2023-08-20 01:48:38 EDT 10h ago      certbot-renew.timer          certbot-renew.service
Sun 2023-08-20 15:26:00 EDT 3h 6min left Sun 2023-08-20 06:40:00 EDT 5h 39min ago snap.certbot.renew.timer     snap.certbot.renew.service
Mon 2023-08-21 00:00:00 EDT 11h left     Sun 2023-08-20 00:00:00 EDT 12h ago      logrotate.timer              logrotate.service
Mon 2023-08-21 01:04:28 EDT 12h left     Sun 2023-08-20 01:04:28 EDT 11h ago      systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service

5 timers listed.
Pass --all to see loaded but inactive timers, too.
(END)

snap.certbot.renew.timer のファイルを確認します。

OnCalenderパラメータで指定されている毎日6時40分と15時26分に更新を試みます(更新ごとにランダムに設定時刻が変更します)。

[user@pub-web ~]$ sudo cat /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-3024.mount
After=var-lib-snapd-snap-certbot-3024.mount
X-Snappy=yes

[Timer]
Unit=snap.certbot.renew.service
OnCalendar=*-*-* 06:40
OnCalendar=*-*-* 15:26

[Install]
WantedBy=timers.target
[user@pub-web ~]$ 

snap.certbot.renew.service のファイルも確認してみます。

[user@pub-web ~]$ sudo cat /etc/systemd/system/snap.certbot.renew.service 
[Unit]
# Auto-generated, DO NOT EDIT
Description=Service for snap application certbot.renew
Requires=var-lib-snapd-snap-certbot-3024.mount
Wants=network.target
After=var-lib-snapd-snap-certbot-3024.mount network.target snapd.apparmor.service
X-Snappy=yes

[Service]
EnvironmentFile=-/etc/environment
ExecStart=/usr/bin/snap run --timer="00:00~24:00/2" certbot.renew
SyslogIdentifier=certbot.renew
Restart=no
WorkingDirectory=/var/snap/certbot/3024
TimeoutStopSec=30
Type=oneshot
[user@pub-web ~]$ 

証明書更新後のサーバー反映も自動化

自動更新された証明書を利用するためには、Webサーバー(Nginx)での設定の再読み込みが必要となりますが、Nginx の設定再読み込みは証明書の自動更新の処理には含まれていません。Nginx の設定再読み込みの処理も自動化していきます。

Nginx の設定再読み込みの処理を自動化するファイルを新規作成、編集します。

[user@pub-web ~]$ sudo vi /etc/letsencrypt/renewal-hooks/post/nginx_reload.sh

#!/bin/bash
systemctl reload nginx                                

作成したファイルのパーミッションを変更します。

[user@pub-web ~]$ sudo chmod 755 /etc/letsencrypt/renewal-hooks/post/nginx_reload.sh 
[user@pub-web ~]$  

[user@pub-web ~]$ sudo ls -la /etc/letsencrypt/renewal-hooks/post/
total 4
drwxr-xr-x. 2 root root 29 Aug 20 12:32 .
drwxr-xr-x. 5 root root 43 Aug 14 10:23 ..
-rwxr-xr-x. 1 root root 35 Aug 20 12:32 nginx_reload.sh
[user@pub-web ~]$                               

Let’s Encrypt(certbot)証明書更新時の追加処理について

以下は参考となります。

snap版のcertbotは、/etc/letsencrypt/renewal-hooks/ 以下に作成されたファイルの処理に従って自動的に追加処理が行われる仕組みなっています。そして、renewal-hooks 直下には3つのディレクトリがあり、ファイルをどのディレクトリに作成するかによって処理が実行されるトリガーが異なっています。

[user@pub-web ~]$ sudo ls -la /etc/letsencrypt/renewal-hooks/
drwxr-xr-x. 5 root root   43 Aug 14 10:23 .
drwxr-xr-x. 7 root root 4096 Aug 20 12:34 ..
drwxr-xr-x. 2 root root    6 Aug 14 10:23 deploy
drwxr-xr-x. 2 root root   29 Aug 20 13:17 post
drwxr-xr-x. 2 root root    6 Aug 14 10:23 pre
[user@pub-web ~]$ 
ディレクトリ追加処理を実行するトリガー
precertbotが全部の証明書更新の処理を始める前に証明書の更新の有無に関わらず必ず実行されます
postcertbotが全部の証明書更新の処理を終わった後で証明書の更新の有無に関わらず必ず実行されます
deploycertbotが個々の証明書更新の処理を終わった後で証明書の更新された場合にだけ実行されます