Назад | Перейти на главную страницу

Работа cron для обновления Let's encrypt

Это правильный способ установить cron для обновления сертификата Let's Encrypt в Apache2? Я использую Ubuntu 16.04.

@monthly letsencrypt renew && service apache2 reload

Ежемесячно бывает недостаточно. Этот сценарий должен запускаться как минимум раз в неделю, а лучше - ежедневно. Помните, что сертификаты не обновляются, если они не близки к истечению, и ежемесячно может привести к тому, что ваши существующие сертификаты иногда истекают до того, как они будут продлены.

Название программы certbot, который был переименован из letsencrypt. Если вы все еще используете letsencrypt, вам необходимо обновиться до текущей версии.

Помимо этих проблем, это примерно то же самое, что и моя работа cron.

43 6 * * * certbot renew --post-hook "systemctl reload nginx"

Обратите внимание, что в 18.04 LTS пакет letsencrypt (наконец) был переименован в certbot. Теперь он включает в себя таймер systemd, который вы можете включить для планирования обновлений certbot с помощью systemctl enable certbot.timer и systemctl start certbot.timer. Однако в Ubuntu не было возможности указывать ловушки. Вам нужно будет настроить переопределение для certbot.service переопределить ExecStart= с желаемой командной строкой, пока Ubuntu не исправит это.

У меня недостаточно репутации, чтобы комментировать, поэтому я отвечу здесь. Недавно (октябрь 2017 г.) я установил и запустил certbot на сервере Ubuntu 16.04, и задание обновления cron было создано автоматически в /etc/cron.d/certbot.

Вот созданное задание cron:

0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(3600))' && certbot -q renew

Перед созданием записи в crontab было бы неплохо проверить, существует ли уже этот файл.

В документация по certbot рекомендует запускать скрипт дважды в день:

Примечание:

если вы настраиваете задание cron или systemd, мы рекомендуем запускать его два раза в день (он ничего не сделает, пока ваши сертификаты не будут обновлены или отозваны, но его регулярное выполнение даст вашему сайту шанс оставаться в сети в если по какой-то причине произошел аннулирование, инициированное Let's Encrypt). Выберите случайную минуту в течение часа для задач по продлению.

Как упоминает Майкл Хэмптон, имя было изменено на certbot, но они по-прежнему предоставляют параметр -auto, который обновляется. В certbot-auto Для запуска команды требуются привилегии root, поэтому строка в вашем cron-скрипте должна выглядеть примерно так:

52 0,12 * * * root /full/path/to/certbot-auto renew --quiet

В моем случае certbot-auto Скрипт помещается в домашний каталог пользователя git. Тогда точная команда

52 0,12 * * * root /home/git/certbot-auto renew --quiet

Обратите внимание, что пример в документации соответствует относительному пути, обозначенному точкой, что может сбивать с толку:

./path/to/certbot-auto renew --quiet

Обязательно предварительно запустите команду обновления в оболочке, чтобы проверить путь, если сертификат не подлежит обновлению, ничего не произойдет (запустите этот тест без --quiet флаг, чтобы увидеть, что происходит).

Строго не требуется перезагружать сервер при обновлении сертификата таким образом, поскольку путь к действующему сертификату не изменяется при правильной настройке.

Это верно, если вы используете apache - для nginx рассмотрите возможность добавления ловушки обновления, например:

52 0,12 * * * root certbot renew --renew-hook 'service nginx reload'

Вам не нужно ничего настраивать. Любая недавняя установка Certbot в Debian / Ubuntu должна установить таймер systemd и задание cron (а задание cron будет запускаться только certbot если systemd не активен, вы не сможете запустить оба).

системный таймер

Вы можете проверить свои таймеры systemd с помощью команды systemctl list-timers (или systemctl list-timers --all если вы также хотите показать неактивные таймеры). Что-то вроде этого:

% sudo systemctl list-timers
NEXT                         LEFT        LAST                         PASSED      UNIT                         ACTIVATES
Fri 2018-08-03 06:17:25 UTC  10h left    Thu 2018-08-02 06:27:13 UTC  13h ago     apt-daily-upgrade.timer      apt-daily-upgrade.service
Fri 2018-08-03 11:43:29 UTC  15h left    Thu 2018-08-02 16:54:52 UTC  3h 7min ago certbot.timer                certbot.service
Fri 2018-08-03 12:44:58 UTC  16h left    Thu 2018-08-02 19:14:58 UTC  47min ago   apt-daily.timer              apt-daily.service
Fri 2018-08-03 19:43:44 UTC  23h left    Thu 2018-08-02 19:43:44 UTC  18min ago   systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
Mon 2018-08-06 00:00:00 UTC  3 days left Mon 2018-07-30 00:00:09 UTC  3 days ago  fstrim.timer                 fstrim.service

Таймер certbot должен быть здесь /lib/systemd/system/certbot.timer и он выполнит команду, указанную в /lib/systemd/system/certbot.service

certbot.timer выполнит службу `certbot.service в 12:00 и 12:00 после случайной задержки до 12 часов (43200 секунд).

# cat /lib/systemd/system/certbot.timer
[Unit]
Description=Run certbot twice daily

[Timer]
OnCalendar=*-*-* 00,12:00:00
RandomizedDelaySec=43200
Persistent=true

[Install]
WantedBy=timers.target

и certbot.service выполнит команду обновления.

# cat /lib/systemd/system/certbot.service
[Unit]
Description=Certbot
Documentation=file:///usr/share/doc/python-certbot-doc/html/index.html
Documentation=https://letsencrypt.readthedocs.io/en/latest/
[Service]
Type=oneshot
ExecStart=/usr/bin/certbot -q renew
PrivateTmp=true

cron работа

Как уже упоминали другие, также установлено задание cron в /etc/cron.d/certbot:

# Eventually, this will be an opportunity to validate certificates
# haven't been revoked, etc.  Renewal will only occur if expiration
# is within 30 days.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew

Это делает:

  • test -x /usr/bin/certbot -a \! -d /run/systemd/system - проверить, если /usr/bin/certbot это исполняемый файл и это /run/systemd/system является не каталог. Переходите к следующему биту, только если эта проверка прошла успешно.
    • Часть проверки systemd фактически означает, что если systemd запущен, не запускайте certbot из задания cron - оставьте это таймеру.
  • perl -e 'sleep int(rand(43200))' - спите произвольное время от 0 секунд до 12 часов (43200 = 12 x 60 x 60).
  • certbot -q renew проверьте свои сертификаты и при необходимости обновите их. В -q флаг "тихий" - не выводить никаких сообщений, если нет ошибки.

Изначально я был сбит с толку заданием cron, так как он не собирался запускаться из-за systemd, так как же будет запускаться certbot? Я нашел ответ в это сообщение на форуме на чем я основал этот ответ.

Для продления сертификата LetsEncrypt я обычно использую getssl. Это очень удобная оболочка-оболочка, которая может даже устанавливать сертификат на другие машины через соединение SSH.

Запись в cron следующая:

01 23 * * * root /root/scripts/getssl/getssl -u -a -q >>/var/log/getssl.log 2>&1 ; /usr/sbin/apache2ctl graceful

Как уже было предложено, вы должны запускать его ежедневно или, что еще лучше, дважды в день.

Как уже упоминал glaux:

Примечание: если вы настраиваете задание cron или systemd, мы рекомендуем запускать его два раза в день (он ничего не сделает, пока ваши сертификаты не будут обновлены или отозваны, но его регулярное выполнение даст вашему сайту шанс остаться. онлайн на случай, если по какой-либо причине произошел аннулирование, инициированное Let's Encrypt). Выберите случайную минуту в течение часа для задач по продлению.

Источник: https://certbot.eff.org/all-instructions/#debian-8-jessie-apache

Итак, в итоге я использовал это (работает дважды в день, в 01:00 и в 13:00 каждый день):

6 1,13 * * * certbot renew --post-hook "service apache2 restart"

или даже лучше:

6 1,13 * * * certbot renew --renew-hook "service apache2 restart"

Я не тестировал, но это тоже должно работать:

6 1,13 * * * certbot renew --post-hook "/etc/init.d/apache2 restart"
6 1,13 * * * certbot renew --renew-hook "/etc/init.d/apache2 restart"

Перехватчики --pre-hook и --post-hook запускаются до и после каждой попытки обновления. Если вы хотите, чтобы ваш хук запускался только после успешного обновления, используйте --renew-hook в такой команде.

Источник: https://certbot.eff.org/docs/using.html

Другие участники уже предоставили более подробные ответы. Но похоже, я должен упомянуть об этом здесь.

Начиная с версии certbot 0.21.1 --renew-hook флаг изменен на --deploy-hook Убедитесь, что вы не используете устаревший флаг.

certbot renew --deploy-hook "systemctl restart myservice"

Вот что я использую:

/opt/letsencrypt/letsencrypt-auto renew

выводит как:

Upgrading certbot-auto 0.8.1 to 0.9.1...
Replacing certbot-auto...
Creating virtual environment...
...
new certificate deployed with reload of apache server; fullchain is
/etc/letsencrypt/live/host.simplecoin.cz/fullchain.pem
-------------------------------------------------------------------------------

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/host.simplecoin.cz/fullchain.pem (success)

И это говорит о том, что apache уже перезапущен, поэтому нет необходимости делать это снова. Если я запустил его снова:

Cert not yet due for renewal

поэтому обновлять сертификат ежедневно не проблема, тогда мой cron:

@daily /opt/letsencrypt/cronautorenew.sh

Я использую сценарий, чтобы настроить ведение журнала в отдельный файл, поэтому вот мой cronautorenew.sh:

#!/usr/bin/env bash
printf "\nattempt to renew certificates" >>/var/log/letsencrypt_cron.log 2>&1
date >>/var/log/letsencrypt_cron.log 2>&1
/opt/letsencrypt/letsencrypt-auto renew >>/var/log/letsencrypt_cron.log 2>&1
printf "renew finished\n" >>/var/log/letsencrypt_cron.log 2>&1

В соответствии с Руководство по сертификатам EFF

Многие дистрибутивы Linux обеспечивают автоматическое обновление, когда вы используете пакеты, установленные через их системный менеджер пакетов.

Если вы не уверены, автоматизирована ли эта функция в вашей системе, проверьте ее crontab (обычно в /etc/crontab/ и /etc/cron.*/* $ crontab -l и системные таймеры $ systemctl list-timers.