ホーム » 技術 » certbotがnginxサイトのrenewに失敗した話

certbotがnginxサイトのrenewに失敗した話

さて当サイトはLet’s Encryptの認証を得ていて、毎週月曜日のバッチで更新チェックをやっている。Let’s Encryptの認証は3か月で切れてしまうので、期限のチェックと更新は大事なルーチンなのだ。だが、お約束というかなんというか、当サイトは3か月目の最初の更新に失敗し5時間ほど不通だった。

927

Let’s Encryptの更新バッチは割にシンプルで、失敗する要素はあまりない。なんで失敗するのかよく分からないので原因を突き詰めることにした。まずはログを調べてみよう。certbotは/var/log/letsencryptディレクトリにログを残してくれるので、これをチェックすればよい。見てみるとこんな記述があった。

2019-07-29 09:17:54,215:DEBUG:certbot.plugins.selection:Requested authenticator nginx and installer nginx
2019-07-29 09:17:54,218:DEBUG:certbot.plugins.disco:No installation (PluginEntryPoint#nginx): Could not find a usable 'nginx' binary. Ensure nginx exists, the binary is executable, and your PATH is set correctly.
2019-07-29 09:17:54,220:INFO:certbot.main:Could not choose appropriate plugin: The nginx plugin is not working; there may be problems with your existing configuration.
The error was: NoInstallationError("Could not find a usable 'nginx' binary. Ensure nginx exists, the binary is executable, and your PATH is set correctly.",)
2019-07-29 09:17:54,220:WARNING:certbot.renewal:Attempting to renew cert (north.thco.mp) from /etc/letsencrypt/renewal/north.thco.mp.conf produced an unexpected error: The nginx plugin is not working; there may be problems with your existing configuration.
The error was: NoInstallationError("Could not find a usable 'nginx' binary. Ensure nginx exists, the binary is executable, and your PATH is set correctly.",). Skipping.

なんか、nginxが見つからないと文句を言っている。

実はcertbotは、コマンドラインから起動すると問題なく動く。期限が切れてしまったので再取得しようとしたときも問題ないし、そのあとのrenewのテストをやろうと思って

certbot --dry-run renew

と起動してもちゃんと動く。もしかして環境の問題かな? と思って、起動スクリプトの方を見直すことにした。certbotの起動時には、/etc/cron.d/certbot-renewというファイルからこんな風に起動している。

MAILTO=
13 9 * * mon root /usr/bin/certbot renew --post-hook "systemctl restart nginx" | logger -t certbot-renew -p local0.info

ここでは環境変数PATHには何も指定していないので、おそらくデフォルトの非常に短いPATHしか通っていないのだろう。実際に確認してみると /usr/bin:/bin というひどいありさまだった。これではどうしようもないので、nginxにPATHが通るように次のように指定してみた。

PATH=/usr/sbin:/usr/bin:/bin
MAILTO=
13 9 * * mon root /usr/bin/certbot renew --post-hook "systemctl restart nginx" | logger -t certbot-renew -p local0.info

--dry-runをつけてテストしたところ問題なく動作したので、これでOKのようだ。

Apacheはどうなの?

さて環境変数の問題となると、これまで運用してきた他のサイトはどうやねん、というのが気になる。「失敗する要素はあまりない」と冒頭に書いたが、Let’s Encryptで運用しているHTTPSサイトは他にもあり、そちらでは問題なく更新できているからだ。ただ、違いと言えばそちらはApacheで運用しているということぐらいだ。

というわけでそちらのサイトのログもチェックしてみよう。

2019-07-22 09:30:18,304:DEBUG:certbot.plugins.selection:Requested authenticator apache and installer apache
2019-07-22 09:30:18,333:DEBUG:certbot.plugins.util:Can't find apachectl, attempting PATH mitigation by adding /usr/sbin:/usr/local/bin:/usr/local/sbin

というわけでApacheも似たようなエラーを出していた。だが、Apacheのプラグインはapachectlなしでも認証を続けてくれるようで、証明書の更新自体はちゃんと終わっていた。そうだったのかcertbot。ということでこちらにもちゃんとPATHを設定しておくことにした。

もうひとつ、今回certbotのログを読んでわかったのがこれ。

2019-07-22 09:29:02,229:INFO:certbot.renewal:Non-interactive renewal: random delay of 76 seconds

これまで、管理しているサイトごとに色々工夫してランダムな時刻を設定していたのだが、意味がないことが発覚したので、管理の意味も込めてなるべく統一コードで済ませるようにしていきたいと思う。

あと、本来ならrenewに失敗したときにうまくhookしたいのだが、今のところいい知恵が浮かばないので、別の機会にネタにしたい。