Let's Encrypt證書自動更新

Let’s Encrypt證書自動更新

Let’s Encrypt免費SSL證書用起來非常方便,但每次申請只有三個月有效期,在每次到期之前都需要重新申請,不過重新申請並不麻煩,只需要一行命令就完事:certbot renew

即便是一條命令就OK,也不想每隔三個月就需要登錄到機器上執行更新命令,所以我在第一次申請之後就配置了crontab每隔兩個月重新申請一次。

願景是美好的,但過了一段時間後,我網站證書竟然過期了,也就是說crontab沒有生效或者任務失敗了,此文就是來找到這個問題所在以及修復它。

history

v1

最開始我配置了一條這樣的crontab:

0 0 1 */2 * certbot renew --force-renewal

然後發現不生效,鑑於之前的經驗知道crontab執行命令的路徑應該是$HOME,而且不會加載環境變量,所以在這裏改了一下。

v2

通過which certbot查找到命令的完整路徑,然後配置到crontab中:

0 0 1 */2 * /usr/bin/certbot renew --force-renewal

但過了一段時間後發現網站的證書沒有更新,自己依舊沒當回事,覺得可能是month: */2這個寫法不對。

v3

雖然之前在crontab文檔裏面是見過*/2這種寫法的,但這次沒去深究,遂改成1,3,5…逗號的寫法:

0 0 1 1,3,5,7,9,11 * /usr/bin/certbot renew --force-renewal

結果依舊悲催。

v4

悲催後,我又改了下:

0 0 1 1,3,5,7,9,11 * /usr/bin/certbot renew --quiet --force-renewal 1>/dev/null 2>/dev/null

寫這篇文章就是發生在第四次瞎B試失敗後,受不了了…

now

crontab日誌

爲了驗證,這次就不再是配置兩個月間隔的crontab,就看着時間配置,比如現在是13:57,那麼crontab裏面就配置成:

0 14 * * * /usr/bin/certbot renew --quiet --force-renewal 1>/dev/null 2>/dev/null

到了14:00,去找crontab的日誌(/var/log/cron),發現是命令是執行的,而且沒有什麼有效信息,日誌內容如下:

Jul  4 14:00:01 ams CROND[21881]: (root) CMD (/usr/bin/certbot renew --quiet --force-renewal 1>/dev/null 2>/dev/null)
Jul  4 14:00:01 ams CROND[21882]: (root) CMD (echo "tmp" > /root/tmp)
Jul  4 14:00:01 ams CROND[21883]: (root) CMD (/usr/lib64/sa/sa1 1 1)
Jul  4 14:01:01 ams CROND[22000]: (root) CMD (run-parts /etc/cron.hourly)
Jul  4 14:01:01 ams run-parts(/etc/cron.hourly)[22000]: starting 0anacron
Jul  4 14:01:01 ams run-parts(/etc/cron.hourly)[22009]: finished 0anacron

其中echo "tmp" > /root/tmp是自己不清楚如何查看crontab日誌的情況下用來驗證crontab是否執行。

最終通過日誌以及/root/tmp確認命令有被執行,但證書就是沒有更新,由於通過手動執行命令可以更新證書,這裏判斷命令在crontab裏面就不好使了,具體原因還不清楚。

letsencrypt日誌

crontab日誌中沒什麼發現,進入Google搜索模式幾分鐘後發現letsencrypt有自己的日誌:/var/log/letsencrypt/letsencrypt.log,遂查看:

2018-07-04 14:00:02,500:DEBUG:certbot.main:certbot version: 0.23.0
2018-07-04 14:00:02,500:DEBUG:certbot.main:Arguments: ['--quiet', '--force-renewal']
2018-07-04 14:00:02,500:DEBUG:certbot.main:Discovered plugins: PluginsRegistry(PluginEntryPoint#manual,PluginEntryPoint#nginx,PluginEntryPoint#null,PluginEntryPoint#standalone,PluginEntryPoint#webroot)
2018-07-04 14:00:02,516:DEBUG:certbot.log:Root logging level set at 30
2018-07-04 14:00:02,516:INFO:certbot.log:Saving debug log to /var/log/letsencrypt/letsencrypt.log
2018-07-04 14:00:02,543:DEBUG:certbot.plugins.selection:Requested authenticator <certbot.cli._Default object at 0x36b5550> and installer <certbot.cli._Default object at 0x36b5550>
2018-07-04 14:00:02,546:DEBUG:certbot.renewal:Auto-renewal forced with --force-renewal...
2018-07-04 14:00:02,565:DEBUG:certbot.plugins.selection:Requested authenticator nginx and installer nginx
2018-07-04 14:00:02,570:DEBUG:certbot.plugins.disco:No installation (PluginEntryPoint#nginx): 
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/certbot/plugins/disco.py", line 126, in prepare
    self._initialized.prepare()
  File "/usr/lib/python2.7/site-packages/certbot_nginx/configurator.py", line 135, in prepare
    raise errors.NoInstallationError
NoInstallationError
2018-07-04 14:00:02,570:DEBUG:certbot.plugins.selection:No candidate plugin
2018-07-04 14:00:02,570:DEBUG:certbot.plugins.selection:No candidate plugin
2018-07-04 14:00:02,571:DEBUG:certbot.plugins.selection:Selected authenticator None and installer None
2018-07-04 14:00:02,571: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()
2018-07-04 14:00:02,571:WARNING:certbot.renewal:Attempting to renew cert (www.isenle.com) from /etc/letsencrypt/renewal/www.isenle.com.conf produced an unexpected error: The nginx plugin is not working; there may be problems with your existing configuration.
The error was: NoInstallationError(). Skipping.
2018-07-04 14:00:02,571:DEBUG:certbot.renewal:Traceback was:
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/certbot/renewal.py", line 422, in handle_renewal_request
    main.renew_cert(lineage_config, plugins, renewal_candidate)
  File "/usr/lib/python2.7/site-packages/certbot/main.py", line 1095, in renew_cert
    installer, auth = plug_sel.choose_configurator_plugins(config, plugins, "certonly")
  File "/usr/lib/python2.7/site-packages/certbot/plugins/selection.py", line 201, in choose_configurator_plugins
    diagnose_configurator_problem("authenticator", req_auth, plugins)
  File "/usr/lib/python2.7/site-packages/certbot/plugins/selection.py", line 297, in diagnose_configurator_problem
    raise errors.PluginSelectionError(msg)
PluginSelectionError: The nginx plugin is not working; there may be problems with your existing configuration.
The error was: NoInstallationError()

這堆異常大概是說沒有安裝nginx插件,結合自己機器上安裝了nginx以及手動執行renew是OK的,所以猜測這裏是因爲crontab執行renew時找不到相關程序導致,而程序存在卻找不到,無非就是PATH有問題,遂進行驗證:

20 14 * * * echo "$PATH" > /root/tmp

到時間後查看/root/tmp發現內容是:/usr/bin:/bin,而which nginx的結果是:/usr/sbin/nginx,基本可以確定是PATH的問題,所以現在把crontab的環境變量配置一下就OK了,用crontab -e進入編輯,在最前面加上兩行環境設置:

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin

0 0 1 */2 * certbot renew --quiet --force-renewal

花了半小時,問題最終得到解決,以後就不用管證書的自動續期了。

review

針對這件事情做個review,從自己v1-v4的處理中,總結出自己的一些缺點:

  • 馬虎對待,不求甚解
  • 處理問題的方式不對,只是瞎B試
  • 知識不牢靠,比如crontab的PATH、*/2等

這篇文章不是解決問題後所寫,而是當我決定來解決這個問題的時候開始寫的,最開始以爲是Let’s Encrypt的問題,最後發現與Let’s Encrypt並沒有關係,只是crontab的PATH問題而已。

crontab有兩種使用方式,一種是編輯/etc/crontab,一種是用crontab -e,前者默認配置了SHELL與PATH,而我在這裏使用的是crontab -e,所以弄出這麼個問題。

博客原文

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章