MHOSTMHOST

Как установить SSL-сертификат Let's Encrypt на Nginx: пошаговая инструкция

Let's Encrypt — бесплатный центр сертификации, которому доверяют все современные браузеры. С его сертификатом сайт открывается по HTTPS, браузер не показывает предупреждение «Не защищено», а поисковики не понижают сайт.

В инструкции получим сертификат через утилиту Certbot, которая сама настроит Nginx, включит перенаправление с HTTP на HTTPS и автоматическое продление.

Почему автопродление критично. Сертификаты Let's Encrypt сейчас действуют 90 дней, а срок постепенно сокращается: с февраля 2027 года — 64 дня, с февраля 2028 года — 45 дней. Письма о скором истечении срока Let's Encrypt больше не присылает. Если продление сломается, вы узнаете об этом от клиентов. Поэтому в статье отдельно разбираем, как проверить автопродление.

Требования:

  • Сервер на Ubuntu 22.04, 24.04 или 26.04 с установленным Nginx.
  • Домен, A-запись которого указывает на IP сервера. Проверка: dig +short example.com.
  • Открытые порты 80 и 443. Порт 80 нужен даже для HTTPS: через него Let's Encrypt проверяет, что домен принадлежит вам.

Шаг 1. Установите Certbot

Установите Certbot и плагин для Nginx из репозитория Ubuntu:

sudo apt update

sudo apt install -y certbot python3-certbot-nginx

Проверьте установку: certbot --version.

Разработчики Certbot также распространяют его через snap: там всегда самая свежая версия. Если предпочитаете её, установите вместо apt-пакета:

sudo snap install --classic certbot

sudo ln -s /snap/bin/certbot /usr/bin/certbot

Не ставьте оба варианта сразу: две версии Certbot будут конфлитовать при продлении.

Если на сервере включён firewall, откройте веб-порты:

sudo ufw allow 'Nginx Full'

Шаг 2. Подготовьте конфиг сайта в Nginx

Certbot ищет в конфигах Nginx блок server с вашим доменом в строке server_name и сам дописывает туда настройки HTTPS. Если конфиг сайта уже есть, проверьте, что домен указан в server_name, и переходите к шагу 3.

Если конфига нет, создайте минимальный. Замените example.com на свой домен:

sudo nano /etc/nginx/sites-available/example.com

Вставьте содержимое:

server {

listen 80;

server_name example.com www.example.com;

root /var/www/example.com;

index index.html;

}

Создайте папку сайта с тестовой страницей и включите конфиг:

sudo mkdir -p /var/www/example.com

echo '<h1>It works</h1>' | sudo tee /var/www/example.com/index.html

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/

sudo nginx -t && sudo systemctl reload nginx

Откройте http://example.com в браузере — должна появиться надпись «It works». Если вместо неё видна страница Nginx по умолчанию, проверьте server_name.

Домен с www и без. Включите оба варианта в server_name и создайте A-запись для www. Иначе сертификат будет только на один адрес, и при входе по второму браузер покажет ошибку.

Шаг 3. Получите сертификат

Одна команда получает сертификат и настраивает HTTPS в Nginx:

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

При первом запуске Certbot спросит:

  1. Email. На него придут важные уведомления об аккаунте. Напоминаний об истечении срока больше не будет.
  2. Согласие с условиями использования Let's Encrypt — ответьте Y.
  3. Рассылку EFF (организации, которая разрабатывает Certbot) — на ваш выбор.

Certbot проверит, что домен указывает на ваш сервер, получит сертификат и допишет в конфиг Nginx настройки HTTPS и перенаправление всех запросов с HTTP на HTTPS. В конце появится сообщение Successfully deployed certificate.

Файлы сертификата лежат в /etc/letsencrypt/live/example.com/:

  • fullchain.pem — сертификат вместе с промежуточными, его указывают в ssl_certificate.
  • privkey.pem — закрытый ключ сертификата, его указывают в ssl_certificate_key. Никому не передавайте.

Если хотите получить сертификат, не давая Certbot менять конфиг Nginx, используйте certonly: sudo certbot certonly --nginx -d example.com. Тогда строки ssl_certificate и ssl_certificate_key в конфиг нужно добавить вручную.

Шаг 4. Проверьте сертификат и автопродление

Откройте https://example.com — в адресной строке должен появиться замок. Адрес с http:// должен сам перенаправлять на HTTPS.

Список сертификатов на сервере и срок их действия:

sudo certbot certificates

Автопродление. Certbot сам создаёт таймер systemd, который дважды в день проверяет сертификаты и продлевает те, что скоро истекают. Убедитесь, что таймер активен:

systemctl list-timers | grep certbot

В выводе должен быть certbot.timer (для snap-версии — snap.certbot.renew.timer) с временем следующего запуска.

Проверьте, что продление сработает, с помощью тестового запуска (настоящие сертификаты он не трогает):

sudo certbot renew --dry-run

Если в конце есть строка Congratulations, all simulated renewals succeeded, автопродление работает. При продлении через плагин --nginx Certbot сам перезагружает Nginx, чтобы тот подхватил новый сертификат.

Проверка снаружи. Узнать, когда истекает сертификат, который реально отдаёт сайт, можно с любого компьютера:

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

Раз Let's Encrypt больше не присылает письма об истечении срока, подключите внешний мониторинг с проверкой SSL: он предупредит в Telegram или на почту, если до истечения останется меньше недели — значит, автопродление сломалось.

Wildcard-сертификат для всех поддоменов

Wildcard-сертификат *.example.com подходит для любых поддоменов: app.example.com, n8n.example.com, shop.example.com. Удобно, если поддоменов много или они создаются динамически.

Для wildcard Let's Encrypt проверяет домен не через сайт, а через DNS: Certbot должен создать специальную TXT-запись. Чтобы продление шло автоматически, нужен плагин для вашего DNS-провайдера. Покажем на примере Cloudflare — самого популярного варианта.

Установите плагин:

sudo apt install -y python3-certbot-dns-cloudflare

В Cloudflare создайте API-токен по шаблону Edit zone DNS для вашего домена. Сохраните его в файл с доступом только для root:

sudo mkdir -p /root/.secrets

echo 'dns_cloudflare_api_token = ВАШ_ТОКЕН' | sudo tee /root/.secrets/cloudflare.ini

sudo chmod 600 /root/.secrets/cloudflare.ini

Получите сертификат на основной домен и все поддомены. Параметр --deploy-hook запомнится и будет перезагружать Nginx после каждого продления:

sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials /root/.secrets/cloudflare.ini -d example.com -d "*.example.com" --deploy-hook "systemctl reload nginx"

При certonly Certbot не меняет конфиг Nginx, поэтому добавьте в блок server каждого поддомена строки:

listen 443 ssl;

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

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

Для других DNS-провайдеров есть свои плагины (например, python3-certbot-dns-digitalocean). Если плагина нет, wildcard можно получить вручную через --manual, но тогда продлевать тоже придётся вручную — с нынешними сроками это непрактично.

Let's Encrypt и Cloudflare: что учесть

Если домен работает через прокси Cloudflare (оранжевое облако), посетители видят сертификат Cloudflare, а сертификат на вашем сервере защищает соединение между Cloudflare и VPS. В этом случае:

  • В Cloudflare включите режим SSL/TLS Full (strict). Режим Flexible оставляет трафик до сервера незашифрованным и в связке с перенаправлением на HTTPS на сервере даёт бесконечный цикл редиректов.
  • Первый выпуск сертификата. Проще всего на время выпуска переключить запись на серое облако (DNS only), а потом вернуть оранжевое.
  • Надёжнее всего — DNS-проверка. Плагин python3-certbot-dns-cloudflare из раздела про wildcard работает независимо от прокси и firewall: серверу вообще не нужен открытый наружу порт 80. Это особенно важно, если вы пускаете на сервер только IP Cloudflare, как в статье как защитить VPS от DDoS-атак.

Альтернатива — Cloudflare Origin Certificate. Бесплатный сертификат от Cloudflare сроком до 15 лет, продлевать не нужно. Но ему доверяет только Cloudflare: если выключить прокси, браузеры покажут ошибку. Let's Encrypt универсальнее: сайт останется доступен по HTTPS и без Cloudflare.

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

  • Timeout during connect или Connection refused при проверке домена. Let's Encrypt не может достучаться до сервера по порту 80. Проверьте firewall (sudo ufw status), что Nginx запущен, и что домен указывает на правильный IP: dig +short example.com.
  • Could not automatically find a matching server block. В конфигах Nginx нет блока с вашим доменом в server_name. Вернитесь к шагу 2.
  • too many certificates already issued. Сработал лимит Let's Encrypt на повторный выпуск одинаковых сертификатов (не больше 5 в неделю). Подождите и для экспериментов используйте тестовый сервер: добавляйте к команде --dry-run или --staging.
  • Браузер пишет NET::ERR_CERT_COMMON_NAME_INVALID на www-адресе. В сертификат не включён www. Добавьте его: sudo certbot --nginx --expand -d example.com -d www.example.com.
  • ERR_TOO_MANY_REDIRECTS. Почти всегда это Cloudflare в режиме Flexible. Переключите SSL/TLS на Full (strict).
  • Сертификат продлился, но сайт отдаёт старый. Nginx не перезагрузили после продления. Выполните sudo systemctl reload nginx и для сертификатов, полученных через certonly, добавьте --deploy-hook "systemctl reload nginx".

Чек-лист

Частые вопросы

Сколько стоит сертификат Let's Encrypt? Нисколько, он бесплатный. Браузеры доверяют ему так же, как платным DV-сертификатам.

Чем отличается от платного SSL? Шифрование такое же. Платные сертификаты нужны, если требуется проверка организации (OV/EV), страховая гарантия или поддержка центра сертификации.

Сколько действует сертификат? Сейчас 90 дней. С февраля 2027 года — 64 дня, с февраля 2028 года — 45 дней. С настроенным автопродлением это ни на что не влияет.

Можно ли выпустить сертификат на несколько доменов сразу? Да, перечислите их через несколько флагов -d. Один сертификат может покрывать до 100 имён.

Как удалить сертификат, который больше не нужен? sudo certbot delete --cert-name example.com. Перед этим уберите ссылки на него из конфига Nginx, иначе Nginx не запустится.