Let's Encrypt GA: выпускаем production-сертификаты для 15 доменов и считаем экономию
12 апреля Let's Encrypt перешёл в General Availability. Раскатываем Ansible-роль на первые 15 клиентских доменов и сравниваем с тем, что платили за Comodo.
Let's Encrypt объявил о General Availability 12 апреля 2016 - бесплатные TLS-сертификаты доступны любому без инвайта
12 апреля Let's Encrypt объявил о General Availability. Закрытая бета, инвайты, ожидание письма на email с подтверждением домена - всё это закончилось. Любой берёт certbot, указывает домен и получает сертификат. Без форм, без ожидания, без денег.
Для нас этот момент не застал врасплох: в марте мы как раз дописали Ansible-роль и прогнали её на staging. GA совпал с планом - можно раскатывать на production.
Первый день: 15 доменов за рабочий день
Начали с утра 12-го - как только пришло официальное письмо от Let's Encrypt. Взяли список из 15 клиентских доменов: те, где сертификаты были куплены давно и давно же отмечены как «надо обновить», плюс несколько, где HTTP вообще не закрывался TLS - просто руки не доходили.
Playbook запускается примерно так:
ansible-playbook -i inventory/production letsencrypt.yml \
--limit "client_group_a" \
--check
Сначала --check, смотрим что изменится, потом без него. На каждом хосте роль:
- убеждается что webroot-директория существует и nginx её отдаёт;
- запрашивает сертификат через letsencrypt certonly;
- обновляет nginx-конфиг с путями к cert и key;
- делает reload.
Из 15 доменов 13 прошли с первого раза без вмешательства. На двух - проблемы.
Первая проблема - HAProxy перед nginx. На одном хосте мы предупреждали, что webroot-схема потребует отдельного рассмотрения. Так и вышло: HAProxy принимает 80-й порт и ничего не знает про .well-known/acme-challenge/. Решение - временно добавить в конфиг HAProxy backend с прямым проксированием на nginx только для challenge-пути, выпустить сертификат, убрать временный блок. Некрасиво, работает. Нормальное решение - вынести challenge на отдельный dedicated backend - поставили в backlog.
Вторая проблема - rate limit. Один домен мы уже пытались получить в staging и зачем-то переключились на production в середине отладки. Упёрлись в лимит «5 сертификатов за 7 дней на один домен». Подождали - на следующий день выпустили без проблем.
К концу дня - 15 доменов с валидными Let's Encrypt сертификатами, cron настроен, мониторинг на дату истечения добавлен в Zabbix. ssllabs.com на всех проверенных - A или A-.
Стоимость: считаем то, что перестали платить
Интересная часть. У разных клиентов были разные ситуации с сертификатами:
- Comodo PositiveSSL для одного домена - около 1 500-2 000 ₽ в год. Самый распространённый вариант среди клиентов.
- Comodo EssentialSSL Wildcard для нескольких поддоменов - 8 000-12 000 ₽ в год. Некоторые клиенты покупали wildcard вместо нескольких отдельных.
- RapidSSL - примерно в том же диапазоне что PositiveSSL, у пары клиентов был именно он.
Один типичный клиент из наших сегодняшних 15 - корпоративный сайт плюс три поддомена (api, docs, lk). Раньше покупали wildcard - один сертификат на всё. С Let's Encrypt - четыре отдельных сертификата, каждый бесплатно, автопродление.
Если брать только сертификаты - экономия примерно 8 000-10 000 ₽ в год на такого клиента. По 15 клиентам из сегодняшнего списка суммарная экономия в год - где-то в районе 120-180 тысяч рублей. Цифры приблизительные: у разных клиентов разные конфигурации, часть платила меньше за один домен, часть - больше за wildcard. Но порядок именно такой.
Плюс управленческие расходы - время на продление, сопровождение платёжного процесса, контроль дат истечения. Это не оцифровывается точно, но ненулевое.
Что это не закрывает
Несколько случаев, где Let's Encrypt не работает или работает неудобно.
EV-сертификаты. Зелёная строка с названием организации в браузере - только от коммерческих CA. Let's Encrypt выдаёт только DV (Domain Validation). Для большинства клиентских сайтов это не важно, для банковских и финансовых - важно, и там мы продолжаем с платными.
Wildcard-сертификаты. Let's Encrypt выдаёт сертификаты только для конкретных доменов, wildcard не поддерживается. Если поддомены создаются динамически или их слишком много чтобы перечислять - либо перечисляем конкретные, либо остаёмся на платном wildcard. Ограничение реальное, у нескольких клиентов именно такая ситуация.
Нестандартные схемы валидации. HTTP-01 через webroot - основной метод. Если хост за NAT без публичного HTTP, или нужна валидация через DNS - letsencrypt это умеет через dns плагины, но не для всех провайдеров и требует отдельной настройки.
Инструкция: минимальный путь от нуля до работающего сертификата
Для тех, кто хочет повторить без нашей Ansible-роли - руками, на одном хосте.
Установка letsencrypt на CentOS 7:
yum install -y epel-release
yum install -y letsencrypt
На Ubuntu/Debian:
apt-get install -y letsencrypt
Создать директорию для challenge и добавить в nginx:
mkdir -p /var/www/letsencrypt-challenge
В nginx.conf или в конфиге виртуального хоста для порта 80:
location ^~ /.well-known/acme-challenge/ {
alias /var/www/letsencrypt-challenge/.well-known/acme-challenge/;
default_type text/plain;
}
nginx -t && systemctl reload nginx
Получить сертификат:
letsencrypt certonly --webroot \
-w /var/www/letsencrypt-challenge \
-d example.ru \
-d www.example.ru \
--email ops@example.ru \
--agree-tos \
--non-interactive
Сертификаты лягут в /etc/letsencrypt/live/example.ru/. Прописать в nginx:
ssl_certificate /etc/letsencrypt/live/example.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.ru/privkey.pem;
Добавить в cron автопродление:
0 4 * * 3 letsencrypt renew --quiet && systemctl reload nginx
Проверить через ssllabs.com - должно быть A, если ssl_protocols и ssl_ciphers в nginx не из 2010 года.
Что дальше
Сегодня - 15 доменов. В списке ещё больше двадцати клиентских сервисов, которые ждут того же. Часть из них - те самые случаи с HAProxy и нестандартными схемами, которые потребуют чуть больше времени на настройку.
Managed-сопровождение с автоматизированным управлением сертификатами Let's Encrypt - уже стандарт для новых клиентских проектов. Платные сертификаты остаются там, где реально нужны: EV и wildcard для особых случаев. Всё остальное - letsencrypt и cron.
Объяснять клиентам что сертификат «бесплатный, но нормальный» приходится реже, чем казалось. Зелёный замок в браузере выглядит одинаково - клиент это видит, и вопросов «а точно не хуже?» почти нет.