Если сайт открывается с предупреждением «Небезопасное соединение» — большинство пользователей закроет вкладку. Не потому что они параноики, просто браузеры уже давно воспитали у людей этот рефлекс. SSL-сертификат сегодня — не опция, а базовая гигиена.

Разберём, как это работает, где брать сертификаты бесплатно и как настроить автообновление так, чтобы забыть об этом вопросе навсегда.

Что такое SSL и зачем он нужен

SSL (точнее, его современная версия TLS) — это протокол шифрования, который защищает данные между браузером пользователя и сервером. Без него всё передаётся в открытом виде: пароли, номера карт, личные данные.

Помимо безопасности, сертификат влияет на:

  • SEO — Google с 2014 года учитывает HTTPS как фактор ранжирования.
  • Доверие — замочек в адресной строке визуально сигнализирует о надёжности.
  • Работу браузеров — Chrome помечает HTTP-сайты как небезопасные, Firefox блокирует часть функций (геолокацию, камеру) без HTTPS.
  • Производительность — HTTP/2 и HTTP/3 работают только по HTTPS.

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

Let's Encrypt — что это и почему все им пользуются

Let's Encrypt — некоммерческий удостоверяющий центр (CA), запущенный в 2016 году при поддержке Mozilla, EFF, Cisco и других. Он выдаёт DV-сертификаты бесплатно и автоматически.

На апрель 2026 года Let's Encrypt обслуживает более 350 миллионов активных сертификатов. Это де-факто стандарт для большинства проектов.

Ограничения Let's Encrypt, которые стоит знать:

  • Срок действия сертификата — 90 дней (не год, как у платных).
  • Лимиты выдачи: 50 сертификатов на домен в неделю, 5 дублирующих сертификатов в неделю.
  • Нет OV/EV — только доменная валидация.
  • Wildcard-сертификаты (*.example.com) поддерживаются, но требуют DNS-challenge.

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

Как работает получение сертификата

Let's Encrypt использует протокол ACME (Automatic Certificate Management Environment). Клиент на сервере общается с серверами Let's Encrypt и доказывает, что контролирует домен одним из способов:

HTTP-01 challenge — Let's Encrypt проверяет файл по адресу http://yourdomain.com/.well-known/acme-challenge/TOKEN. Самый простой способ для одного домена.

DNS-01 challenge — нужно создать TXT-запись в DNS. Подходит для wildcard-сертификатов и случаев, когда сервер закрыт от интернета.

TLS-ALPN-01 challenge — проверка через TLS на 443 порту. Используется реже.

Certbot — самый популярный клиент

Certbot от EFF — стандартный инструмент для работы с Let's Encrypt. Устанавливается на большинство дистрибутивов.

Установка на 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, получит сертификат и настроит HTTPS-редирект. После выполнения команды он спросит email для уведомлений и предложит автоматически настроить редирект с HTTP на HTTPS.

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

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

Только получить сертификат без правки конфигов

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

Сертификаты окажутся в /etc/letsencrypt/live/example.com/:

  • fullchain.pem — цепочка сертификатов (нужна для Nginx/Apache)
  • privkey.pem — приватный ключ
  • cert.pem — только ваш сертификат
  • chain.pem — промежуточные сертификаты

Настройка Nginx с Let's Encrypt

Типичный конфиг после получения сертификата:

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;

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

    # ваш основной конфиг
    root /var/www/example.com;
    index index.html;
}

Параметр ssl_protocols TLSv1.2 TLSv1.3 — убираем старые TLS 1.0 и 1.1, которые считаются небезопасными. HSTS через заголовок Strict-Transport-Security сообщает браузерам, что сайт всегда доступен только по HTTPS.

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

90-дневный срок жизни сертификата означает, что без автообновления сайт упадёт ровно через три месяца. Let's Encrypt присылает письма за 30, 14 и 7 дней до истечения, но лучше не полагаться на почту.

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

Новые версии certbot при установке через apt автоматически создают systemd-timer. Проверить:

sudo systemctl status certbot.timer

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

Посмотреть, когда последний раз отрабатывал таймер:

sudo systemctl list-timers certbot.timer

Через cron (если systemd timer не создался)

Добавить в crontab:

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

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

Проверка автообновления

Чтобы убедиться, что процесс работает, без реального обновления:

sudo certbot renew --dry-run

Если вывод заканчивается на Congratulations, all simulated renewals succeeded — всё настроено правильно.

Wildcard-сертификаты через DNS-challenge

Wildcard-сертификат (*.example.com) покрывает все поддомены: api.example.com, app.example.com, blog.example.com и т.д. Для его получения нужен DNS-01 challenge.

Пример с использованием Cloudflare:

sudo apt install python3-certbot-dns-cloudflare

Создать файл с API-ключом Cloudflare:

sudo nano /etc/letsencrypt/cloudflare.ini
dns_cloudflare_api_token = ВАШ_API_TOKEN
sudo 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-провайдеров есть аналогичные плагины: certbot-dns-route53, certbot-dns-digitalocean, certbot-dns-yandex и другие.

acme.sh — альтернатива Certbot

Если Certbot кажется тяжёлым или нужна более гибкая настройка, есть acme.sh — shell-скрипт без зависимостей.

curl https://get.acme.sh | sh -s email=your@email.com

Получить сертификат:

acme.sh --issue -d example.com --webroot /var/www/html

Установить в Nginx:

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-задание при установке. Умеет работать с десятками DNS-провайдеров напрямую, включая российские: reg.ru, beget, selectel.

Частые ошибки и как их избежать

Сертификат не обновился, Nginx не перезагружен. Всегда добавляйте --post-hook или --deploy-hook с перезагрузкой веб-сервера. Certbot обновит файлы, но Nginx узнает об этом только после reload.

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

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

Порт 80 закрыт файрволом. HTTP-01 challenge требует доступа на 80 порт. Проверьте:

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

Сертификат для IP-адреса. Let's Encrypt не выдаёт сертификаты для голых IP. Только для доменных имён.

Неправильные права на файлы. Приватный ключ должен читаться только root:

ls -la /etc/letsencrypt/live/example.com/

Нормальный вывод — lrwxrwxrwx root root для симлинков и drwx------ root root для директорий.

Проверка сертификата

Посмотреть информацию о сертификате прямо из терминала:

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

Вывод покажет notBefore и notAfter — даты начала и окончания действия.

Для красивого вывода:

echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -text | grep -A2 Validity

Онлайн-инструменты: SSL Labs (ssllabs.com/ssltest) даёт детальный отчёт с оценкой конфигурации от A до F. Стремитесь к A+.

Когда Let's Encrypt не подойдёт

Для банков, платёжных систем и крупного e-commerce иногда требуют OV или EV-сертификаты — они подтверждают юридическое лицо, а не только домен. Их выдают платные CA: Sectigo, DigiCert, GlobalSign. Стоимость от 3 000 до 50 000 рублей в год.

Также платный сертификат стоит рассмотреть, если нужна расширенная техническая поддержка или SLA на доступность CA.

Для обычных корпоративных сайтов, лендингов, интернет-магазинов и сервисов Let's Encrypt полностью закрывает потребности. В REEXY при разработке сайтов — от лендинга за 3 500 ₽ до корпоративного сайта за 15 000 ₽ — настройка SSL входит в стандартный процесс развёртывания.

Мониторинг истечения сертификатов

Даже с автообновлением имеет смысл настроить внешний мониторинг — на случай, если что-то сломается в автоматике.

Простой bash-скрипт для проверки:

#!/bin/bash
DOMAIN="example.com"
THRESHOLD=14

EXPIRY=$(echo | openssl s_client -connect $DOMAIN:443 -servername $DOMAIN 2>/dev/null \
  | openssl x509 -noout -enddate | cut -d= -f2)

EXPIRY_EPOCH=$(date -d "$EXPIRY" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))

if [ $DAYS_LEFT -lt $THRESHOLD ]; then
  echo "WARNING: $DOMAIN certificate expires in $DAYS_LEFT days!"
  # отправить алерт
fi

Запускать через cron раз в день. Есть готовые решения: check_ssl_cert (Nagios-плагин), Prometheus с экспортёром ssl_exporter, или просто uptimerobot.com с проверкой SSL.

Итого

Let's Encrypt убрал главный барьер для HTTPS — его стоимость. Теперь нет причин держать сайт на HTTP. Схема простая: ставим certbot, получаем сертификат, настраиваем автообновление через systemd timer или cron, проверяем --dry-run.

Автообновление — не «настроил и забыл» навсегда. Раз в несколько месяцев стоит проверять, что таймер жив и сертификаты обновляются. Пять минут профилактики лучше, чем разбор ситуации в 2 ночи, когда у клиента упал сайт.