Let's Encrypt и ACME: certbot, acme.sh, нативный ACME Angie

Рейтинг: 62.3% · 11 голосов
Самый подробный курс по Nginx - от первого конфига до production API-gateway. Архитектура и event loop, контексты и location, виртуальные хосты, статика, reverse proxy и upstream-балансировка, кэширование, HTTPS и TLS (post-quantum), HTTP/2 и HTTP/3 QUIC, безопасность и rate limiting, realip, JSON-логи и сквозная трассировка, метрики, тюнинг и траблшутинг. Плюс OpenResty (Lua, фазы, JWT, динамика) и Angie (нативные Prometheus, ACME, dynamic upstream). На основе эталонного gateway и лучших практик. Для новичков и SRE/DevOps. Актуально на 2026 (nginx 1.30/1.31, Angie, ingress-nginx EOL -> Gateway API).
Ответить
Аватара пользователя
Igor_NgINX
Сообщения: 44
Зарегистрирован: 11 май 2026, 05:31

Let's Encrypt и ACME: certbot, acme.sh, нативный ACME Angie

Сообщение Igor_NgINX »

Оглавление курса (44)
  1. Что такое Nginx и почему он захватил веб
  2. Установка Nginx, Angie и OpenResty: пакеты, версии, Docker
  3. Первый конфиг с нуля: минимальный сервер за 5 минут
  4. Архитектура процессов: master, worker и event loop
  5. Анатомия конфигурации: контексты, наследование и модульность
  6. Виртуальные хосты: server и server_name
  7. Директива location: матчинг и приоритеты по шагам
  8. Раздача статики: root, alias, try_files, sendfile
  9. Переменные, map и блок if
  10. rewrite, return и канонизация URL
  11. Работа с заголовками: add_header и proxy_set_header
  12. Модель доверия прокси-заголовков: realip и защита от спуфинга
  13. Сжатие: gzip, brotli и zstd
  14. Reverse proxy: proxy_pass и проброс запроса
  15. upstream и балансировка нагрузки
  16. Таймауты, повторы и устойчивость прокси
  17. FastCGI и PHP: nginx + PHP-FPM (и uwsgi/scgi)
  18. WebSocket, gRPC и стриминг через Nginx
  19. Кэширование ответов: proxy_cache и микрокэш
  20. HTTPS и TLS: сертификаты, протоколы, шифры (2026)
  21. Let's Encrypt и ACME: certbot, acme.sh, нативный ACME Angie (вы здесь)
  22. HTTP/2 и HTTP/3 (QUIC) в 2026
  23. Безопасность: заголовки, скрытие версии, ограничения
  24. Rate limiting и защита от перегрузки
  25. Контроль доступа: allow/deny, auth_basic, auth_request и mTLS
  26. Логирование: access_log, форматы и структурированный JSON
  27. Сквозная трассировка запросов и OpenTelemetry
  28. Метрики и мониторинг Nginx
  29. Производительность и тюнинг под нагрузку
  30. Траблшутинг: 502, 504, 403, 404 и debug-лог
  31. OpenResty: Nginx как платформа на LuaJIT
  32. Фазы обработки запроса и Lua-хуки
  33. Lua API: ngx.*, shared dict, cosocket и lua-resty-core
  34. Практика OpenResty: авторизация, JWT, кэш, Redis
  35. Angie: современный форк Nginx 2026
  36. Динамическая конфигурация и service discovery
  37. Nginx как API-gateway и Kubernetes Gateway API
  38. Динамические модули, njs и WAF
  39. Stream-модуль: проксирование TCP и UDP
  40. Деплой, перезагрузка и конфиг как код
  41. Сценарий: статика, SPA и кэширование за CDN
  42. Сценарий: микросервисный gateway по образцу ngx-trace-gateway
  43. Капстоун: собираем production-gateway с нуля
  44. Чек-лист безопасности, CVE 2026 и аудит конфигурации
Раньше HTTPS стоил денег и нервов: купить сертификат, прислать паспорт, скачать архив из четырёх файлов, склеить цепочку в правильном порядке, через год повторить - и не забыть, иначе в понедельник утром у всех клиентов красный замок и паника в чате. Let's Encrypt убрал из этой схемы деньги, бюрократию и (почти весь) ручной труд. Сегодня nginx letsencrypt - это не разовая операция, а фоновый процесс, который сам выпускает и продлевает бесплатные сертификаты. Но дьявол в деталях: какой challenge выбрать, где лежит .well-known, как не упереться в rate limits и почему в 2026 для нового проекта стоит присмотреться к Angie, у которого ACME встроен прямо в конфиг. Разберём механику до винтика.

Что такое ACME и DV-сертификат - механика на пальцах

ACME (Automatic Certificate Management Environment, RFC 8555) - это протокол диалога между твоим сервером и центром сертификации (CA), например Let's Encrypt. Никакого живого человека: всё машинно. Сертификат, который ты получаешь - DV (Domain Validation), то есть CA подтверждает только одно: ты реально управляешь доменом. Не компанией, не юрлицом - именно доменом. Для веб-сайта этого достаточно, браузер рисует тот же замок, что и для дорогого OV/EV.

Как CA убеждается, что домен твой? Он даёт тебе задачу - challenge - которую может выполнить только владелец домена. Три основных типа:
  • HTTP-01 - CA говорит "положи файл с таким-то содержимым по адресу http://твойдомен/.well-known/acme-challenge/ТОКЕН и я его скачаю". Если файл на месте - значит, ты управляешь веб-сервером на 80 порту этого домена. Самый простой, но требует доступности по HTTP на 80 порту и НЕ умеет wildcard.
  • DNS-01 - CA говорит "создай TXT-запись _acme-challenge.твойдомен со значением X". Проверяется через DNS. Единственный способ получить wildcard (*.example.com), работает даже для серверов без публичного доступа, но требует API к твоему DNS-провайдеру.
  • TLS-ALPN-01 - валидация прямо в TLS-хендшейке на 443, нишевый вариант.
Алгоритм выпуска всегда один: клиент создаёт аккаунт (пара ключей), отправляет заказ (order) на список доменов, CA возвращает challenges, клиент их выполняет, говорит "проверяй", CA проверяет, клиент шлёт CSR, получает сертификат. Срок жизни - 90 дней, и тут важная новость 2026: Let's Encrypt запускает короткоживущие сертификаты на 45 дней (короче срок - меньше ущерба при утечке ключа). Вывод простой: ручное продление мертво как класс, автоматика обязательна.

Изображение

nginx certbot: три способа получить бесплатный сертификат

В ванильном nginx своего ACME-клиента в ядре НЕТ. Стандартный инструмент - certbot. У него три рабочих режима, и выбор между ними определяет всю эксплуатацию.

Режим 1: плагин --nginx (магия "сделай всё за меня"). Certbot сам читает твой nginx.conf, временно правит его под HTTP-01, выпускает сертификат и вписывает ssl_certificate в конфиг:

Код: Выделить всё

certbot --nginx -d example.com -d www.example.com
Удобно для одного сайта на одной машине. Минус - certbot лезет в твои конфиги автоматическим парсером, а если у тебя модульная структура с десятком include (как в эталонном ngx-trace-gateway), парсер может не понять её и сломать. Для сложных шлюзов этот режим не подходит.

Режим 2: webroot (контроль в твоих руках). Certbot только кладёт challenge-файл в каталог, который ты сам отдаёшь по HTTP, и не трогает конфиг вообще:

Код: Выделить всё

certbot certonly --webroot -w /var/www/acme -d example.com -d www.example.com
А в nginx ты заранее настраиваешь отдачу .well-known. Это самый предсказуемый способ для продакшена. В http_server.conf добавляешь:

Код: Выделить всё

location ^~ /.well-known/acme-challenge/ {
    root /var/www/acme;
    default_type "text/plain";
    allow all;
    access_log off;
}
Префикс ^~ критичен: он гарантирует, что этот location выиграет приоритет над регэксп-локациями статики и редиректами. Очень частая грабля - правило app_redirects_security или общий redirect на HTTPS перехватывает /.well-known раньше, и CA получает 301 вместо файла. Поэтому location для acme-challenge всегда ставь выше любых return 301 и не редиректь его на HTTPS.

Режим 3: DNS-01 для wildcard. Если нужен nginx wildcard сертификат (*.example.com - один сертификат на все поддомены), HTTP-01 не подойдёт в принципе, только DNS-01:

Код: Выделить всё

certbot certonly --dns-cloudflare \
  --dns-cloudflare-credentials /etc/letsencrypt/cf.ini \
  -d example.com -d "*.example.com"
Certbot через плагин сам создаёт TXT-запись, ждёт распространения, проходит валидацию и убирает запись. Нужен API-токен провайдера (Cloudflare, Route53, и т.д.). Wildcard на Let's Encrypt бывает ТОЛЬКО через DNS-01 - запомни это намертво.

Альтернатива certbot - acme.sh, чистый shell-скрипт без зависимостей от Python, с поддержкой десятков DNS-провайдеров из коробки. Логика та же, многие предпочитают его на минималистичных серверах за лёгкость и отсутствие питоновского окружения.

Автопродление и reload: чтобы nginx ssl автоматически не протух

Выпустить сертификат - половина дела. Вторая половина - продлевать его без участия человека и подхватывать новый файл. Современный пакет certbot ставит systemd-таймер, который дважды в день дёргает renew:

Код: Выделить всё

systemctl list-timers | grep certbot
certbot renew --dry-run
Команда renew умна: она трогает только сертификаты, которым осталось меньше 30 дней (а с 45-дневными сертификатами 2026 - продлевает на трети срока жизни). Остальные пропускает, чтобы не жечь лимиты. Ключевой момент - после обновления файлов nginx надо перечитать конфиг, он не следит за сертификатами на диске сам. Это делается через deploy-hook:

Код: Выделить всё

certbot renew --deploy-hook "nginx -s reload"
Хук выполняется ТОЛЬКО если сертификат реально обновился, поэтому лишних reload не будет. Если ставишь crontab вручную (не systemd), строка такая:

Код: Выделить всё

17 3 * * * certbot renew --quiet --deploy-hook "nginx -s reload"
Время 3:17, а не 3:00 - намеренно: не бей по CA в круглый час вместе с миллионом других серверов. И всегда гоняй --dry-run при настройке: он повторяет весь цикл против staging-окружения LE без расхода лимитов и без выписки реального сертификата.

Про цепочку сертификатов. CA выдаёт не один файл, а лист (твой сертификат) + промежуточные (intermediate) сертификаты CA. Браузеру нужна вся цепочка до доверенного корня, иначе часть клиентов (особенно старый Android и боты) получит ошибку доверия. Certbot складывает готовую цепочку в fullchain.pem - в ssl_certificate указывай ИМЕННО его, не cert.pem:

Код: Выделить всё

ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
Это типичная ошибка новичка - подставить cert.pem без промежуточных и потом ловить "неполную цепочку" в SSL Labs.

angie acme: нативный ACME прямо в конфиге - киллер-фича 2026

А теперь главное отличие 2026 года. Angie (форк nginx от части бывшей команды разработки) принёс то, чего нет в ядре nginx: нативный ACME-клиент прямо в конфигурации, бесплатно и без внешних инструментов. Никакого certbot, никаких systemd-таймеров, никаких deploy-hook. Объявляешь acme_client в http-блоке - и Angie сам выпускает, продлевает и подгружает сертификат БЕЗ reload. Сертификаты ECDSA из коробки. Конфиг буквально такой:

Код: Выделить всё

http {
    resolver 1.1.1.1 8.8.8.8 valid=300s;

    acme_client le https://acme-v02.api.letsencrypt.org/directory;

    server {
        listen 443 ssl;
        server_name example.com www.example.com;

        acme le;

        ssl_certificate     $acme_cert_le;
        ssl_certificate_key $acme_cert_key_le;

        location / {
            root /var/www/html;
        }
    }
}
Разберём механику. Директива acme_client задаёт именованного клиента и URL директории CA. resolver обязателен - Angie резолвит адрес ACME-сервера динамически. В server-блоке директива acme le подключает домены этого сервера к клиенту, а переменные $acme_cert_le и $acme_cert_key_le отдают свежий сертификат и ключ прямо в ssl_certificate. Angie перехватывает /.well-known/acme-challenge/ТОКЕН на уровне ядра ДО выбора виртуального сервера - тебе не нужно вручную настраивать location под challenge. Продление происходит само в фоне, новый сертификат применяется без перезагрузки воркеров - старые соединения не рвутся.

Это серьёзно меняет эксплуатацию: один файл конфига вместо связки nginx + certbot + cron + hooks. Для нового продакшена в 2026 это сильный аргумент в пользу Angie. Оговорка: встроенный модуль Angie работает по HTTP-01, поэтому wildcard через него не выпустить - для *.example.com по-прежнему нужен DNS-01 через внешний acme.sh/certbot или DNS-провайдера, и сертификат подаётся обычным ssl_certificate.

А что в ванильном nginx - ACME через модуль, но не в ядре

Чтобы не было путаницы: в самом nginx нативного ACME в ядре НЕТ - не ищи core-директиву acme в ванильном nginx, её там не существует. Но в 2025-2026 появились ОФИЦИАЛЬНЫЕ модули от команды nginx, которые добавляют ACME через подключаемый модуль:
  • nginx-acme (модуль ngx_http_acme_module) - новый модуль на Rust SDK, ставится пакетом nginx-module-acme, доступен и для OSS, и для Plus с версии 1.29.0. На момент 2026 он в статусе preview и поддерживает только HTTP-01 (DNS-01 и wildcard - в планах, но ещё нет).
  • njs-acme - реализация на njs (JavaScript-движке nginx) поверх ngx_http_js_module, библиотека работает с Let's Encrypt без reload.
Ключевой нюанс: оба - это подключаемые модули (load_module), а не встроенный функционал ядра. То есть "нативный ACME прямо из коробки в конфиге" - это про Angie, а для nginx ты либо ставишь дополнительный модуль, либо используешь проверенный временем certbot/acme.sh. Для большинства существующих установок certbot + webroot остаётся самым надёжным и предсказуемым выбором.

Типичные грабли
  • Rate limits Let's Encrypt. Это боль номер один. Лимит - 50 сертификатов на зарегистрированный домен за 7 дней и (важнее при отладке) всего 5 дубликатов одного и того же набора имён за неделю. Перевыпустил конфиг пять раз подряд в проде - и ты в бане на неделю с реальным доменом. Поэтому отлаживай ТОЛЬКО против staging LE (--test-cert или --dry-run): там лимиты огромные, а сертификат невалидный, но процесс полностью идентичен.
  • Редирект перехватывает .well-known. Общий return 301 на HTTPS или фильтры из app_redirects_security ловят /.well-known/acme-challenge раньше нужного location. CA получает редирект вместо токена и валидация падает. Лечение - location ^~ /.well-known/acme-challenge/ выше всех редиректов, без редиректа на HTTPS.
  • Забыл reload после продления. Файл на диске обновился, а nginx держит в памяти старый - и за день до истечения отдаёт протухший сертификат. Всегда deploy-hook "nginx -s reload". У Angie этой грабли нет - он перечитывает сам.
  • Подставил cert.pem вместо fullchain.pem. Неполная цепочка, часть клиентов получает ошибку доверия. Только fullchain.pem.
  • 80 порт закрыт фаерволом/CDN. HTTP-01 требует, чтобы CA достучался до твоего сервера по 80. За проксирующим CDN или с закрытым 80 - переходи на DNS-01.
  • OCSP stapling устарел. Не тащи вслепую ssl_stapling из старых гайдов: Let's Encrypt убрал OCSP-URL в мае 2025, для LE стэплинг фактически мёртв, это legacy.
Мини-лаба: выпускаем сертификат двумя способами

Повтори руками по шагам.

Часть A - nginx + certbot webroot:
  • Создай каталог: mkdir -p /var/www/acme
  • Добавь в server-блок location ^~ /.well-known/acme-challenge/ с root /var/www/acme (см. выше), выше любых редиректов. Проверь nginx -t и nginx -s reload.
  • Выпусти против staging: certbot certonly --webroot -w /var/www/acme -d твойдомен --test-cert
  • Убедись, что прошло, потом убери --test-cert и выпусти боевой.
  • Пропиши fullchain.pem/privkey.pem в ssl_certificate, reload.
  • Настрой автопродление: certbot renew --dry-run, затем deploy-hook с nginx -s reload.
Часть B - Angie нативно:
  • Поставь Angie, добавь в http-блок resolver и acme_client le с URL директории LE.
  • В server-блоке добавь acme le и ssl_certificate $acme_cert_le; ssl_certificate_key $acme_cert_key_le;
  • angie -t, перезапусти, посмотри в error_log как клиент проходит challenge и выписывает сертификат.
  • Сравни ощущения: в Angie ты не настраивал ни location под challenge, ни cron, ни reload.
Контрольные вопросы
  • Почему wildcard-сертификат *.example.com нельзя получить через HTTP-01 и какой challenge нужен?
  • Зачем в ssl_certificate указывают fullchain.pem, а не cert.pem? Что сломается при ошибке?
  • Чем нативный ACME в Angie (acme_client) принципиально отличается от связки nginx + certbot по эксплуатации?
  • Что такое rate limit "5 дубликатов в неделю" у Let's Encrypt и как не попасть в бан при отладке?
Итог

ACME превратил выпуск TLS в фоновую автоматику. Для ванильного nginx рабочая лошадка - certbot (webroot для контроля, DNS-01 для wildcard) или acme.sh, с обязательным автопродлением и reload-хуком. Нативного ACME в ядре nginx нет - только подключаемые модули nginx-acme (Rust) и njs-acme. А вот Angie в 2026 даёт нативный acme_client прямо в конфиге без certbot и без reload - это его реальная киллер-фича. Главные грабли - rate limits (отлаживай на staging), перехват .well-known редиректом и неполная цепочка. Освоишь это - и красный замок в понедельник утром останется в прошлом.
👍1 ❤️4 🔥 😄 🤔3
Аватара пользователя
lettow
Сообщения: 1
Зарегистрирован: 12 май 2026, 08:49

Re: Let's Encrypt и ACME: certbot, acme.sh, нативный ACME Angie

Сообщение lettow »

Не знал что у Angie acme прямо в конфиге без certbot и без reload, это реально удобно. Только не догнал - для wildcard *.домен он сам DNS-01 не умеет? То есть звёздочку всё равно через acme.sh выписывать?
👍2 ❤️ 🔥 😄 🤔
Аватара пользователя
Ozzyland
Сообщения: 1
Зарегистрирован: 02 июн 2026, 06:31

Re: Let's Encrypt и ACME: certbot, acme.sh, нативный ACME Angie

Сообщение Ozzyland »

А я как раз вчера на проде перевыпустил конфиг раз шесть подряд и поймал бан Let's Encrypt на неделю. Теперь понятно про 5 дубликатов, надо было через --dry-run гонять. Спасибо, дорого далось :)
👍 ❤️2 🔥 😄 🤔
Ответить
← Предыдущая глава
HTTPS и TLS: сертификаты, протоколы, шифры (2026)
Следующая глава →
HTTP/2 и HTTP/3 (QUIC) в 2026

Все главы курса «Nginx профессионально: от первого конфига до API-gateway на OpenResty и Angie»

Поделиться темой: ✈ Telegram VK
Похожие запросы: Angie: форк nginx с нативными метрикамиHTTPS и TLS в nginx: сертификаты и протоколыLet's Encrypt для nginx: бесплатный сертификат

Вернуться в «Nginx профессионально: от первого конфига до API-gateway на OpenResty и Angie»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость