Почему сертификат — это не опция
Если сайт работает по HTTP, Chrome показывает красный замок и надпись «Не защищено». Google понижает такие сайты в выдаче. Пользователи закрывают вкладку. Это не страшилка — это реальность 2026 года.
SSL-сертификат шифрует трафик между браузером и сервером. Без него данные передаются в открытом виде: логины, пароли, платёжные данные. Даже если у вас сайт-визитка без форм — сертификат всё равно нужен ради SEO и доверия.
Что такое Let's Encrypt
Let's Encrypt — центр сертификации, который выдаёт SSL-сертификаты бесплатно. Запущен в 2016 году Mozilla, Cisco, EFF и рядом других организаций. Сегодня обслуживает более 300 миллионов сайтов.
Сертификаты выдаются на 90 дней. Это сделано специально — короткий срок мотивирует к автообновлению и снижает риски при компрометации ключа. Именно поэтому Let's Encrypt изначально проектировался под автоматизацию через протокол ACME.
Что важно знать:
- Выдаётся Domain Validation (DV) — подтверждает только владение доменом
- Wildcard-сертификаты (*.example.com) поддерживаются через DNS-01 challenge
- Мультидоменные сертификаты (SAN) — до 100 доменов в одном
- Не подходит для EV (Extended Validation) — если нужна строка с названием компании, придётся платить
Как работает выдача сертификата
Протокол ACME (Automatic Certificate Management Environment) — стандарт, по которому клиент на сервере договаривается с Let's Encrypt о выдаче сертификата. Процесс такой:
- Клиент (например, Certbot) отправляет запрос на сертификат для домена example.com
- Let's Encrypt отвечает: «Докажи, что домен твой»
- Клиент проходит challenge — HTTP-01 или DNS-01
- Let's Encrypt проверяет и выдаёт сертификат
HTTP-01 challenge — самый простой. Certbot создаёт файл по пути /.well-known/acme-challenge/токен, Let's Encrypt обращается к нему по HTTP. Работает только если сервер доступен из интернета на 80-м порту.
DNS-01 challenge — для wildcard и случаев, когда 80-й порт закрыт. Certbot добавляет TXT-запись _acme-challenge.example.com в DNS. Let's Encrypt проверяет запись. Занимает чуть больше времени из-за DNS propagation.
Устанавливаем Certbot
Certbot — официальный клиент Let's Encrypt. Поддерживает Nginx, Apache, standalone-режим.
На Ubuntu/Debian:
sudo apt update
sudo apt install certbot python3-certbot-nginx
Получаем сертификат для Nginx:
sudo certbot --nginx -d example.com -d www.example.com
Certbot сам найдёт конфиг Nginx, допишет нужные директивы и перезагрузит сервер. После этого в /etc/letsencrypt/live/example.com/ появятся файлы:
fullchain.pem — цепочка сертификатов
privkey.pem — приватный ключ
cert.pem — только сертификат (обычно не нужен отдельно)
chain.pem — промежуточные сертификаты
Настраиваем Nginx вручную
Если хочется контроля, а не «пусть Certbot всё сделает сам» — настраиваем конфиг руками. Получаем сертификат в standalone-режиме (Nginx при этом должен быть остановлен):
sudo certbot certonly --standalone -d example.com -d www.example.com
Конфиг Nginx:
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
add_header Strict-Transport-Security "max-age=63072000" always;
location / {
root /var/www/example.com;
index index.html;
}
}
Несколько пояснений:
TLSv1.2 TLSv1.3 — TLS 1.0 и 1.1 давно устарели и небезопасны
ssl_session_cache — кешируем сессии, чтобы не делать полный handshake при каждом запросе
- HSTS — говорим браузеру всегда использовать HTTPS; осторожно, после включения откатить сложно
Автообновление — самое важное
Let's Encrypt выдаёт сертификат на 90 дней. Certbot рекомендует обновлять за 30 дней до истечения. Если забыть — сайт начнёт показывать ошибку, и вы об этом узнаете от клиентов, а не от мониторинга.
Certbot при установке создаёт systemd-таймер или запись в cron. Проверить:
sudo systemctl list-timers | grep certbot
Стандартная запись в /etc/cron.d/certbot:
0 */12 * * * root certbot renew --quiet
Certbot проверяет сертификаты дважды в день и обновляет те, которым осталось менее 30 дней. Даже если одна проверка упадёт, следующая сработает через 12 часов.
Проверить, что автообновление работает:
sudo certbot renew --dry-run
Если всё хорошо, увидите:
Congratulations, all renewals succeeded.
Хук после обновления
После обновления сертификата Nginx нужно перезагрузить, иначе он продолжит отдавать старый. Создаём файл /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh:
#!/bin/bash
systemctl reload nginx
Делаем исполняемым:
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
Теперь после каждого успешного обновления Nginx сам перезагрузится. Аналогично работает для Apache (systemctl reload apache2) и любого другого сервиса.
Wildcard-сертификат через DNS
Если нужен сертификат для *.example.com — только DNS-01 challenge. HTTP-01 для wildcard не работает.
sudo certbot certonly \
--manual \
--preferred-challenges dns \
-d "*.example.com" \
-d example.com
Certbot попросит добавить TXT-запись в DNS. Добавляете, ждёте распространения (обычно 1–5 минут, иногда до 30), подтверждаете.
Проблема ручного wildcard: при обновлении снова нужно вручную добавлять TXT-запись. Поэтому для wildcard лучше использовать DNS-плагины — они автоматически управляют записями через API регистратора. Плагины есть для большинства популярных провайдеров:
# Cloudflare
sudo apt install python3-certbot-dns-cloudflare
# DigitalOcean
sudo apt install python3-certbot-dns-digitalocean
Пример для Cloudflare — создаём /etc/letsencrypt/cloudflare.ini:
dns_cloudflare_api_token = ВАШ_API_ТОКЕН
Ограничиваем права и получаем сертификат:
sudo chmod 600 /etc/letsencrypt/cloudflare.ini
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
-d "*.example.com" \
-d example.com
Теперь автообновление полностью автоматическое — Certbot сам обновит TXT-запись через API.
acme.sh как альтернатива Certbot
acme.sh — легковесная альтернатива на bash. Не требует root, работает в cron пользователя, поддерживает десятки DNS-провайдеров.
Установка:
curl https://get.acme.sh | sh -s email=admin@example.com
Получение сертификата через Cloudflare DNS:
export CF_Token="ВАШ_ТОКЕН"
export CF_Account_ID="ВАШ_АККАУНТ"
~/.acme.sh/acme.sh --issue --dns dns_cf \
-d example.com \
-d "*.example.com"
Установка в Nginx:
~/.acme.sh/acme.sh --install-cert -d example.com \
--key-file /etc/nginx/ssl/example.com.key \
--fullchain-file /etc/nginx/ssl/example.com.pem \
--reloadcmd "systemctl reload nginx"
acme.sh сам добавляет запись в cron и при обновлении выполняет reloadcmd.
Мониторинг сертификатов
Автообновление может сломаться — DNS-провайдер поменял API, кончилось место на диске, изменился IP сервера. Нужно следить за сроком действия.
Простейшая проверка через openssl:
echo | openssl s_client -connect example.com:443 2>/dev/null | \
openssl x509 -noout -dates
Скрипт для ежедневного оповещения:
#!/bin/bash
DOMAIN="example.com"
DAYS_THRESHOLD=14
EXPIRY=$(echo | openssl s_client -connect $DOMAIN:443 2>/dev/null | \
openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))
if [ $DAYS_LEFT -lt $DAYS_THRESHOLD ]; then
echo "ВНИМАНИЕ: сертификат $DOMAIN истекает через $DAYS_LEFT дней" | \
mail -s "SSL alert: $DOMAIN" admin@example.com
fi
Из внешних сервисов — UptimeRobot умеет следить за сроком SSL-сертификатов и присылать уведомления. Бесплатный тариф покрывает базовые нужды.
Ограничения Let's Encrypt
Важно знать лимиты, чтобы не попасть в ситуацию, когда сертификат не выдаётся:
- 50 сертификатов в неделю на один зарегистрированный домен
- 5 дубликатов в неделю — если несколько раз запрашивать один и тот же набор доменов
- 5 неудачных попыток в час для одного аккаунта и домена
На практике лимиты мешают только при массовой автоматизации или при ошибочном написании скрипта, который циклит запросы. Для тестирования используйте staging-окружение:
sudo certbot --staging --nginx -d example.com
Staging выдаёт сертификаты без лимитов, но они не доверенные — браузер покажет предупреждение. Зато можно спокойно отлаживать автоматизацию.
Когда нужен платный сертификат
Let's Encrypt закрывает 95% задач. Но бывают исключения:
EV-сертификат — Extended Validation. Раньше давал зелёную строку с названием компании. Chrome и Firefox убрали это визуальное отличие ещё в 2019–2020 годах. Сегодня нужен разве что для специфического корпоративного комплаенса.
OV-сертификат — Organization Validation. Подтверждает существование организации. Нужен для некоторых B2B-клиентов и государственных тендеров.
Сервер без доступа из интернета — если сервер в закрытом контуре и нет возможности настроить DNS-API, автообновление Let's Encrypt не сработает.
Для большинства проектов — корпоративных сайтов, интернет-магазинов, лендингов — Let's Encrypt полностью достаточен.
Типичные ошибки
Забытый renewal-хук. Certbot обновил сертификат, но Nginx читает старый. Сайт работает, пока старый сертификат не истечёт — тогда всё сломается. Всегда настраивайте хук на reload.
80-й порт закрыт файрволом. HTTP-01 challenge не пройдёт. Либо откройте порт, либо используйте DNS-01.
Несоответствие доменов. Сертификат выдан для example.com, а Nginx настроен на www.example.com. Всегда запрашивайте сертификат для всех вариантов домена.
Права на файлы ключей. Приватный ключ должен быть доступен только root. Если что-то поменяли в правах на /etc/letsencrypt/ — Certbot может не смочь прочитать файлы при обновлении.
Staging-сертификат в проде. Если тестировали через --staging, перед переходом в прод удалите staging-сертификат и получите новый без флага.
В REEXY настройка SSL — один из первых шагов перед сдачей любого проекта. Даже простой сайт-визитка от 2 000 ₽ сдаётся с работающим HTTPS: это базовая гигиена, без которой выпускать сайт просто неприлично.
Автообновление через Certbot с правильными хуками и мониторингом срока — это то, что должно работать тихо годами. Один раз настроить правильно и забыть об этой задаче навсегда.