certbot が SSL/TLS 証明書の更新に失敗し始めたのを直す (Let’s Encrypt)

2021-11-20

#Linux #Webデザイン letsencrypt TLS/SSL コマンドライン

Let’s Encrypt で取得した SSL/TLS サーバー証明書が失効間近になっていた。
まもなく有効期限切れの警告メールが来ていたのだけど見逃していて、スマホが教えてくれてようやく気づく。

Let’s Encrypt certificate expiration notice for domain “example.com” (and 1 more)

Your certificate (or certificates) for the names listed below will expire in 10 days (on 20 Nov 21 16:50 +0000). Please make sure to renew your certificate before then, or visitors to your web site will encounter errors.

どれどれ更新期限は…今日!どうしてこうなった!

certbot で期限を更新できなくなっている

これまで Cron で certbot renew を実行して自動更新していて、ずっと問題なく更新できてたけど、ログを見ると何らかの理由で更新に失敗している模様。

yum update してから改めて certbot を実行してみると、やはりエラー。

# /usr/bin/certbot renew
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/example.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert is due for renewal, auto-renewing...
Plugins selected: Authenticator webroot, Installer None
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org
Failed to renew certificate example.com with error: ("bad handshake: Error([('SSL
routines', 'ssl3_get_server_certificate', 'certificate verify failed')],)",)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
All renewals failed. The following certificates could not be renewed:
  /etc/letsencrypt/live/example.com/fullchain.pem (failure)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1 renew failure(s), 0 parse failure(s)

更新できない原因

調べてみたところ、原因は certbot のバージョンが古いことでした。
CentOS の yum コマンドからは certbot を最新版に更新できなくなり、今後は snap でインストールとアップデートを行う模様。

※ snap は Ubuntu の開発元が作った、複数のディストリビューションに対応した比較的新しいパッケージ管理システム。(Snappy - Wikipedia)

certbot の公式サイトを確認

Certbot の公式サイトがいつの間にか出来ていたようなので、そちらでインストール手順を確認する。
サイトを開き、中段の “My HTTP website is running …” のところで Software と System を選択すると、環境毎のインストール方法が出てくる。

Apache / CentOS 7 の場合は下記のページが表示される。

最新版のインストール

最初に snap をインストールしてから、旧バージョンの certbot をアンインストールし、snap で最新版の certbot をインストールする。手順には特に難しい所はなく、数分で完了する。

上記の公式情報は英語かつ情報量が多いので要約すると、サーバにSSHで接続して、下記のコマンドを順次実行すれば良い。(手順は Apache, nginx の何れも同様)

インストールの準備 (CentOS 7)

snap のデーモン snapd は CentOS 7.6 以降の対応なので、OS のバージョンが古い場合は先にアップグレードしておく。

snapd は EPEL リポジトリにある。
まだ yum に EPEL が無ければ sudo yum install epel-release で追加しておく。

snapd をインストール

sudo yum install snapd で snapd をインストールする。

続いて sudo systemctl enable --now snapd.socket で snapd を有効化。
sudo ln -s /var/lib/snapd/snap /snap で snap のシンボリックリンクを作成。

再ログインまたは再起動して、snap が動作することを確認する。

core をインストール

次に sudo snap install core を実行。

# sudo snap install core
error: too early for operation, device not yet seeded or device model not acknowledged

上記のようにエラーが出ることがあるが、数分待ってから再実行すればインストールできる。
続いて sudo snap refresh core で最新バージョン確認。

# sudo snap install core
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 16-2.52.1 from Canonical✓ installed

# sudo snap refresh core
snap "core" has no updates available

古い certbot をアンインストール

既存の古い certbot をアンインストール。

# sudo yum remove certbot
…
削除しました:
  certbot.noarch 0:1.11.0-2.el7

依存性の削除をしました:
  python2-certbot-apache.noarch 0:1.11.0-1.el7

完了しました!

新しい certbot をインストール

最新版の certbot をインストールする。

# sudo snap install --classic certbot
certbot 1.21.0 from Certbot Project (certbot-eff✓) installed

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

以上で certbot が動作するようになる。
なお、公式の説明文は新規の証明書取得を想定しているので、証明書を既に取得している場合、この先の手順は必要ない。

SSL/TLS サーバー証明書の更新

急ぎであれば手動で certbot renew を実行して、証明書を更新する。

# sudo certbot renew
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/example.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Renewing an existing certificate for example.com

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

# sudo service httpd restart
Redirecting to /bin/systemctl restart httpd.service

無事更新できました。

参考サイト

QooQ