プログラマーのメモ書き

伊勢在住のプログラマーが気になることを気ままにメモったブログです

Let's Encrypt の更新エラー

こちらの記事で書いたサーバーの Let's Encrypt の証明書の更新ですが、cron で自動実行されているので安心と思い込んでいたら、あと20日で有効期限が切れるよ、というメールが先日やってきました。

慌てて、サーバーを確認すると。syslogに更新失敗の記録が載っていました。

Dec 19 06:19:10 ip-xxx-xxx-xxx-xxx systemd[1]: Starting Certbot...
Dec 19 06:19:15 ip-xxx-xxx-xxx-xxx certbot[8506]: Attempting to renew cert (サーバーのドメイン名) from /etc/letsencrypt/renewal/サーバーのドメイン名.conf produced an unexpected error: Failed authorization procedure. サーバーのドメイン名 (http-01): urn:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from https://サーバーのドメイン名/.well-known/acme-challenge/JDoMfpSsox4bWhzrsYgGLIVN4OUEx0NJHFcdWgL0Wwg [52.199.225.177]: "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n<title>404 Not Found</title>\n</head><body>\n<h1>Not Found</h1>\n<p". Skipping.
Dec 19 06:19:15 ip-xxx-xxx-xxx-xxx certbot[8506]: All renewal attempts failed. The following certs could not be renewed:
Dec 19 06:19:15 ip-xxx-xxx-xxx-xxx certbot[8506]:   /etc/letsencrypt/live/サーバーのドメイン名/fullchain.pem (failure)
Dec 19 06:19:15 ip-xxx-xxx-xxx-xxx certbot[8506]: 1 renew failure(s), 0 parse failure(s)
Dec 19 06:19:15 ip-xxx-xxx-xxx-xxx systemd[1]: certbot.service: Main process exited, code=exited, status=1/FAILURE
Dec 19 06:19:15 ip-xxx-xxx-xxx-xxx systemd[1]: certbot.service: Failed with result 'exit-code'.
Dec 19 06:19:15 ip-xxx-xxx-xxx-xxx systemd[1]: Failed to start Certbot.

このエラーを解決しようとした際にやったことをメモっておきます。

改めてテスト

下記の記事などを参考にもう一度テストしました。

Let'sEncryptの取得&自動更新設定してみた(CentOS7.1&Apache2.4.6) - Qiita

最初は --dry-run つけて試してました。

ubuntu@ip-xxx-xxx-xxx-xxx:/etc/cron.d$ sudo certbot renew --force-renew --dry-run --webroot-path /var/www/html/ドキュメントルート
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/サーバーのドメイン名.conf
-------------------------------------------------------------------------------
Plugins selected: Authenticator webroot, Installer None
Renewing an existing certificate
Attempting to renew cert (サーバーのドメイン名) from /etc/letsencrypt/renewal/サーバーのドメイン名.conf produced an unexpected error: urn:ietf:params:acme:error:malformed :: The request message was malformed :: Method not allowed. Skipping.
All renewal attempts failed. The following certs could not be renewed:
  /etc/letsencrypt/live/サーバーのドメイン名/fullchain.pem (failure)

-------------------------------------------------------------------------------
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

All renewal attempts failed. The following certs could not be renewed:
  /etc/letsencrypt/live/サーバーのドメイン名/fullchain.pem (failure)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
-------------------------------------------------------------------------------
1 renew failure(s), 0 parse failure(s)
ubuntu@ip-xxx-xxx-xxx-xxx:/etc/cron.d$ 

エラーになっていました。 --force-renew かな?と思い、これをはずしても同じ結果。

でも、深く考えずに --dry-run をはずすと、できてしまった・・・

ubuntu@ip-xxx-xxx-xxx-xxx:/etc/cron.d$ sudo certbot renew --webroot-path /var/www/html/ドキュメントルート
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/サーバーのドメイン名.conf
-------------------------------------------------------------------------------
Cert is due for renewal, auto-renewing...
Plugins selected: Authenticator webroot, Installer None
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for サーバーのドメイン名
Using the webroot path /var/www/html/ドキュメントルート for all unmatched domains.
Waiting for verification...
Cleaning up challenges

-------------------------------------------------------------------------------
new certificate deployed without reload, fullchain is
/etc/letsencrypt/live/サーバーのドメイン名/fullchain.pem
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/サーバーのドメイン名/fullchain.pem (success)
-------------------------------------------------------------------------------
ubuntu@ip-xxx-xxx-xxx-xxx:/etc/cron.d$ 

cron.d でエラーになっていた理由

あとから、考えるとLet's Encrypt の設定ファイル(/etc/letsencrypt/renewal/サーバーのドメイン名.conf)内のwebrootの指定が 実際のフォルダよりも一つ上のフォルダを指していました。

webroot_path = /var/www/html,

どうもこのため、エラーが起きていたようです(ただ、 renew に成功するとこの.confファイルが書き換えられるため、記憶をたどって書いています)。

で、上のコマンドラインで実行時には、正しいwebrootを指定していたので、成功になったようです。

--dry-run でエラーになっていた理由

下記の記事などによると、 --dry-run をつけた場合、0.32 以前の certbot だと、エラーが起きるようなこと書いています。

Problem with renew certificates - The request message was malformed :: Method not allowed - Help - Let's Encrypt Community Support

今の環境だと、0.23 だったようです。多分これですね。

ubuntu@ip-xxx-xxx-xxx-xxx:/var/log$ certbot --version
certbot 0.23.0
ubuntu@ip-xxx-xxx-xxx-xxx:/var/log$ 

まあ、とりあえず更新が動くようになったので、今日のところはこれでOKとします。