Установка SSL на CentOS, чиним certbot и настраиваем cron

12.07.2021
Потребовалось помочь клиенту установить SSL сертификаты на сайты, который расположены на хостинге jino, казалось бы достаточно заказать let encrypt для определенного домена (читай - пара кликов мыши). Но на деле оказалось что у клиента vps, на котором CentOS с нестандартным софтом для панели хостинга (судя по переписке клиента с тех. поддержкой).

В основном я работаю на Ubuntu (на момент написания статьи), поэтому yarn вместо apt для меня было немного неудобно :)

Захожу к клиенту по ssh, обнаруживаю (конфиги хостов /etc/httpd/conf.d/) что у клиента httpd (это тот же apache, но я тогда не знал об этом).

Проверяю наличие модуля mod_ssl для httpd:

> rpm -qa | grep mod_ssl
mod_ssl-2.4.6-67.el7.centos.6.x86_64

Нормально двигаемся дальше.

Certbot

Смотрим certbot:

> certbot
An unexpected error occurred:
ImportError: cannot import name constants
Please see the logfile '/tmp/tmpyl9Qi0/log' for more details.

certbot не работает, а в логе по указанному пути выдает следующее:

2021-06-29 10:11:05,440:DEBUG:certbot._internal.log:Exiting abnormally:
Traceback (most recent call last):
  File "/usr/bin/certbot", line 9, in <module>
    load_entry_point('certbot==1.11.0', 'console_scripts', 'certbot')()
  File "/usr/lib/python2.7/site-packages/certbot/main.py", line 15, in main
    return internal_main.main(cli_args)
  File "/usr/lib/python2.7/site-packages/certbot/_internal/main.py", line 1383, in main
    plugins = plugins_disco.PluginsRegistry.find_all()
  File "/usr/lib/python2.7/site-packages/certbot/_internal/plugins/disco.py", line 236, in find_all
    plugin_ep = cls._load_entry_point(entry_point, plugins, with_prefix=False)
  File "/usr/lib/python2.7/site-packages/certbot/_internal/plugins/disco.py", line 254, in _load_entry_point
    plugin_ep = PluginEntryPoint(entry_point, with_prefix)
  File "/usr/lib/python2.7/site-packages/certbot/_internal/plugins/disco.py", line 56, in __init__
    self.plugin_cls = entry_point.load()
  File "/usr/lib/python2.7/site-packages/pkg_resources/__init__.py", line 2303, in load
    return self.resolve()
  File "/usr/lib/python2.7/site-packages/pkg_resources/__init__.py", line 2309, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
  File "/usr/lib/python2.7/site-packages/certbot_nginx/configurator.py", line 17, in <module>
    from certbot import constants as core_constants
ImportError: cannot import name constants
2021-06-29 10:11:05,440:ERROR:certbot._internal.log:An unexpected error occurred:
2021-06-29 10:11:05,440:ERROR:certbot._internal.log:ImportError: cannot import name constants

Особый интерес здесь представляют последние строки, а именно ошибка импорта констант:

File "/usr/lib/python2.7/site-packages/certbot_nginx/configurator.py", line 17, in <module>
    from certbot import constants as core_constants

Модуль nginx для certbot в нашем случае в общем-то не нужен, но в таком виде сам certbot не сможет работать, поэтому надо исправить.

Посмотрим какой версии модуль nginx для certbot:

> rpm -qa|grep certbot
python2-certbot-nginx-0.22.0-1.el7.noarch
python2-certbot-apache-1.11.0-1.el7.noarch
certbot-1.11.0-1.el7.noarch
python2-certbot-1.11.0-1.el7.noarch

Как видно модуль nginx отстает от certbot, обновляем:

> yum update python2-certbot-nginx

Смотрим:

> rpm -qa|grep certbot
python2-certbot-apache-1.11.0-1.el7.noarch
python2-certbot-nginx-1.11.0-1.el7.noarch
certbot-1.11.0-1.el7.noarch
python2-certbot-1.11.0-1.el7.noarch

Теперь пробуем запустить certbot, все должно работать:

> certbot

Cron

Случайно решил проверить автопродление ssl, но не обнаружил для этого задач ни при помощи crontab -l ни в директории /etc/cron.d/, в systemd тоже ничего нет похожего.

Кстати, для просмотра задач всех пользователей можно воспользоваться такой командой:

for user in $(cut -d':' -f1 /etc/passwd); do crontab -u $user -l; done

Добавляем файл certbot в /etc/cron.d/ со следующим содержимым (владельца, группу и права выставить аналогчно другим файлам в этой директории):

0 0 * * * root certbot renew --post-hook "systemctl reload httpd"

Что значит:

Каждый день в полночь запускать от имени root проверку сертификатов (и обновление если надо), после чего перезапустить httpd.

Теперь надо перезагрузить cron (в некоторых случаях crond):

systemctl restart cron

Все должно работать :)