Amazon Linux 上の Let’s Encrypt で証明書更新エラーが出た時の対処方法

最近は無料で SSL/TLS のサーバー証明書が取得できるサービスがボチボチあって、
個人でも気軽に取得・利用できるようになっており、
「良い時代になったなー」なんて思ってるおじさんエンジニアのよしかわです。

このブログ https://blog.yskw.info/ でも、
Let’s Encrypt による無料のサーバー証明書を利用させてもらっています。

Let’s Encrypt で取得できる証明書は期限が 90 日となっている為、
およそ 3 か月に一回証明書を更新する必要が有ります。

更新の方法自体はとってもシンプル。

certbot-auto renew

を実行するだけです。

…が、今回 AmazonLinux 上で certbot-auto を起動しようとしたらこんなエラーが。

$ ./certbot-auto renew
Upgrading certbot-auto 0.8.1 to 0.9.1...
Replacing certbot-auto...
Creating virtual environment...
Installing Python packages...
Installation succeeded.
Traceback (most recent call last):
  File "/root/.local/share/letsencrypt/bin/letsencrypt", line 7, in <module>
    from certbot.main import main
  File "/root/.local/share/letsencrypt/local/lib/python2.7/dist-packages/certbot/main.py", line 12, in <module>
    import zope.component
  File "/root/.local/share/letsencrypt/local/lib/python2.7/dist-packages/zope/component/__init__.py", line 16, in <module>
    from zope.interface import Interface
ImportError: No module named interface

ちなみに、インストールした時は certbot-auto のバージョンは 0.8.1。
今回の実行で自動的に 0.9.1 にアップグレードされました。
(上記ログの最初の行でアップグレードされたことが判ります。)

先日 python のバージョンアップしちゃったので、これのせいかなぁ…

# grep -i python27-2.7 yum.log
Aug 01 17:11:58 Updated: python27-2.7.10-4.122.amzn1.x86_64
Sep 02 18:38:06 Updated: python27-2.7.12-2.120.amzn1.x86_64

と思いつつ、エラーメッセージでググってみると、stackoverflow にて同様のエラーに遭遇した方発見。

Letsencrypt ImportError: No module named interface on amazon linux while renewing

unset PYTHON_INSTALL_LAYOUT を実行せよとの事だけど、そんな環境変数設定されてるの?
と思ったら、設定されていました。

$ env | grep PYTHON_INSTALL_LAYOUT
PYTHON_INSTALL_LAYOUT=amzn

上記記事からリンクされてたこのエントリの情報に従って、対処していきます。
Facing problem while renewing letsencrypt Certificates – ImportError: No module named interface Amazon Linux

まず環境変数を削除

$ unset PYTHON_INSTALL_LAYOUT
$ env | grep PYTHON_INSTALL_LAYOUT # 設定が無くなった事を確認

certbot-auto を再実行

$ ./certbot-auto -v

(2017/03 追記)

環境変数を unset した後も下記のようなエラーが出る場合

Error: couldn't get currently installed version for /root/.local/share/letsencrypt/bin/letsencrypt:
Traceback (most recent call last):
 File "/root/.local/share/letsencrypt/bin/letsencrypt", line 7, in <module>
 from certbot.main import main
 File "/root/.local/share/letsencrypt/local/lib/python2.7/dist-packages/certbot/main.py", line 11, in <module>
 import zope.component
 File "/root/.local/share/letsencrypt/local/lib/python2.7/dist-packages/zope/component/__init__.py", line 16, in <module>
 from zope.interface import Interface
ImportError: No module named interface

~/.local ディレクトリをいったん削除したうえで

./certbot-auto -v --debug

とすれば、環境構築からやり直せます。

…が、python を使って作業をされている方は要注意かもしれません。
私は python 全然使った事無いので、環境再構築でも困らないのですが。

(追記ココまで。)

(2017/11 追記)

気が付いたら ~/.local 削除してもエラー出るようになっていました。

https://github.com/certbot/certbot/issues/5100
こちらの投稿を参考にして下記コマンド実行後、renew -a debug したら更新できて一安心。

unset PYTHON_INSTALL_LAYOUT
/opt/eff.org/certbot/venv/local/bin/pip install --upgrade certbot

# もう何やってるか判らないから正直ちょっとまずいですわ…

(追記ココまで。)

途中でドメインを聞かれたので、証明書を発行しているドメインを入力

No names were found in your configuration files. Please enter in your domain
name(s) (comma and/or space separated) (Enter 'c' to cancel): yskw.info

※ これ、もしかすると既存の証明書を上書きしてしまうかも…?

certbot-auto -v が終わったら、renew を実施

$ ./certbot-auto renew
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/blog.yskw.info.conf
-------------------------------------------------------------------------------
Cert is due for renewal, auto-renewing...
Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for yskw.info
http-01 challenge for blog.yskw.info
Waiting for verification...
Cleaning up challenges
Unable to clean up challenge directory /var/www/html/blog.yskw.info/.well-known/acme-challenge
Generating key (2048 bits): /etc/letsencrypt/keys/0003_key-certbot.pem
Creating CSR: /etc/letsencrypt/csr/0003_csr-certbot.pem

-------------------------------------------------------------------------------
new certificate deployed without reload, fullchain is
/etc/letsencrypt/live/blog.yskw.info/fullchain.pem
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/yskw.info.conf
-------------------------------------------------------------------------------
Cert not yet due for renewal

The following certs are not due for renewal yet:
  /etc/letsencrypt/live/yskw.info/fullchain.pem (skipped)
Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/blog.yskw.info/fullchain.pem (success)

先程入力したドメイン (yskw.info) の証明書は既に更新されていたので skip されちゃいましたが、それ以外の証明書 (上記の例だと blog.yskw.info) がちゃんと更新されました。

あとは Web サーバーを再起動すれば、新しい証明書が適用されます。