Почему HTTPS — это не опция

Браузеры уже несколько лет помечают HTTP-сайты как «небезопасные». Поисковики дают бонус сайтам с HTTPS. Платёжные системы вообще не работают без SSL. Так что сертификат — это базовая гигиена, а не роскошь.

SSL (точнее TLS, но все говорят SSL) шифрует трафик между браузером пользователя и сервером. Без него данные из форм — логины, пароли, номера карт — летят в открытом виде. Любой, кто сидит в той же кофейне с публичным Wi-Fi, может их перехватить.

Платные сертификаты vs Let's Encrypt

Раньше сертификат стоил от 20 до нескольких тысяч долларов в год. Были разные уровни: DV (Domain Validation) просто подтверждает владение доменом, OV (Organization Validation) проверяет организацию, EV (Extended Validation) раньше давал зелёную строку в адресной строке — но браузеры её убрали, и смысл EV теперь сомнительный.

В 2013 году появился Let's Encrypt — некоммерческий центр сертификации, который выдаёт DV-сертификаты бесплатно и автоматически. Сейчас это стандарт де-факто для большинства сайтов.

Когда платный сертификат всё-таки нужен:

  • OV для крупных финансовых организаций с требованиями регулятора
  • Wildcard на очень большое количество поддоменов при специфических ограничениях
  • Когда нужна расширенная поддержка и гарантии от CA

Для обычного бизнес-сайта, лендинга или интернет-магазина Let's Encrypt закрывает задачу на 100%.

Как работает Let's Encrypt

Let's Encrypt использует протокол ACME (Automated Certificate Management Environment). Схема простая:

  1. Твой сервер отправляет запрос на сертификат для домена example.com
  2. Let's Encrypt говорит: «Докажи, что это твой домен»
  3. Сервер проходит challenge — HTTP-01 или DNS-01
  4. Let's Encrypt проверяет и выдаёт сертификат
  5. Сертификат действует 90 дней

90 дней — намеренно короткий срок. Это заставляет автоматизировать обновление и не держать просроченные сертификаты годами.

HTTP-01 challenge

Самый простой способ. Let's Encrypt просит разместить файл по адресу http://example.com/.well-known/acme-challenge/TOKEN. Если файл доступен — домен подтверждён. Работает только если сервер смотрит в интернет на 80 порту.

DNS-01 challenge

Let's Encrypt просит создать TXT-запись в DNS: _acme-challenge.example.com. Нужен для:

  • Wildcard-сертификатов (*.example.com)
  • Серверов, которые не торчат в интернет напрямую
  • Ситуаций, когда 80 порт закрыт

DNS-01 сложнее в автоматизации — нужен API-доступ к DNS-провайдеру.

Certbot — основной инструмент

Certbot — официальный клиент ACME от EFF. Умеет получать, устанавливать и обновлять сертификаты.

Установка на Ubuntu/Debian

sudo apt update
sudo apt install certbot python3-certbot-nginx

Для Apache:

sudo apt install certbot python3-certbot-apache

Получение сертификата для Nginx

sudo certbot --nginx -d example.com -d www.example.com

Certbot сам найдёт конфиг Nginx, допишет настройки SSL, перезагрузит сервер. После этого в конфиге появится:

ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

Standalone режим

Если Nginx ещё не настроен или нужен сертификат без веб-сервера:

sudo certbot certonly --standalone -d example.com

Certbot поднимет временный HTTP-сервер на 80 порту, пройдёт challenge и положит сертификаты в /etc/letsencrypt/live/example.com/.

Webroot режим

Если не хочешь останавливать веб-сервер:

sudo certbot certonly --webroot -w /var/www/html -d example.com

Автообновление — самое важное

Сертификат живёт 90 дней. Забыть обновить — значит получить упавший сайт в самый неподходящий момент. Автоматизация обязательна.

Через systemd (рекомендуется)

На современных Ubuntu/Debian certbot при установке сам создаёт systemd timer. Проверить:

sudo systemctl status certbot.timer

Должно быть active (waiting). Timer запускает certbot renew дважды в день в случайное время. Если до истечения сертификата больше 30 дней — ничего не происходит. Если меньше — обновляет.

Посмотреть следующий запуск:

sudo systemctl list-timers | grep certbot

Через cron

Если systemd недоступен или ты предпочитаешь cron:

sudo crontab -e

Добавить строку:

0 3 * * * certbot renew --quiet --post-hook "systemctl reload nginx"

Запускается каждый день в 3 ночи. --quiet убирает лишний вывод. --post-hook перезагружает Nginx только если сертификат реально обновился.

Тест обновления

Перед тем как доверять автоматике, проверь что всё работает:

sudo certbot renew --dry-run

Это имитирует обновление без реальных изменений. Если видишь Congratulations, all renewals succeeded — всё в порядке.

Wildcard-сертификаты

Wildcard покрывает все поддомены: *.example.com — то есть api.example.com, app.example.com, mail.example.com одним сертификатом.

Для wildcard нужен DNS-01 challenge. Придётся настроить API-доступ к DNS-провайдеру.

Пример для Cloudflare:

sudo apt install python3-certbot-dns-cloudflare

Создать файл /etc/letsencrypt/cloudflare.ini:

dns_cloudflare_email = your@email.com
dns_cloudflare_api_key = YOUR_API_KEY

Установить права:

chmod 600 /etc/letsencrypt/cloudflare.ini

Получить wildcard:

sudo certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
  -d example.com \
  -d *.example.com

Плагины есть для большинства популярных DNS-провайдеров: Route53, DigitalOcean, Hetzner, Yandex Cloud и других.

Альтернативы Certbot

acme.sh

Популярная альтернатива на чистом bash. Не требует root, умеет работать в userspace, поддерживает огромное количество DNS-провайдеров.

curl https://get.acme.sh | sh
~/.acme.sh/acme.sh --issue -d example.com --webroot /var/www/html

acme.sh сам добавляет cron-задачу при установке.

Caddy

Если только начинаешь и не привязан к Nginx — Caddy получает и обновляет SSL автоматически без какой-либо настройки. Просто пишешь в Caddyfile:

example.com {
    root * /var/www/html
    file_server
}

И всё. Caddy сам всё сделает. Хороший выбор для несложных проектов.

Traefik

Если работаешь с Docker и контейнерами — Traefik умеет автоматически получать сертификаты для сервисов через метки в docker-compose.yml. Популярен в связке с микросервисами.

Типичные проблемы и как их решать

«Too many requests» — лимиты Let's Encrypt

Let's Encrypt ограничивает количество сертификатов: 50 в неделю на домен. Если часто пересоздаёшь сертификаты в процессе разработки — используй staging-окружение:

sudo certbot certonly --staging -d example.com

Staging-сертификаты браузер не принимает, но позволяют тестировать без риска словить лимит.

Порт 80 закрыт

HTTP-01 challenge требует открытый 80 порт. Проверь firewall:

sudo ufw allow 80
sudo ufw allow 443

Или переходи на DNS-01 challenge.

Сертификат не обновляется автоматически

Сначала прогони certbot renew --dry-run. Потом смотри логи:

sudo journalctl -u certbot
# или
cat /var/log/letsencrypt/letsencrypt.log

Частая причина — изменился конфиг Nginx и certbot не может найти webroot или 80 порт отдаёт что-то не то.

Смешанный контент (Mixed Content)

Получил сертификат, включил HTTPS, но браузер всё равно ругается. Причина — на странице есть ресурсы (картинки, скрипты, CSS), которые грузятся по HTTP. Нужно найти и заменить все http:// на https:// в коде или добавить в nginx заголовок:

add_header Content-Security-Policy "upgrade-insecure-requests";

Редирект HTTP → HTTPS

После получения сертификата нужно принудительно перенаправлять всех на HTTPS. В Nginx:

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

HSTS — следующий шаг

HSTS (HTTP Strict Transport Security) говорит браузеру: «Этот сайт всегда только HTTPS, не пробуй HTTP вообще». Добавляется в конфиг Nginx:

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

max-age=31536000 — год в секундах. Включай только после того, как убедился, что HTTPS работает стабильно — отменить HSTS непросто.

Мониторинг срока действия

Даже с автоматическим обновлением стоит настроить мониторинг. Сервер мог упасть в момент очередного обновления, автоматика — не сработать.

Проверить срок вручную:

sudo certbot certificates

Или через openssl:

echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -dates

Для системного мониторинга — инструменты типа Zabbix, Prometheus или Uptime Kuma умеют следить за сроком сертификата и слать алерты за 14–30 дней до истечения.

Ещё полезный инструмент — SSL Labs (ssllabs.com/ssltest). Он не только проверит срок, но и оценит конфигурацию: какие протоколы поддерживаются, нет ли уязвимостей, какой рейтинг (A, B, C...). Хорошая настройка даёт A или A+.

Когда этим занимается студия

Всё вышесказанное — это ручная настройка, если ты сам управляешь сервером. Когда сайт делает веб-студия, SSL входит в базовую конфигурацию. В REEXY сертификат настраивается при запуске любого проекта — отдельно платить за это не нужно. Это часть инфраструктурной работы наряду с настройкой редиректов, заголовков безопасности и автообновления.

Если сайт уже есть, но SSL не настроен или сертификат периодически слетает — это решается в рамках поддержки сайта. Проблема обычно оказывается банальной: неправильный cron, закрытый порт или смена IP без обновления конфига certbot.