Краткая памятка по настройке HTTPS для Nginx через LetsEncrypt
Сначала несколько общеизвестных фактов:
- Сервис LetsEncrypt бесплатно предоставляет всем желающим заверенные SSL-сертификаты для доменных имён в публичных DNS-зонах.
- Общение с сервисом производится только через API с помощью клиентских утилит, веб-интерфейса у него нет.
- Выдавая сертификат на доменное имя, сервис требует от заявителя подтвердить, что он действительно является владельцем данного имени.
- Подтверждение возможно одним из двух способов: через HTTP (по умолчанию) или через DNS.
Что требуется для подтверждения через HTTP?
- Клиентская утилита обязана запускаться на том сервере, в IP-адрес которого распознаётся заверяемое доменное имя.
- IP-адрес обязан быть публичным.
- На порту 80 должен быть запущен Веб-сервер.
- Веб-серверу требуется небольшая дополнительная настройка, чтобы правильно отвечать на проверочные запросы LetsEncrypt.
Почему в качестве клиентской утилиты мы выбрали dehydrated?
- Потому что это один файл на bash с минимумом зависимостей (openssl и curl).
- Потому что его пакет есть в стандартных репозитариях большиства дистрибутивов.
- Потому что у него простая ручная установка в тех дистрибутивах, в которых готовый пакет отсутствует (например, в Ubuntu 16.04) или устарел.
Ручная установка (если нет готового пакета):
- Скачиваем сценарий и делаем исполняемым:
cd /usr/bin
wget https://raw.githubusercontent.com/lukas2511/dehydrated/master/dehydrated
chmod +x dehydrated
mkdir /etc/dehydrated /var/lib/dehydrated
BASEDIR=/var/lib/dehydrated
WELLKNOWN="${BASEDIR}/acme-challenges"
DOMAINS_TXT="/etc/dehydrated/domains.txt"
Создаём ключи и получаем сертификаты:
- Сначала создаём учётную запись в LetsEncrypt:
dehydrated --register --accept-terms
xx.ru www.xx.ru
yy.ru www.yy.ru
server {
server_name xx.ru www.xx.ru;
location ^~ /.well-known/acme-challenge {
alias /var/lib/dehydrated/acme-challenges;
}
location / {
return 301 https://$host$request_uri;
}
nginx -t
nginx -s reload
dehydrated -c
Теперь включаем HTTPS:
- Добавляем в /etc/nginx/sites-enabled/xx.ru.conf:
server {
listen 443 ssl;
server_name xx.ru www.xx.ru;
ssl_certificate /var/lib/dehydrated/certs/xx.ru/fullchain.pem;
ssl_certificate_key /var/lib/dehydrated/certs/xx.ru/privkey.pem;
}
nginx -s reload
Настраиваем автопродление:
- Сертификаты выдаются на 90 суток.
- "dehydrated -c" без ключа "--force" не пытается продлевать сертификат, если он выдан менее 80 суток назад.
- Поэтому оптимально вызывать продление раз в неделю — т.е. с минимумом неудачных попыток, но с гарантированным попаданием в заключительный 10-дневный интервал.
- Для этого создаём файл /etc/cron.weekly/Dehydrated (и делаем его исполняемым через "chmod +x"):
#!/bin/sh
dehydrated -c -g
#!/bin/sh
test "$1" = "deploy_cert" || exit 0
nginx -s reload
Как и зачем использовать подтверждение через DNS вместо HTTP?
- Сайт или сервис может быть недоступен из внешнего мира (находиться в офисной локальной сети, приватном облаке и т.д), поэтому LetsEncrypt не сумеет обратиться к нему извне, чтобы проверить владельца.
- Либо по каким-то причинам мы вынуждены запускать клиентскую утилиту с другого компьютера.
- В этом случае LetsEncrypt позволяет подтверждать владение доменом через специальные DNS-записи.
- Для этого dehydrated должен запускаться с дополнительным ключом "-t dns-01".
- Сценарий hook.sh становится примерно таким:
#!/bin/sh
case "$1" in
"deploy_challenge") printf "Please add to DNS:\n_acme-challenge.%s. %d in TXT \"%s\"\n" "${2}" "${TTL}" "${4}"
read -p "Configure, then press Enter..." x ;;
"clean_challenge" ) printf "Please delete from DNS:\n_acme-challenge.%s. %d in TXT \"%s\"\n" "${2}" "${TTL}" "${4}" ;;
"deploy_cert" ) ;; # optional: /path/to/deploy_cert.sh "$@" ;;
esac
← Назад в Блог