Настройка HTTPS в Nginx через Certbot

Пошаговое получение и подключение бесплатного TLS-сертификата Let's Encrypt для сайта Nginx через Certbot с проверкой автоматического продления.

HTTPS защищает соединение между браузером и веб-сервером с помощью TLS. Для публичного сайта бесплатный сертификат можно получить у Let's Encrypt через Certbot.

В этой инструкции рассматривается только выпуск сертификата для уже настроенного виртуального хоста Nginx, автоматическое изменение конфигурации и проверка продления.

Проверено на: Ubuntu Server 24.04 LTS
Уровень сложности: начальный
Время выполнения: около 15 минут
Требуемый доступ: пользователь с правами sudo

Что будет настроено

После выполнения инструкции:

  • будет проверен домен и виртуальный хост;
  • будет установлен Certbot;
  • будет выпущен сертификат Let's Encrypt;
  • Nginx начнёт обслуживать HTTPS;
  • HTTP будет перенаправляться на HTTPS;
  • будет проверена цепочка сертификата;
  • будет проверено автоматическое продление.

Что потребуется

Подготовьте:

Домен: example.com
IP сервера: SERVER_IP
E-mail администратора: admin@example.com

Также должны быть выполнены условия:

  • домен указывает на сервер;
  • Nginx уже установлен;
  • виртуальный хост работает по HTTP;
  • порт 80/tcp доступен из интернета;
  • порт 443/tcp не блокируется firewall;
  • сервер доступен по публичному IP.

Проверка DNS

Проверьте A-запись:

dig +short example.com

При использовании www:

dig +short www.example.com

Ожидается IP сервера.

Проверьте системный resolver:

getent hosts example.com

Если DNS возвращает другой IP, Certbot не сможет подтвердить домен через HTTP-01.

Проверка HTTP-доступа

curl -I http://example.com

Ожидается ответ Nginx:

HTTP/1.1 200 OK

Проверьте виртуальный хост:

sudo nginx -T |
grep -n 'server_name example.com'

Домен должен присутствовать в активной конфигурации Nginx.

Проверка порта 80

На сервере:

sudo ss -lntp |
grep ':80'

Ожидается процесс Nginx.

С внешнего компьютера:

curl -I http://example.com

Проверка должна выполняться не только с самого сервера, но и из внешней сети.

Проверка UFW

sudo ufw status verbose

Если UFW активен, должны быть разрешены HTTP и HTTPS.

Проверьте профили:

sudo ufw app list

Разрешите оба протокола:

sudo ufw allow 'Nginx Full'

Проверьте:

sudo ufw status numbered

После перехода на Nginx Full отдельное правило Nginx HTTP можно удалить только после проверки номеров правил.

Проверка конфигурации Nginx

sudo nginx -t

До установки Certbot конфигурация должна проходить проверку без ошибок.

Установка Certbot

Обновите индекс пакетов:

sudo apt update

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

sudo apt install -y   certbot   python3-certbot-nginx

Проверьте версию:

certbot --version

Создание резервной копии конфигурации

Перед изменением:

sudo cp   /etc/nginx/sites-available/example.com   /etc/nginx/sites-available/example.com.before-certbot

Проверьте:

ls -l   /etc/nginx/sites-available/example.com*

Certbot обычно изменяет активный server block автоматически.

Выпуск сертификата для одного домена

sudo certbot   --nginx   -d example.com

Certbot запросит:

  • e-mail;
  • согласие с условиями Let's Encrypt;
  • согласие или отказ от информационных писем;
  • настройку перенаправления HTTP на HTTPS.

Выпуск сертификата для example.com и www

Сначала убедитесь, что обе DNS-записи указывают на сервер.

Затем:

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

Не добавляйте www.example.com, если такой DNS-записи нет.

Указание e-mail без интерактивного ввода

sudo certbot   --nginx   -d example.com   --email admin@example.com   --agree-tos   --no-eff-email

Для production-сервера не используйте --register-unsafely-without-email: уведомления об истечении и проблемах сертификата важны.

Автоматическое перенаправление на HTTPS

Чтобы Certbot сразу настроил redirect:

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

После этого запрос:

http://example.com

будет перенаправляться на:

https://example.com

Что изменяет Certbot

Certbot обычно добавляет:

listen 443 ssl;
listen [::]:443 ssl;

и пути к сертификату:

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

Также может быть добавлен HTTP server block с перенаправлением на HTTPS.

Проверка изменённой конфигурации

sudo nginx -t

Покажите активный server block:

sudo nginx -T |
grep -nE   'server_name example.com|listen 443|ssl_certificate|return 301'

Проверка HTTPS

curl -I https://example.com

Ожидается:

HTTP/2 200

или:

HTTP/1.1 200 OK

Конкретная версия HTTP зависит от конфигурации Nginx и клиента.

Проверка перенаправления HTTP

curl -I http://example.com

Ожидается:

301 Moved Permanently

или другой redirect-код с заголовком:

Location: https://example.com/

Проверка перехода:

curl -IL http://example.com

Проверка сертификата через OpenSSL

openssl s_client   -connect example.com:443   -servername example.com   </dev/null 2>/dev/null |
openssl x509   -noout   -subject   -issuer   -dates   -ext subjectAltName

Проверьте:

  • доменное имя;
  • issuer;
  • дату начала;
  • дату окончания;
  • список SAN.

Проверка цепочки доверия

openssl s_client   -connect example.com:443   -servername example.com   -verify_return_error   </dev/null

В конце ожидается:

Verify return code: 0 (ok)

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

sudo ls -l   /etc/letsencrypt/live/example.com/

Обычно доступны ссылки:

cert.pem
chain.pem
fullchain.pem
privkey.pem

Закрытый ключ:

privkey.pem

нельзя копировать в публичные каталоги, логи и репозитории.

Просмотр срока действия

sudo openssl x509   -in /etc/letsencrypt/live/example.com/fullchain.pem   -noout   -dates

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

sudo certbot certificates

Команда показывает:

  • имя сертификата;
  • домены;
  • дату истечения;
  • путь к сертификату;
  • путь к закрытому ключу.

Проверка systemd timer

systemctl status certbot.timer --no-pager

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

systemctl is-enabled certbot.timer

Покажите следующее время запуска:

systemctl list-timers   --all |
grep certbot

Тест автоматического продления

sudo certbot renew --dry-run

Успешный результат означает, что Certbot смог смоделировать продление сертификата.

Тест не должен завершаться ошибкой challenge или reload Nginx.

Журнал Certbot

Основной журнал:

sudo tail -100   /var/log/letsencrypt/letsencrypt.log

Журнал systemd:

sudo journalctl -u certbot   -n 100   --no-pager

Для timer:

sudo journalctl -u certbot.timer   -n 100   --no-pager

Проверка reload после продления

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

Проверьте конфигурацию:

sudo nginx -t

Проверьте reload вручную:

sudo systemctl reload nginx

Для стандартной установки дополнительные deploy hooks обычно не требуются.

Добавление нового домена в существующий сертификат

Допустим, нужно добавить:

www.example.com

Сначала создайте DNS-запись, затем:

sudo certbot   --nginx   --cert-name example.com   -d example.com   -d www.example.com   --expand

Проверьте:

sudo certbot certificates

Не удаляйте старое имя из команды случайно: Certbot сформирует новый набор доменов сертификата.

Удаление домена из сертификата

Перевыпустите сертификат с нужным набором имён:

sudo certbot   --nginx   --cert-name example.com   -d example.com

Перед выполнением проверьте, что удаляемое имя больше не используется.

Отзыв сертификата

Отзыв нужен при компрометации закрытого ключа или ошибочном выпуске.

sudo certbot revoke   --cert-path   /etc/letsencrypt/live/example.com/cert.pem

После отзыва создайте новый сертификат и новый ключ.

Удаление сертификата из Certbot

Покажите список:

sudo certbot certificates

Удалите:

sudo certbot delete   --cert-name example.com

Перед удалением уберите ссылки на сертификат из конфигурации Nginx.

Иначе Nginx перестанет запускаться.

Восстановление конфигурации до Certbot

Отключите HTTPS-конфигурацию и восстановите резервную копию:

sudo cp   /etc/nginx/sites-available/example.com.before-certbot   /etc/nginx/sites-available/example.com

Проверьте:

sudo nginx -t

Примените:

sudo systemctl reload nginx

Сертификат можно удалить только после восстановления рабочей HTTP-конфигурации.

Несколько виртуальных хостов

Для каждого независимого домена лучше выпускать отдельный сертификат:

sudo certbot   --nginx   -d example.net

Это упрощает:

  • продление;
  • удаление;
  • диагностику;
  • перенос сайта;
  • управление доменами.

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

Сертификат вида:

*.example.com

нельзя получить через HTTP-01.

Для wildcard требуется DNS-01 challenge и доступ к DNS API либо ручное создание TXT-записи.

Wildcard-сертификаты рассматриваются отдельно.

Внутренние домены

Let's Encrypt не выпускает сертификаты для:

localhost
server.local
внутреннего IP
частного имени без публичной DNS-зоны

Для внутренней инфраструктуры используйте:

  • собственный центр сертификации;
  • публичный домен с DNS-01;
  • корпоративную PKI;
  • сертификат reverse proxy.

Типичные проблемы

Certbot сообщает unauthorized

Проверьте:

dig +short example.com
curl -I http://example.com

Let's Encrypt должен попасть именно на этот сервер.

Timeout during connect

Проверьте:

  • порт 80;
  • UFW;
  • firewall провайдера;
  • NAT;
  • security group;
  • публичную маршрутизацию.

Неверный server_name

Проверьте:

sudo nginx -T |
grep -n 'server_name'

Домен должен присутствовать в активном server block.

Certbot не находит подходящий virtual host

Проверьте, что файл включён:

ls -l /etc/nginx/sites-enabled/

Проверьте:

sudo nginx -T |
grep -n 'example.com'

Ошибка too many certificates

Let's Encrypt применяет rate limits.

Для повторных экспериментов используйте staging:

sudo certbot   --nginx   -d example.com   --test-cert

Тестовый сертификат не является доверенным браузером.

HTTPS работает, но браузер показывает неверный сертификат

Проверьте:

  • используемый домен;
  • server_name;
  • дублирующие listen 443;
  • SNI;
  • активную конфигурацию;
  • кэш браузера.

Команда:

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

certbot renew --dry-run завершается ошибкой

Проверьте журнал:

sudo tail -100   /var/log/letsencrypt/letsencrypt.log

Частые причины:

  • изменился DNS;
  • закрыт порт 80;
  • удалён server block;
  • Nginx не проходит nginx -t;
  • домен больше не указывает на сервер.

После Certbot Nginx не перезагружается

Проверьте:

sudo nginx -t

Исправьте указанный файл.

Не удаляйте файлы из /etc/letsencrypt вручную.

Безопасный порядок настройки

  1. Проверить DNS.
  2. Проверить внешний HTTP-доступ.
  3. Проверить UFW.
  4. Выполнить nginx -t.
  5. Создать резервную копию server block.
  6. Установить Certbot.
  7. Выпустить сертификат.
  8. Проверить HTTPS.
  9. Проверить redirect.
  10. Проверить сертификат через OpenSSL.
  11. Выполнить certbot renew --dry-run.
  12. Проверить timer.

Быстрый набор команд

Установка:

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

Выпуск:

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

Проверка:

curl -I https://example.com

Сертификаты:

sudo certbot certificates

Тест продления:

sudo certbot renew --dry-run

Итог

После выполнения инструкции:

  • проверены DNS и HTTP-доступ;
  • установлен Certbot;
  • выпущен сертификат Let's Encrypt;
  • Nginx настроен на HTTPS;
  • включено перенаправление HTTP на HTTPS;
  • проверена цепочка доверия;
  • проверено автоматическое продление.

Следующим самостоятельным этапом можно настроить Nginx как reverse proxy для внутреннего приложения.

← Предыдущая статья Создание виртуального хоста Nginx для отдельного домена Следующая статья → Настройка reverse proxy в Nginx