LinuxサーバーでLet's Encrypt自動更新がエラーとなる時のチェック項目

[環境](#環境)
[1)証明書の手動更新](#1証明書の手動更新)
[2)証明書の自動更新](#2証明書の自動更新)
[snap版certbot設定](#snap版certbot設定)
[自動更新シェルスクリプト](#自動更新シェルスクリプト)
[参考記事](#参考記事)



#環境
CentOS7
Apache2.4

まず、手動更新してみる
A:手動更新が成功→自動更新に問題あり
B:手動更新で失敗→更新自体に問題あり

#1)証明書の手動更新

###1-1)手動更新

```
# certbot renew
```

A：更新できたら1-2)再起動
B：更新失敗したら1-5)certbot renewエラー確認

###1-2)再起動

```
# systemctl restart httpd
```

###1-3)ブラウザで証明書期限の日付を確認

A：日付が３ヶ月後になっていたら成功→次に2-1)
B：日付が更新されていないなら1-4)アパッチのssl.conf設定かバーチャルドメイン設定を確認

###1-4)アパッチのssl.conf設定かバーチャルドメイン設定を確認

証明書ファイルの確認

```
# ls /etc/letsencrypt/archive/<ドメイン名>/

cert.pem  chain.pem  fullchain.pem  privkey.pem
```

ssl.conf設定を使っているなら

```:#&nbsp;vim&nbsp;/etc/httpd/conf.d/ssl.conf
SSLCertificateFile /etc/letsencrypt/live/[ドメイン]/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/[ドメイン]/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/[ドメイン]/chain.pem
```

バーチャルドメイン設定
```:#&nbsp;vim&nbsp;/etc/httpd/conf.d/virtual.conf
SSLCertificateFile /etc/letsencrypt/live/[ドメイン]/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/[ドメイン]/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/[ドメイン]/chain.pem
```

Apache再起動

```
# systemctl restart httpd
```

###1-5)certbot renewエラー確認

```
更新失敗時のエラーコード

Detail: Invalid response from
   https://＜ドメイン名＞/.well-known/acme-challenge/ZOUcJL25kxy5g4zLN_E5Qs8Sc4mimt5ht4_i9huMCgI
```
/.well-known/acme-challenge/にアクセスできずに失敗している模様

Let's Encryptのconfファイルの設定を確認する
正しければ下記のようになってるはず

```:#&nbsp;vim&nbsp;/etc/letsencrypt/renewal/example.com.conf
[renewalparams]
webroot_path = /var/www/html/example.com/public,
[[webroot_map]]
example.com = /var/www/html/example.com/public

```

ここが、

```:#&nbsp;vim&nbsp;/etc/letsencrypt/renewal/example.com.conf
[renewalparams]
webroot_path = /var/www/certbot/example.com/public,
[[webroot_map]]
記載なし

```

上記のように修正

改めて手動更新

```
# certbot renew

Congratulations, all renewals succeeded: 
  /etc/letsencrypt/live/example.com/fullchain.pem (success)
```

手動更新に成功

#2)証明書の自動更新
2a：Snap版certbotでの定期更新
2b：Cronでの定期更新
上記 a,b どちらかでよい

#snap版certbot設定
###2a-1)Snap版certbot設定の確認

systemdのタイマー機能を確認

```:#&nbsp;systemctl&nbsp;list-timers&nbsp;|&nbsp;less
NEXT                         LEFT          LAST                         PASSED       UNIT                         ACTIVATES
金 2021-04-09 18:53:31 JST  1h 40min left 木 2021-04-08 18:53:31 JST  22h ago      systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
土 2021-04-10 02:55:00 JST  9h left       金 2021-04-09 15:56:01 JST  1h 17min ago snap.certbot.renew.timer     snap.certbot.renew.service
```

`snap.certbot.renew.timer`が設定されていることを確認する

snap.certbot.renew.timer のユニットファイルを確認

```:#&nbsp;view#&nbsp;/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-1093.mount
After=var-lib-snapd-snap-certbot-1093.mount
X-Snappy=yes
 
[Timer]
Unit=snap.certbot.renew.service
OnCalendar=*-*-* 02:55
OnCalendar=*-*-* 15:56
 
[Install]
WantedBy=timers.target
```

snap.certbot.renew.serviceのユニットファイルを確認

```:#&nbsp;view#&nbsp;/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-1093.mount
Wants=network.target
After=var-lib-snapd-snap-certbot-1093.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/1093
TimeoutStopSec=30
Type=oneshot
 
[Install]
WantedBy=multi-user.target
```

###2a-1)Apacheの自動再起動を設定

```:#&nbsp;vim&nbsp;/etc/letsencrypt/renewal-hooks/post/web_restart.sh
#!/bin/bash
systemctl restart httpd
```

パーミッションの変更

```
# chmod 755 /etc/letsencrypt/renewal-hooks/post/web_restart.sh
```

Snap版certbotでの定期更新設定は以上

#自動更新シェルスクリプト
###2b-1)自動更新シェルスクリプトの確認

```:#&nbsp;vim&nbsp;/root/bin/update_sslcert.sh
#!/bin/bash
#
CERTBOT_CMD=/usr/bin/certbot
WEBSERVER_RESTART_CMD="systemctl restart httpd"
 
MAILTO=<メール通知先アドレス>
 
echo "===== Update SSL Certfile ====="
echo "`date` Update SSL Certfile start"
 
# 証明書の更新
${CERTBOT_CMD} renew \
  --post-hook "${WEBSERVER_RESTART_CMD}"
 
LE_STATUS=$?
 
# 証明書の取得に失敗したときはメールで通知
if [ "$LE_STATUS" != 0 ]; then
    echo "Update SSL Certfile failed" |\
    mail -s "Update SSL Certfile in `hostname`" ${MAILTO}
fi
 
echo "`date` Update SSL Certfile end"
 
# EOF
```

ファイルの権限設定

```
# chmod 755 /root/bin/update_sslcert.sh
```

シェルスクリプトの動作確認

動作確認の仮設定

```:#&nbsp;vim&nbsp;/root/bin/update_sslcert.sh
-- 変更前
...
 
${CERTBOT_CMD} renew \
  --post-hook "${WEBSERVER_RESTART_CMD}"
--
 
-- 変更後
...
 
${CERTBOT_CMD} renew \
  --post-hook "${WEBSERVER_RESTART_CMD}" --force-renewal
--
```

シェルスクリプトの実行

```
# /root/bin/update_sslcert.sh

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations, all renewals succeeded: 
  /etc/letsencrypt/live/example.com/fullchain.pem (success)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Running post-hook command: /etc/letsencrypt/renewal-hooks/post/web_restart.sh
Running post-hook command: systemctl restart httpd

```

`Congratulations, all renewals succeeded:`
が表示されればテスト成功

###2b-2)更新の確認

ブラウザでの証明書確認

psでの確認

```
# ps aux | grep httpd

root      2253  0.0  0.0 112828   980 pts/0    S+   15:48   0:00 grep --color=auto httpd
```

エラーログで確認

```
# less /var/log/httpd/error_log
```

シンボリックリンクのタイムスタンプの確認

```:#&nbsp;ls&nbsp;-l&nbsp;/etc/letsencrypt/live/example.com
合計 4
-rw-r--r-- 1 root root 692  8月 23 10:33 README
lrwxrwxrwx 1 root root  34 10月 24 15:42 cert.pem -> ../../archive/example.com/cert4.pem
lrwxrwxrwx 1 root root  35 10月 24 15:42 chain.pem -> ../../archive/example.com/chain4.pem
lrwxrwxrwx 1 root root  39 10月 24 15:42 fullchain.pem -> ../../archive/example.com/fullchain4.pem
lrwxrwxrwx 1 root root  37 10月 24 15:42 privkey.pem -> ../../archive/example.com/privkey4.pem
```

###2b-3)シェルスクリプトの定期実行設定

```
# Update SSL Cert File
0 5 * * 1 /root/bin/update_sslcert.sh 1>> /var/log/update_sslcert.log 2>&1
```

毎週月曜日午前5時に更新の意味

時刻設定
＊（分）　＊（時）　＊（週）　＊（月）　＊（年）
`https://memo.morelents.com/crontab-setting/`　

テストとして数分後に設定してみる

```
45 15 * * * /root/bin/update_sslcert.sh 1>> /var/log/update_sslcert.log 2>&1
```

毎日16時05分に更新の意味
現在時刻の数分後に設定し、その時間を待つ
作動したかどうか確認

```
less /var/log/update_sslcert.log

===== Update SSL Certfile =====
2021年 10月 24日 日曜日 16:05:01 JST Update SSL Certfile start
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/example.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert not yet due for renewal


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The following certificates are not due for renewal yet:
  /etc/letsencrypt/live/example.com/fullchain.pem expires on 2022-01-22 (skipped)
No renewals were attempted.
No hooks were run.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2021年 10月 24日 日曜日 16:05:02 JST Update SSL Certfile end

```

***
#参考記事
`https://bank-of-clouds.com/lets-encrypt-renewal-fail-recovery`
`https://inaba-serverdesign.jp/blog/20210331/snap-lets-encrypt-ssl-certificate-update.html`
`https://inaba-serverdesign.jp/blog/20210331/snap-lets-encrypt-ssl-certificate-update.html`