Установка 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:

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

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

Certbot

Смотрим certbot:

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

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

•••
plaintext
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

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

•••
plaintext
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:

•••
bash
> 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, обновляем:

•••
bash
> yum update python2-certbot-nginx

Смотрим:

•••
bash
> 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, все должно работать:

•••
bash
> certbot

Cron

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

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

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

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

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

Что значит:

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

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

•••
bash
systemctl restart cron

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