Привел в порядок сертификаты от Letsencrypt

Небольшая заметка на тему. Давненько уже перешел на использование сертификатов от Letsencrypt. В общем-то, сразу после того, как случайно просрочил сертификат от cacert.org, после чего не смог больше залогиниться у них на сайте – сертификат для логина, понятное дело, больше не подходил, а “обычный” логин выдавал ошибку. Пошел искать альтернативу и успешно ее нашел. По какому-то мануалу создал нужные сертификаты, с тех пор так и пользуюсь – правда, с обновлением только вручную. Пробовал найденные команды для автоматического обновления, получал ошибку, в подробности не вник – так и забросил, а раз в 3 месяца при получении письма от LE просто выполнял несколько команд.

Сейчас подошел очередной срок (письмо я, правда, в этот раз почему-то не получил), а так как в последние дни занимаюсь наведением порядка на сервере – решил подробнее разобраться и с этой темой.

В целом, проблема была с тем, что сертификаты могут выписываться как на конкретный домен, так и быть wildcard-сертификатами (т.е., подходить под любой субдомен). В моем случае был актуален второй вариант – когда я самый первый раз создавал сертификаты, то выписал их как на linuxoid.in, так и на *.linuxoid.in “в одном флаконе”. А создание – и обновление! – таких сертификатов делается в том числе через TXT-записи в DNS. Так как DNS у меня является отдельной сущностью (и плагинов у certbot’а под него нет), то и простых вариантов работы с этими сертификатами у меня не было.

Когда наконец-то докопался до этого момента и решил “делать правильно”, подумал – “а так ли уж надо wildcard?”. Удобно, конечно, создать и обновлять один сертификат, а в конфигах серверов указывать только один файл, да вот как раз с моментом обновления и возникала каждый раз проблема – так не лучше ли один раз напрячься и расписать, что конкретно мне надо? Доменов и субдоменов у меня немного, большей частью веб – а значит, рядом есть Апач, через который и будет происходить верификация.

Успешно создал несколько сертификатов для субдоменов, все прошло без ошибок. Сертификаты прописал в конфигах доменов, жизнь налаживалась.

Оставалось разобраться со старыми и пока еще действующими сертификатами, использующимися в ejabberd. Номинально тот обслуживает 2 домена, однако у сервера есть ряд сервисных доменов – conference, upload, pubsub и proxy (последнего у меня нет). Согласно заметке в блоге разработчика сервера, “make sure all these subdomains use the SSL certificate supplied to ejabberd XMPP server. If you can, simplify things and use a wildcard certificate and a wildcard subdomain” – собственно, что и привело в свое время меня к использованию wildcard’ов. Кстати, там же: “If you don’t configure these subdomains, you will find a warning about them in the ejabberd XMPP server logs during each startup” – однако для jabberworld.info у меня не было субдомена conference – и при этом предупреждений я не видел. С других серверов conference.jabberworld.info тоже нормально дискаверилась. Так что обязательность DNS-записей для сервисов немного под вопросом, как и сертификаты. Однако я уже решил идти до конца; для автоматической верификации создал на веб-сервере все нужные домены и смог создать все необходимые для ejabberd’а сертификаты. Теперь был полный комплект и я мог избавиться от старых wildcard’ов.

По использованию. certbot хранит сертификаты в /etc/letsencrypt/, доступными на чтение только руту. С Апачем и Mumble server (да, решил прописать сертификат и там – почему бы и нет?) проблемы не возникло. Судя по всему, вычитка сертификатов идет до сброса прав у процесса, поэтому проблем с правами на чтение не возникает. С ejabberd же чуть иначе и добраться до файлов он уже не мог. Пришлось набросать небольшой скрипт, который будет вызываться как --post-hook или --deploy-hook после обновления:

#!/bin/bash
 
for i in {proxy.,upload.,pubsub.,conference.,}{linuxoid.in,jabberworld.info}
do
cp /etc/letsencrypt/live/$i/fullchain.pem /etc/ejabberd/certs/${i}.fullchain.pem
cp /etc/letsencrypt/live/$i/privkey.pem /etc/ejabberd/certs/${i}.privkey.pem
done
chown root:ejabberd -R /etc/ejabberd/certs/
chmod 640 /etc/ejabberd/certs/*.pem
 
/usr/sbin/ejabberdctl reload_config
/usr/sbin/service mumble-server restart
/usr/sbin/service apache2 restart

В современном ejabberd’e, как выяснилось, уже не требуется сливать fullchain и privkey в один файл, поэтому в итоге в ejabberd.yml появился довольно длинный список сертификатов и их ключей:

certfiles:
 - "/etc/ejabberd/certs/conference.jabberworld.info.fullchain.pem"
 - "/etc/ejabberd/certs/conference.jabberworld.info.privkey.pem"
 - "/etc/ejabberd/certs/conference.linuxoid.in.fullchain.pem"
 - "/etc/ejabberd/certs/conference.linuxoid.in.privkey.pem"
 - "/etc/ejabberd/certs/jabberworld.info.fullchain.pem"
 - "/etc/ejabberd/certs/jabberworld.info.privkey.pem"
 - "/etc/ejabberd/certs/linuxoid.in.fullchain.pem"
 - "/etc/ejabberd/certs/linuxoid.in.privkey.pem"
 - "/etc/ejabberd/certs/pubsub.jabberworld.info.fullchain.pem"
 - "/etc/ejabberd/certs/pubsub.jabberworld.info.privkey.pem"
 - "/etc/ejabberd/certs/pubsub.linuxoid.in.fullchain.pem"
 - "/etc/ejabberd/certs/pubsub.linuxoid.in.privkey.pem"
 - "/etc/ejabberd/certs/upload.jabberworld.info.fullchain.pem"
 - "/etc/ejabberd/certs/upload.jabberworld.info.privkey.pem"
 - "/etc/ejabberd/certs/upload.linuxoid.in.fullchain.pem"
 - "/etc/ejabberd/certs/upload.linuxoid.in.privkey.pem"
 - "/etc/ejabberd/certs/proxy.jabberworld.info.fullchain.pem"
- "/etc/ejabberd/certs/proxy.jabberworld.info.privkey.pem"
- "/etc/ejabberd/certs/proxy.linuxoid.in.fullchain.pem"
- "/etc/ejabberd/certs/proxy.linuxoid.in.privkey.pem"

В процессе поисков информации попалось такое: https://github.com/processone/ejabberd/issues/1292 – было, правда, 6 лет назад и не знаю, насколько актуально на сейчас. Так или иначе, для основного домена я получаю валидный сертификат, а насчет необходимости сертификатов для субдоменов уже написал выше. Ну и вроде ничего не отвалилось 🙂

Ну и к вопросу о правах: https://github.com/processone/ejabberd/issues/2211 – да, вариант, конечно, добавить группу для letsencrypt, но пока решил не делать – мало ли, вдруг сломается что-то. Можно будет когда-то поэкспериментировать. По-идее, новые файлы все равно будут создаваться с правами root:root и потребуется какой-то хук для исправления этого – так можно тогда просто оставить все как есть. Или, как вариант, таки попробовать упомянутый по ссылке ACME, он уже несколько раз мне на глаза попадался. Тогда у ejabberd’а будет свой набор сертификатов, которые он сам и будет обслуживать. Заметка на эту тему: “Note that the ACME protocol requires challenges to be sent on port 80. Since this is a privileged port, ejabberd cannot listen on it directly without root privileges. Thus you need some mechanism to forward port 80 to the port defined by the listener”

Автообновление сертификатов пока не включал – все равно до срока истечения еще далеко, а я хочу попробовать команду в реальной работе и пронаблюдать обновление. В целом, у certbot’a есть как штатный инструмент обновления через cron – /etc/cron.d/certbot – так и через systemd – certbot.timer. Первый не выполняется, если в системе присутствует systemd.

Кроме того, хочу попробовать в дальнейшем указывать ключ большего размера через --rsa-key-size 4096

 

2 мысли о “Привел в порядок сертификаты от Letsencrypt”

  1. Словил косяк небольшой с ejabberd: судя по всему, капча отдавалась не с тем сертификатом, который был для домена, прописанного как captcha_url, в итоге в веб-форме капча отсутствовала. Сменил url на jabberworld.info (т.е., один из обслуживаемых сервером), все стало нормально.

Добавить комментарий