Let's Encrypt и безопасная настройка TLS

Сертификаты больше не стоят денег и не требуют ручной возни: certbot выдаёт и продлевает их сам, а пара директив доводит TLS до оценки A+.
«Бесплатно, автоматически, безопасно. Сегодня нет ни одной причины оставлять сайт на http.»

В прошлом уроке мы настроили HTTPS, предполагая, что сертификат уже есть. Теперь получим его бесплатно через Let's Encrypt и закрутим TLS до современного уровня безопасности.

Получение сертификата через certbot

# установка (Ubuntu/Debian)
apt install certbot python3-certbot-nginx

# выпуск сертификата и автонастройка Nginx
certbot --nginx -d example.com -d www.example.com

# проверка автопродления (certbot ставит таймер сам)
certbot renew --dry-run

Certbot подтверждает, что домен твой (обычно через временный файл на сайте), выпускает сертификат на 90 дней и сам правит конфиг Nginx. Продление автоматическое — системный таймер обновляет сертификат заранее.

Современные параметры TLS

ssl_protocols TLSv1.2 TLSv1.3;          # старьё (TLS 1.0/1.1) выключено
ssl_prefer_server_ciphers off;          # для современных профилей off корректнее
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;

ssl_session_cache shared:SSL:10m;       # переиспользование сессий
ssl_session_timeout 1d;
ssl_session_tickets off;                # лучше для forward secrecy

Оставляем только TLS 1.2 и 1.3 — старые версии уязвимы. Шифры — только современные AEAD с ECDHE (это даёт forward secrecy: даже если ключ утечёт завтра, старый перехваченный трафик не расшифровать). Кеш сессий ускоряет повторные подключения.

HSTS: только HTTPS

add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;

HSTS говорит браузеру: «ходи на этот домен только по https, минимум два года». Параметр always важен — без него заголовок не отправится на страницах ошибок (4xx/5xx).

Как работает под капотом

Forward secrecy обеспечивает обмен ключами ECDHE: для каждой сессии генерируется одноразовая пара, и сеансовый ключ нельзя восстановить из приватного ключа сервера задним числом. Кеш сессий (ssl_session_cache) хранит параметры завершённых рукопожатий, позволяя клиенту возобновить сессию коротким путём вместо полного рукопожатия — это заметно ускоряет повторные визиты. Важная актуальная деталь: Let's Encrypt прекратил поддержку OCSP в 2025 году, поэтому ssl_stapling on на их сертификатах теперь ничего не делает и лишь пишет предупреждение в лог — его можно убрать.

Частые ошибки

  • Оставить TLS 1.0/1.1. Старые протоколы снижают оценку безопасности и уязвимы; отключи их.
  • HSTS без always. Заголовок не уйдёт на ошибочных ответах — образуется дыра.
  • preload в HSTS «на всякий случай». Это трудно откатить: домен зашьют в браузеры. Добавляй preload только осознанно.
  • Забыть про автопродление. Сертификат на 90 дней без таймера однажды протухнет.

Best practices

  • certbot --nginx + проверка renew --dry-run — и забудь о ручном продлении.
  • Только TLSv1.2 TLSv1.3, современные AEAD-шифры, ECDHE для forward secrecy.
  • HSTS с always; preload — только сознательно.
  • Вынеси ssl-параметры в snippet и проверь сайт на внешнем TLS-тесте.

Жизненный цикл сертификата и автоматизация

Сертификаты Let's Encrypt живут всего 90 дней — это сделано намеренно, чтобы вынудить автоматизацию: короткий срок означает, что ручное продление просто нереально поддерживать, и все настраивают автообновление. Certbot после первого выпуска ставит системный таймер (или cron), который заранее, обычно за месяц до истечения, обновляет сертификат и тихо перезагружает Nginx. Твоя задача — один раз проверить, что это работает: certbot renew --dry-run прогоняет весь процесс вхолостую. Если он зелёный, можно спать спокойно.

Полезно понимать, как именно Let's Encrypt убеждается, что домен твой. Самый частый способ — HTTP-01: certbot кладёт временный файл по пути /.well-known/acme-challenge/, а сервер Let's Encrypt запрашивает его по твоему домену; раз файл доступен — значит, ты контролируешь и сайт, и DNS. Поэтому важно не перехватывать этот путь своими редиректами и не закрывать его за авторизацией. Альтернатива — DNS-01, где подтверждение идёт через TXT-запись в DNS; этот способ нужен для wildcard-сертификатов (*.example.com) и работает, даже если сайт ещё не запущен. Зная механику, ты легко диагностируешь сбои продления: чаще всего причина в том, что challenge-путь чем-то перекрыт или DNS настроен неверно. Автоматизированный, самопродлевающийся, бесплатный HTTPS — это сегодня норма, и настроить его правильно — дело пятнадцати минут, которые окупаются годами спокойствия.

Итоги

Let's Encrypt + certbot дают бесплатные автопродлеваемые сертификаты. Безопасный TLS — это TLSv1.2/1.3, современные AEAD-шифры с ECDHE (forward secrecy), кеш сессий и HSTS с always. OCSP stapling для Let's Encrypt с 2025 года не нужен. Дальше — защита: заголовки безопасности и ограничение частоты запросов.

Проверьте себя
1. Что даёт обмен ключами ECDHE (forward secrecy)?
AУскоряет статику
BДаже при утечке приватного ключа сервера ранее перехваченный трафик нельзя расшифровать задним числом
CОтключает HTTPS
DСжимает сертификат
2. Зачем у заголовка HSTS нужен параметр `always`?
AДля сжатия
BЧтобы заголовок отправлялся в том числе на ответах с ошибками (4xx/5xx), не оставляя дыр
CЧтобы включить HTTP/2
DЧтобы продлить сертификат