Задача: использовать сертификаты Let's Encrypt для персонального сервера: вебсервер, почта, xmpp.
Серверный софт: Nginx, Prosody, Exim4.
Базовая инструкция: https://certbot.eff.org/#debianstretch-nginx
Дальше всё для моего домена, это в точности та конфигурация, которая у меня на сервере.
Текст будет обновляться по мере возникновения новых проблем.
Шаг 1. Подготовка серверного окружения¶
Ставим certbot:
$ sudo apt install certbot
Для корректной работы плагина webroot
я решил сделать отдельный каталог, куда бы certbot
писал необходимые файлы для подтверждения домена (источник).
$ sudo mkdir -p /var/www/certbot
Дальше создаём сниппет для nginx. Пишем в файл /etc/nginx/snippets/certbot-webroot-acme-challenge.conf
следующее:
location ^~ /.well-known/acme-challenge/ { default_type "text/plain"; root /var/www/certbot; } location = /.well-known/acme-challenge/ { return 404; }
Или можете скачать готовый так:
$ sudo wget 'https://raw.githubusercontent.com/sigsergv/blog-data/master/letsencrypt/certbot-webroot-acme-challenge.conf' \ -O /etc/nginx/snippets/certbot-webroot-acme-challenge.conf
Дальше во все необходимые конфиги (/etc/nginx/sites-enabled/
) добавляем такую строчку в секцию server
:
server { listen 80; ....здесь остальные строки конфига.... include /etc/nginx/snippets/certbot-webroot-acme-challenge.conf; }
Шаг 2. Создание сертификата¶
Я сделал два сертификата. Один для nginx и доменов regolit.com, blog.regolit.com, www.regolit.com, misc.regolit.com, smtp.regolit.com
, второй — специально для домена jabber.regolit.com
. Делаются они такими командами:
$ sudo certbot certonly --webroot -d regolit.com,blog.regolit.com,www.regolit.com,misc.regolit.com,smtp.regolit.com --webroot-path /var/www/certbot $ sudo certbot certonly --webroot -d jabber.regolit.com --webroot-path /var/www/certbot
После успешного завершения скрипта будет показана вся нужная информация: что было создано и куда положено.
Я НЕ пользуюсь фичами certbot по установке сертификатов, вместо этого я их сам раскладываю куда надо.
Шаг 3. Установка сертификатов¶
nginx¶
Для nginx в конфиг (у меня это /etc/nginx/sites-enabled/default
) нужно прописать такое:
ssl_certificate_key /etc/letsencrypt/live/regolit.com-0001/privkey.pem; ssl_certificate /etc/letsencrypt/live/regolit.com-0001/fullchain.pem;
prosody¶
К сожалению, для prosody нельзя указать напрямую путь к приватному ключу (и сертификату) из хранилища certbot, поскольку программа запускается не от юзера root, а все файлы в каталоге /etc/letsencrypt/live/
доступны для чтения только юзеру root. Поэтому ключ и сертификат сначала копируем в каталог prosody и меняем пермиссии с владельцем. Всё эти команды (они дальше уйдут в hook-файл, запускаемый автоматически после обновления сертификата):
cp /etc/letsencrypt/live/jabber.regolit.com/privkey.pem /etc/prosody/certs/jabber.regolit.key cp /etc/letsencrypt/live/jabber.regolit.com/fullchain.pem /etc/prosody/certs/jabber.regolit.pem chown prosody:prosody /etc/prosody/certs/jabber.regolit.{key,pem} chmod 0600 /etc/prosody/certs/jabber.regolit.{key,pem}
Для Prosody конфиг /etc/prosody/conf.avail/regolit.com.cfg.lua
меняется так:
VirtualHost "regolit.com" ssl = { key = "/etc/prosody/certs/jabber.regolit.key"; certificate = "/etc/prosody/certs/jabber.regolit.pem"; }
Шаг 4. Настройка обновления сертификата¶
certbot устанавливает cron-скрипт, который автоматически обновляет сертификат, когда в этом возникает необходимость. Вручную можно запустить обновление для всех локальных сертификатов так:
$ sudo certbot renew
Можно протестировать обновление, добавив аргумент --dry-run
, в этом случае certbot не будет сохранять на диск новые сертификаты. Однако какие-то новые файлы в /etc/letsencrypt/
созданы всё равно появятся.
После обновления сертификата на диске нужно как минимум перезапустить затронутые серверы. А для prosody нужно ещё и обновить копии сертификата и ключа.
Но моя цель — полностью автоматизировать всё: при появлении нового сертификата должны перезапуститься серверы, а для prosody нужно ещё и скопировать новые сертификаты куда надо и перезапустить.
Также в этом файле мы копируем сертификат и ключ в файлы exim4, он тоже как и prosody не умеет корректно работать с симлинками.
Для этого создаём файл /root/certbot-post-hook
:
#!/bin/bash cp /etc/letsencrypt/live/jabber.regolit.com/privkey.pem /etc/prosody/certs/jabber.regolit.key cp /etc/letsencrypt/live/jabber.regolit.com/fullchain.pem /etc/prosody/certs/jabber.regolit.pem chown prosody:prosody /etc/prosody/certs/jabber.regolit.{key,pem} chmod 0600 /etc/prosody/certs/jabber.regolit.{key,pem} cat /etc/letsencrypt/live/regolit.com-0001/privkey.pem > /etc/exim4/regolit.com.key cat /etc/letsencrypt/live/regolit.com-0001/fullchain.pem > /etc/exim4/regolit.com.pem /bin/systemctl reload prosody # since version 0.10 it will reload certificates /bin/systemctl reload nginx
Его можно скачать и установить так:
$ wget -O /root/certbot-post-hook https://raw.githubusercontent.com/sigsergv/blog-data/master/letsencrypt/certbot-post-hook $ chmod +x /root/certbot-post-hook
Дальше нужно отредактировать cron-скрипт /etc/cron.d/certbot
:
# /etc/cron.d/certbot: crontab entries for the certbot package # # Upstream recommends attempting renewal twice a day # # 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 --post-hook /root/certbot-post-hook
Рандомная скриптота¶
Не стоит ручками лазить в каталог /etc/letsencrypt/
, вместо этого пользуйтесь командами certbot.
Список всех сертификатов в локальном хранилище¶
$ sudo certbot certificates Saving debug log to /var/log/letsencrypt/letsencrypt.log ------------------------------------------------------------------------------- Found the following certs: Certificate Name: jabber.regolit.com Domains: jabber.regolit.com Expiry Date: XXXX-XX-XX XX:XX:XX+00:00 (VALID: 89 days) Certificate Path: /etc/letsencrypt/live/jabber.regolit.com/fullchain.pem Private Key Path: /etc/letsencrypt/live/jabber.regolit.com/privkey.pem Certificate Name: regolit.com Domains: regolit.com blog.regolit.com jabber.regolit.com misc.regolit.com www.regolit.com Expiry Date: XXXX-XX-XX XX:XX:XX+00:00 (VALID: 89 days) Certificate Path: /etc/letsencrypt/live/regolit.com/fullchain.pem Private Key Path: /etc/letsencrypt/live/regolit.com/privkey.pem Certificate Name: regolit.com-0001 Domains: regolit.com blog.regolit.com misc.regolit.com www.regolit.com Expiry Date: XXXX-XX-XX XX:XX:XX+00:00 (VALID: 89 days) Certificate Path: /etc/letsencrypt/live/regolit.com-0001/fullchain.pem Private Key Path: /etc/letsencrypt/live/regolit.com-0001/privkey.pem -------------------------------------------------------------------------------
Отзыв сертификата¶
$ sudo certbot revoke --cert-path /etc/letsencrypt/live/regolit.com/fullchain.pem Saving debug log to /var/log/letsencrypt/letsencrypt.log ------------------------------------------------------------------------------- Congratulations! You have successfully revoked the certificate that was located at /etc/letsencrypt/live/regolit.com/fullchain.pem -------------------------------------------------------------------------------
После отзыва сертификат остаётся в локальном хранилище. Удалить его оттуда можно так:
$ sudo certbot delete --cert-name regolit.com Saving debug log to /var/log/letsencrypt/letsencrypt.log ------------------------------------------------------------------------------- Deleted all files relating to certificate regolit.com. -------------------------------------------------------------------------------