本日、無料SSLでおなじみのLet’s Encryptの更新チェック(certbot renew)をかけたら見慣れないエラーが発生して更新チェックが失敗する。
エラー内容はこれ↓
# certbot renew
Traceback (most recent call last):
File "/usr/bin/certbot", line 5, in <module>
from pkg_resources import load_entry_point
File "/usr/lib/python2.7/site-packages/pkg_resources.py", line 3011, in <module>
parse_requirements(__requires__), Environment()
File "/usr/lib/python2.7/site-packages/pkg_resources.py", line 626, in resolve
raise DistributionNotFound(req)
pkg_resources.DistributionNotFound: acme>=0.29.0
これを正常に更新(certbot renew)できるようにします。
【※2019/08/22追記】
以下のようなエラーが出たのでその原因と対策もこの記事の末尾に追記しました。
Failed authorization procedure. example.com (http-01): urn:ietf:params:acme:error:unauthorized :: The client lacks sufficient authorization :: The key authorization file from the server did not match this challenge "HwKeeTrzduQn-3HoAeKIYWClB3zWYD2J8WT4L3JAcsA.6ImYOpAcwK75qQhLNsCDTKG-rmAZyaEyUOpjrHmnUus" != "example.com"
※動作環境
CentOS Linux 7.6
原因調査&対策
いつもLet’s Encryptの更新チェック(certbot renew)を行う際は、
# yum -y --enablerepo=epel update certbot
にて確認のために事前にcertbotのアップデートを行うのだが、その際に
- certbot.noarch 0:0.29.1-1.el7
- python2-certbot.noarch 0:0.29.1-1.el7
の2つがアップデートされたのでcertbot関連の依存関係のエラーという可能性が高い。
エラーメッセージの末尾にも、
「pkg_resources.DistributionNotFound: acme>=0.29.0」
(和訳:acmeのバージョン0.29.0以上が無い)と書いてあるので、「acme」をyumで検索してみる。
# yum search acme
読み込んだプラグイン:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
* base: ftp.iij.ad.jp
* extras: ftp.iij.ad.jp
* remi-safe: ftp.riken.jp
* updates: ftp.iij.ad.jp
================================================== N/S matched: acme ==================================================
python2-acme.noarch : Python library for the ACME protocol
httpd24-mod_md.x86_64 : Certificate provisioning using ACME for the Apache HTTP Server
Name and summary matches only, use "search all" for everything.
python2-acme.noarchというのを発見。
これを更新すればOKっぽい。
これですぐに解決すると思ったが、
yum update python2-acme
で更新を試してもアップデートが存在しない。
そこでふと「certbot 関連のリポジトリはepel」と思い出し、epelを許可して、
yum –enablerepo=epel update python2-acme
で更新をかけてみる。
# yum --enablerepo=epel update python2-acme
読み込んだプラグイン:fastestmirror
Loading mirror speeds from cached hostfile
* base: ftp.iij.ad.jp
* epel: ftp.riken.jp
* extras: ftp.iij.ad.jp
* remi-safe: ftp.riken.jp
* updates: ftp.iij.ad.jp
依存性の解決をしています
--> トランザクションの確認を実行しています。
---> パッケージ python2-acme.noarch 0:0.26.1-1.el7 を 更新
---> パッケージ python2-acme.noarch 0:0.29.1-1.el7 を アップデート
--> 依存性解決を終了しました。
依存性を解決しました
=======================================================================================================================
Package アーキテクチャー バージョン リポジトリー 容量
=======================================================================================================================
更新します:
python2-acme noarch 0.29.1-1.el7 epel 146 k
トランザクションの要約
=======================================================================================================================
更新 1 パッケージ
総ダウンロード容量: 146 k
Is this ok [y/d/N]: y
Downloading packages:
epel/x86_64/prestodelta | 3.7 kB 00:00:00
python2-acme-0.29.1-1.el7.noarch.rpm | 146 kB 00:00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
更新します : python2-acme-0.29.1-1.el7.noarch 1/2
整理中 : python2-acme-0.26.1-1.el7.noarch 2/2
検証中 : python2-acme-0.29.1-1.el7.noarch 1/2
検証中 : python2-acme-0.26.1-1.el7.noarch 2/2
更新:
python2-acme.noarch 0:0.29.1-1.el7
完了しました!
無事python2-acmeのアップデートが完了。
うっかりpython2-acmeのバージョンがずいぶんと古かったみたいですね…。
もう一度、エラーでこけたLet’s Encryptの更新チェック(certbot renew)を試してみる。
# certbot renew
Saving debug log to /var/log/letsencrypt/letsencrypt.log
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/onoredekaiketsu.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert not yet due for renewal
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The following certs are not due for renewal yet:
/etc/letsencrypt/live/onoredekaiketsu.com/fullchain.pem expires on 2019-02-07 (skipped)
No renewals were attempted.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
certbot renewが正常に終了し、Let’s Encryptの更新チェックが正常に完了しました。
まとめ
certbot renewを行った際に、末尾が「pkg_resources.DistributionNotFound: acme>=0.29.0」というエラーを吐いたら、
# yum --enablerepo=epel update python2-acme
でpython2-acmeを更新すればOKです。
以上で解決です。
【※ポイント】
「pkg_resources.DistributionNotFound: パッケージ名>=~」系のエラーが出たら、yumで「–enablerepo=epel」を付けて指定されたパッケージをインストール又はアップデートすれば大抵のエラーは直ります。
Let’s Encryptの証明書を削除する方法
おまけですが、SSL設定に失敗して一からやり直す際や、ドメインを使わなくなった際などでLet’s Encryptの証明書を削除する方法も記載しておきます。
まず「certbot certificates」を実行して既存の証明書一覧を確認する。
# certbot certificates
不要なドメイン名(又はホスト名)を「certbot delete –cert-name」で削除する。
# certbot delete --cert-name ドメイン名
正常に削除されたか「certbot certificates」で確認する。
# certbot certificates
最後に証明書のパスが記入されていたNginx、Apache、postfix、Dovecot、ProFTPDなどの各種サーバーの設定ファイルから削除したドメインの証明書のパスを削除して各種サーバーを全て再起動します。
以上でLet’s Encryptの証明書の削除は完了です。
おまけ(SSL証明書の更新をcronで自動実行)
うっかりミスでLet’s EncryptのSSL証明書の更新を忘れてしまい、ある日突然SSLが無効にならないように、SSL証明書の更新作業はcronで自動化しておきましょう。
以下のページで解説しています。
cronによる自動化設定はとても簡単ですのでやっておきましょう。
【※2019/08/22追記】The key authorization file from the server did not matchエラーの対策
あるドメインでまた見慣れないcertbot関連のエラーが発生しました。以下がそのエラーです。
Failed authorization procedure. example.com (http-01): urn:ietf:params:acme:error:unauthorized :: The client lacks sufficient authorization :: The key authorization file from the server did not match this challenge "HwKeeTrzduQn-3HoAeKIYWClB3zWYD2J8WT4L3JAcsA.6ImYOpAcwK75qQhLNsCDTKG-rmAZyaEyUOpjrHmnUus" != "example.com"
IMPORTANT NOTES:
- The following errors were reported by the server:
Domain: example.com
Type: unauthorized
Detail: The key authorization file from the server did not match
this challenge
"HwKeeTrzduQn-3HoAeKIYWClB3zWYD2J8WT4L3JAcsA.6ImYOpAcwK75qQhLNsCDTKG-rmAZyaEyUOpjrHmnUus"
!= "example.com"
To fix these errors, please make sure that your domain name was
entered correctly and the DNS A/AAAA record(s) for that domain
contain(s) the right IP address.
色々と調べながら試行錯誤を繰り返していたら原因が判明。
原因は、ドメインの「www無し」を「www有り」に転送するために、Nginxのserverディレクティブを追加したのだが、その記述内容に不備があったためでした。
server {
server_name example.com;
listen xxx.xxx.xxx.xxx:80;
return 301 https://www.example.com;
root /home/example.com/public_html;
}
これを以下のように修正。
(※4行目の転送先URLの末尾に$request_uriを追加)
server {
server_name example.com;
listen xxx.xxx.xxx.xxx:80;
return 301 https://www.example.com$request_uri;
root /home/example.com/public_html;
}
【原因の詳細】
転送先の「www有りURL」の末尾に$request_uriを追加していなかったので、Let’s EncryptのBotがアクセスしてくる際に、認証に利用される.well-knownディレクトリへのアクセスまでwww有りURLのトップページに転送してしまうためでした。
単なるイージーミスです。みなさんもイージーミスには気を付けましょう。
以上で解決です。


