Приветствую, дорогой читатель!

С момента появления в нашем любимом веб-сервере Angie замечательной функции ACME-челленджа через DNS прошло уже достаточно времени, чтобы оценить все преимущества этого решения. Эта поистине революционная фича подарила нам долгожданную возможность получать wildcard-сертификаты буквально в несколько кликов.

Однако, как это часто бывает с новыми технологиями, до сих пор у многих пользователей, особенно только начинающих свое знакомство с Angie, возникают вполне закономерные вопросы вроде: «Как правильно это настроить?» или «Как это вообще работает под капотом?». Именно для таких случаев, дорогие друзья, и была задумана эта подробная статья — максимально простыми и понятными словами описать весь процесс настройки от начала и до конца.

Если забежать немного вперед и посмотреть на общую картину, то весь процесс развертывания с нуля занимает всего четыре простых шага:

  1. Регистрация доменного имени — наш фундамент

  2. Предварительные работы с FQDN — подготовка почвы

  3. Установка и настройка инструмента для управления DNS-зонами — настройка механизмов

  4. Установка, конфигурация и запуск самого Angie — завершающий аккорд

Но для начала небольшой ликбез

Почему без SSL нельзя?

Представьте, что интернет — это огромная почтовая система. Когда вы отправляете письмо (данные), оно проходит через множество рук (маршрутизаторов, провайдеров). Без защиты его может перехватить и прочитать или еще хуже, — подменить, кто угодно.

Что такое SSL?

SSL (Secure Sockets Layer) — криптографический протокол, созданный Netscape в 1990-х для безопасной передачи данных. Позже он эволюционировал в TLS (Transport Layer Security), но название «SSL» осталось в обиходе.

Аналогия:

  • HTTP — это открытка: текст виден всем.

  • HTTPS (HTTP + SSL/TLS) — запечатанный конверт с проверкой подлинности.

Как работает SSL/TLS?

Процесс установки защищённого соединения (SSL Handshake):

  1. Клиент (браузер) стучится на сервер:
    — «Привет! Я поддерживаю TLS 1.3. Давай установим безопасное соединение».

  2. Сервер отвечает:

    • Отправляет SSL-сертификат (как паспорт сайта).

    • Говорит, какие методы шифрования поддерживает.

  3. Браузер проверяет сертификат:

    • Подписан ли он доверенным центром (CA)?

    • Не просрочен ли?

    • Соответствует ли домену сайта?

  4. Создание общего ключа:

    • Клиент и сервер используют асимметричное шифрование (например, RSA) для обмена секретным ключом.

    • Дальше общение идёт через симметричное шифрование (AES) — оно быстрее.

  5. Защищённый канал готов!
    Теперь все данные шифруются перед отправкой и расшифровываются только получателем.

Поскольку я упомянул уже SSL-сертификат и удостоверяющий центр, то необходимо рассказать и об этом немного:

Что такое центр сертификации (CA)?

Центр сертификации (Certificate Authority, CA) — это организация, которая:

  1. Проверяет право владения доменом/компанией.

  2. Выпускает SSL/TLS-сертификаты.

  3. Гарантирует их подлинность через цифровую подпись.

Аналогия:

  • CA — как паспортный стол.

  • SSL-сертификат — ваш цифровой паспорт в интернете.

Иерархия доверия

Доверие к SSL-сертификатам строится на цепочке корневых сертификатов, встроенных в ОС и браузеры.

  • Root CA (например, DigiCert, IdenTrust) — верхний уровень доверия.

  • Intermediate CA — «промежуточные» центры (их используют для выпуска сертификатов, чтобы снизить риски компрометации корневого).

Если браузер видит сертификат, подписанный цепочкой до доверенного Root CA, он считает сайт безопасным.

В России Минцифры (через подведомственные организации) регулирует выпуск SSL-сертификатов для госструктур, коммерческих организаций и физических лиц, требующих соответствия национальным стандартам.

Но для получения сертификата необходима ручная подача заявки. В то время, как у Let’s Encrypt полная поддержка ACME. Поэтому далее речь пойдет исключительно про Let's Encrypt.

ACME — протокол для автоматизации сертификатов

Если мы заглянем на лет 10 назад, мы поймем как было сложно настроить HTTPS на своём сервере: ручная генерация CSR, отправка в удостоверяющий центр, ожидание подтверждения, загрузка сертификата… Но потом появился Let’s Encrypt, а вместе с ним — протокол ACME, который полностью изменил процесс получения TLS-сертификатов.

  • Разработан ISRG (Internet Security Research Group) для проекта Let’s Encrypt.

  • Описан в RFC 8555 (2019).

Проблема, которую решает ACME

Раньше для получения TLS-сертификата нужно было:

  1. Сгенерировать CSR (Certificate Signing Request).

  2. Отправить его в CA.

  3. Доказать, что вы владеете доменом (через email, DNS-запись или HTTP-файл).

  4. Дождаться выпуска сертификата и вручную установить его на сервер.

Это медленно, сложно и не масштабируется. Если у вас 100 доменов, процесс становится кошмаром.

Решение: автоматизировать всё!
→ ACME (Automatic Certificate Management Environment) — протокол, который позволяет получать и обновлять сертификаты без ручного вмешательства.

Как работает ACME?

Основные компоненты

  1. ACME-клиент (например, Angie).

  2. ACME-сервер (например, Let’s Encrypt).

  3. Механизм проверки владения доменом (HTTP- или DNS-based).

    Давайте разберём процесс в виде диалога между клиентом и ACME-сервером:

    1. Клиент стучится в дверь:
      — «Let’s Encrypt, я хочу сертификат для example.com

    2. Сервер отвечает с испытанием:
      — «Хорошо, но сначала докажи, что ты владеешь этим доменом. Вот твой challenge — выполни его!»

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

      •   HTTP-01 : Разместить файл по адресу http://example.com/.well-known/acme-challenge/некий-код.

      •   DNS-01 : Добавить в DNS запись вида _acme-challenge.example.com TXT "секретный-токен".

    3. ACME-сервер проверяет:
      Он отправляется по указанному HTTP-адресу или запрашивает DNS, чтобы убедиться, что challenge выполнен.

    4. Если всё в порядке — сертификат ваш!
      Сервер подписывает и выдаёт TLS-сертификат, который клиент автоматически сохраняет и настраивает для использования.

    ACME построен так, чтобы балансировать между удобством и безопасностью:

    • Контроль домена = право на сертификат
      Никаких писем с подтверждением — только криптографически верифицируемые challenge’ы.

    • Короткий срок жизни (90 дней)
      Да, сертификаты нужно обновлять чаще, но это сводит к минимуму риски: даже если ключ утечёт, он быстро станет бесполезным.

    • Автоматическое обновление
      Вместо ручного регенерирования сертификатов раз в год-два, ACME-клиент делает это «за кулисами», без вашего участия.

    Таким образом, ACME не просто упрощает жизнь администраторам — он делает HTTPS более доступным и безопасным для всего интернета.

Зачем это нужно пользователю?

Это решает сразу несколько критически важных задач:

  1. Безопасность — автоматическое поддержание актуальных SSL-сертификатов помогает постоянно поддерживать безопасное соединение с вашими сервисами

  2. Удобство — больше не нужно помнить о продлении сертификатов или вручную добавлять новые домены третьего уровня

  3. Масштабируемость — система одинаково хорошо работает как для одного, так и для сотен доменов

  4. Экономия времени — то, что раньше требовало регулярного внимания, теперь работает само

Проще говоря, после настройки вы можете забыть о проблемах с SSL — Единожды получив wild-card сертификат, можно смело добавлять сервисы со своими доменами третьего уровня.

Концепция в двух словах

ACME DNS-челлендж — это механизм автоматического получения SSL/TLS сертификатов от центра сертификации через подтверждение прав на домен с помощью DNS-записей. В отличие от традиционного HTTP-челленджа, DNS-метод позволяет:

  • Получать wildcard-сертификаты (*.ваш-домен)

  • Работать без открытого 80 порта

И прежде чем погружаться в дальнейшие технические детали, давайте разберёмся, зачем вообще нужны такие сертификаты и почему они так важны для современного веб-проекта.

Зачем нужны wildcard-сертификаты?

Wildcard-сертификаты (сертификаты с подстановочным знаком, вида *.example.com) — это настоящая палочка-выручалочка для администраторов, и вот почему:

  • Универсальное покрытие
    Один сертификат покрывает SSL хэндшейки со всеми поддоменами вашего проекта:

    • app.example.com

    • blog.example.com

    • api.example.com

    • mail.example.com

    • И любые другие, которые вы добавите в будущем

  • Экономия времени и ресурсов
    Вместо управления десятками отдельных сертификатов вы получаете:

    • Единую точку контроля

    • Одновременное обновление всех поддоменов

    • Минимум рутинных операций

  • Гибкость разработки
    Позволяют:

    • Быстро разворачивать тестовые среды (dev.example.com, stage.example.com)

    • Создавать индивидуальные поддомены для клиентов (client1.example.com)

    • Организовывать микросервисную архитектуру

Функциональная схема
Функциональная схема

1. Кое-что об FQDN: выбираем и регистрируем домен правильно

Хоть процесс регистрации домена и кажется на первый взгляд элементарным, думаю, стоит уделить ему немного внимания.

Искусство выбора идеального доменного имени

Выбор имени — это целая наука, и вот несколько профессиональных советов:

  1. Краткость и звучность — идеальное имя должно быть как хороший логотип: запоминающимся и легко произносимым. Например, "bestshop.com" лучше, чем "thebestonlineshop2023.com".

  2. Минимум символов — избегайте дефисов, цифр и сложных сочетаний букв. Имя "super-service.com" хуже, чем "superservice.com".

  3. Проверка доступности — используйте whois-сервисы или встроенные проверки у регистраторов. Помните, что хорошие имена разбирают быстро.

  4. Реальность ожиданий — будьте готовы к компромиссам. Идеальные имена обычно заняты, поэтому заранее продумайте несколько вариантов.

Где лучше регистрировать домен?

Современный рынок предлагает множество вариантов:

  • Международные гиганты — хороши для глобальных проектов

  • Локальные провайдеры — удобны для местного бизнеса и поддержки

  • Специализированные регистраторы — предлагают дополнительные услуги

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

✓ Прозрачность ценообразования
✓ Удобство панели управления
✓ Наличие дополнительных услуг (DNS-хостинг, WHOIS-приватность)
✓ Качество поддержки

После регистрации можно переходить к следующему важному шагу — настройке DNS.

2. Предварительные работы с FQDN

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

В рамках данной статьи я буду использовать Cloudflare в качестве примера — их DNS-хостинг не только абсолютно бесплатен, но и предоставляет массу дополнительных возможностей, что делает его идеальным вариантом для демонстрации работы всей цепочки.

Почему именно Cloudflare?

Выбор Cloudflare в качестве DNS-хостинга обусловлен несколькими вескими причинами:

  1. Бесплатность — базовый функционал доступен без каких-либо платежей

  2. Простота — интуитивно понятный интерфейс управления

  3. API — возможность автоматизации процессов, что критично для нашей задачи

Конечно, если вы регистрировали домен именно на Cloudflare, то этот раздел можно пропустить, так как Cloudflare сам автоматически настроит все что нужно. Но для тех счастливчиков (и я в их числе), кто, подобно мне, предпочел разделить регистратора домена и DNS-хостинг (возможно, из соображений гибкости управления или по историческим причинам), нам предстоит увлекательное путешествие по настройке этой связки. Не переживайте — это не так сложно, как может показаться на первый взгляд, и я проведу вас через все этапы шаг за шагом. Понесемся дальше:

Регистрация в Cloudflare

  1. Создаем аккаунт

    Переходим на cloudflare.com и регистрируемся. Процесс стандартный — email, пароль, подтверждение.

  2. Добавляем сайт

    В панели управления нажимаем «+Add → Connect a domain» и вводим наш зарегистрированный домен (например, example.com ). Выбираем «Manually enter DNS records», жмем «Continue» и выбираем Free plan. Завершаем добавление домена, согласившись с добавлением DNS записей позже вручную.

Делегирование домена Cloudflare

  1. Меняем NS-сервера
    После добавления домена в Cloudflare сервис встанет в ожидании активации, а именно — в ожидании делегирования домена на сервера Cloudflare (обычно это [имя].ns.cloudflare.com). Их нужно прописать у вашего регистратора.

  2. Настройка у регистратора
    Заходим в панель управления доменом у вашего регистратора:

  • Ищем раздел "DNS Management" или "Name Servers (Серверы имен)"

  • Меняем стандартные NS-сервера на полученные от Cloudflare

  • Сохраняем изменения

Проверить статус можно командой:

whois example.com | grep "nserver"

Важно! Распространение изменений может занять до 24 часов (хотя обычно происходит быстрее).

Проверка корректности:

dig NS example.com +short

Должны вернуться ваши Cloudflare NS-сервера.

Настройка DNS-записей в Cloudflare

Теперь, когда домен делегирован на серверы Cloudflare, нам потребуется API-ключ для автоматического управления DNS-записями.

Процесс создания API-ключа:

  1. Переходим в настройки профиля
    В правом верхнем углу панели Cloudflare кликаем по иконке профиля → My Profile.

  2. Открываем раздел API-токенов
    В боковом меню выбираем API Tokens → Create Token.

  3. Выбираем шаблон настроек
    Ищем в списке шаблон Edit zone DNS и нажимаем Use template.

  4. Добавляем к токену разрешение Page Rules:Edit

  5. Настраиваем разрешения:

  • Zone Resources: выбираем Include → Specific zone → указываем наш домен

  • Permissions: оставляем Zone.DNS → Edit

Создаем и копируем токен

Нажимаем Continue to summary → Create Token.

Внимание! Токен отобразится только один раз — сразу скопируйте его в надежное место!

Проверка работоспособности ключа:

curl -X GET "https://api.cloudflare.com/client/v4/zones" \ -H "Authorization: Bearer ВАШ_API_КЛЮЧ" \ -H "Content-Type: application/json"

В ответе должны увидеть список ваших зон, включая добавленный домен.

Добавление/редактирование DNS-записей

  1. Откройте вкладку DNS → Records.

  2. Для добавления записи нажмите + Add record.

  • A-запись (IPv4):

    • Nameexample.com (или поддомен, например ns1).

    • IPv4 address: Укажите IP сервера.

  • NS для ACME  DNS-01 challenge

    • Name: Поддомен (например, _acme-challenge).

    • Nameserver: Адрес NS-сервера (например, ns1.example.com).

    • TTL: Auto или кастомное значение.

      Чтобы активировать зону, просто единожды нажмите кнопку "Активировать" в WEB-интерфейсе или с помощью запроса через API (хэш зоны можно увидеть все там же в интерфейсе или из вывода API):

      curl -X GET "https://api.cloudflare.com/client/v4/zones/НОМЕР_ЗОНЫ/pagerules?status=active" \ -H "Authorization: Bearer ВАШ_API_КЛЮЧ" \ -H "Content-Type: application/json"

Сохранение и проверка

  1. Нажмите Save.

  2. Проверьте запись через команду:

    dig example.com +short

3. Установка и настройка OctoDNS для управления DNS-зонами

Для автоматизации управления DNS-записями мы будем использовать OctoDNS — настоящий «комбайн» для управления DNS-записями с открытым исходным кодом, который изначально создавался для нужд GitHub и теперь поддерживается сообществом. Этот инструмент позволяет декларативно описывать DNS-зоны в YAML-файлах и синхронизировать их с различными DNS-провайдерами.

Установка и подготовка окружения

Создаем рабочую директорию и виртуальное окружение Python:

sudo mkdir /dns

cd /dns

python -m venv env

source env/bin/activate

Устанавливаем необходимые пакеты:

pip install octodns octodns_cloudflare

Создаем директорию для конфигурации:

sudo mkdir /dns-conf

Настройка конфигурации OctoDNS

Создаем основной конфигурационный файл example.com.prod.yaml:

sudo vi /dns-conf/example.com.prod.yaml

Содержимое файла:

providers:
  config:
    class: octodns.provider.yaml.YamlProvider
    directory: /dns-conf
    default_ttl: 3600
    enforce_order: True
  cloudflare:
    class: octodns_cloudflare.CloudflareProvider
    token: ВАШ_API_КЛЮЧ
    account_id: ВАШ_ID_АККАУНТА
zones:
  example.com.:
    sources:
      - config
    targets:
      - cloudflare

Где:

  • ВАШ_API_КЛЮЧ - токен Cloudflare, который мы создали ранее

  • ВАШ_ID_АККАУНТА - можно найти в панели Cloudflare в разделе "Overview"

    Создаем файл с DNS-записями для нашего домена:

sudo vi /dns-conf/example.com.yaml

Пример содержимого:

Примечание: В YAML должны содержаться все записи которые присутствуют у провайдера. В противном случае, при синхронизации записи будут удалены. Так же, YAML должен быть заполнен в алфавитном порядке.

'':
  - ttl: 86400
    type: A
    values:
      - IP_АДРЕС_ВАШЕГО_СЕРВЕРА
  - ttl: 86400
    type: MX
    values:
      - exchange: mail.example.com.
        preference: 10
'_acme-challenge':
  ttl: 86400
  type: NS
  values:
    - ns.example.com.
'mail':
  ttl: 86400
  type: A
  values:
    - IP_АДРЕС_ВАШЕГО_СЕРВЕРА
'ns':
  ttl: 86400
  type: A
  values:
    - IP_АДРЕС_ВАШЕГО_СЕРВЕРА
'www':
  ttl: 86400
  type: A
  values:
    - IP_АДРЕС_ВАШЕГО_СЕРВЕРА

Запуск синхронизации DNS-записей

Сначала выполняем пробный запуск (без внесения изменений):

octodns-sync --config-file=./config/example.com.prod.yaml

Если в выводе все выглядит корректно, выполняем реальную синхронизацию:

octodns-sync --config-file=./config/example.com.prod.yaml --doit

Профессиональный совет: Интегрируйте OctoDNS в ваш CI/CD-пайплайн для автоматического развертывания изменений DNS. Это как система автопилота для ваших DNS-записей.

OctoDNS особенно полезен, когда:

  • У вас множество доменов и поддоменов

  • Требуется согласованность между разными провайдерами

  • Важна история изменений в DNS

  • Необходима автоматизация рутинных операций

Теперь у нас есть система управления DNS-записями, а мы готовы перейти к настройке самого Angie для работы с wildcard-сертификатами.

4. Установка, конфигурация и запуск Angie

Теперь, когда у нас готова вся необходимая инфраструктура, перейдём к финальному аккорду — настройке Angie для автоматического получения wildcard-сертификатов через DNS-челлендж.

Устанавливать мы будем на Debian. Для других OS обратитесь к официальной документации.

  1. Установите вспомогательные пакеты для подключения репозитория Angie:

    sudo apt-get update

    sudo apt-get install -y ca-certificates curl

  2. Скачайте открытый ключ репозитория Angie для проверки подлинности пакетов:

    sudo curl -o /etc/apt/trusted.gpg.d/angie-signing.gpg \ https://angie.software/keys/angie-signing.gpg

  3. Подключите репозиторий Angie:

    echo "deb https://download.angie.software/angie/$(. /etc/os-release && echo "$ID/$VERSION_ID $VERSION_CODENAME") main" \ | sudo tee /etc/apt/sources.list.d/angie.list > /dev/null

  4. Обновите индексы репозиториев:

    sudo apt-get update

  5. Установите пакет Angie:

    sudo apt-get install -y angie

Если вы мигрируете с nginx, вы можете найти статью Миграция с nginx на Angie на официальном сайте.

4.1 Настройка Angie для автоматического получения wildcard-сертификатов (Подход с NS записью указывающей на наш сервер)

После успешной установки Angie, настройка получения wildcard-сертификатов через DNS-челлендж требует минимальной конфигурации.

Базовая конфигурация

Приведите вашу конфигурацию (/etc/angie/angie.conf) к следующему виду:

user  angie;
worker_processes  auto;
worker_rlimit_nofile 65536;

error_log  /var/log/angie/error.log info;
pid        /run/angie.pid;

events {
    worker_connections  65536;
}

http {
    # Конфигурация ACME-клиента
    acme_client example_com https://acme-v02.api.letsencrypt.org/directory
        challenge=dns;

    server {
        server_name *.example.com;
        acme example_com;

        ssl_certificate $acme_cert_example_com;
        ssl_certificate_key $acme_cert_key_example_com;

        location / {
            default_type text/plain;
            return 200 "Thank you for requesting $host\n";
        }
    }
}

После успешного выполнения ACME-челленджа:

  • Сертификат будет доступен по пути: /var/lib/angie/acme/example/certificate.pem

  • Приватный ключ: /var/lib/angie/acme/example/private.key

Сертификат автоматически подставляется в переменную $acme_cert_example_com а ключ в $acme_cert_key_example_com соответственно, чтобы исключить дисковые операции. Angie автоматически обновляет сертификаты перед истечением срока их действия.

Для понимания схемы взаимодействия компонентов:

  • Мы настроили NS запись у DNS хостера, указывающую на наш сервер с Angie

  • На Angie открыт порт 53 (по умолчанию), отвечающий на DNS запрос записью TXT.

  • Angie делает запрос к Let's Encrypt и получает токен.

  • Let's Encrypt проверяет запись _acme-challenge.example.com и напрямую попадает на Angie, который отдает нужную запись TXT

  • Далее эта запись автоматически удаляется и Angie получает готовый сертификат.

Мы рассмотрели вариант с NS записью которая указывает напрямую на IP Angie. Хотя, этот вариант является самым простым и быстрым для получения сертификата, но что делать если нет возможности отвечать напрямую?

Минусы NS-делегирования на Angie

  • Необходим статический публичный IP.

  • Проблемы с NAT и динамическими IP.

  • Некоторые регистраторы запрещают NS записи на поддомены.

4.2 Альтернатива: Прямое добавление TXT-записи через API

Установка дополнительных пакетов

Для данного варианта, нам потребуется установить дополнительно пакет yq для работы с YAML файлами а так же пакет динамического модуля angie-module-cgi (Если вам нужны дополнительные модули, вы можете посмотреть полный список дополнений):

sudo apt-get install -y angie-module-cgi yq

Для понимания схемы взаимодействия компонентов:

  • Мы настроили Angie для работы с hook.

  • За выкатку записи TXT на DNS хостинг отвечает bash скрипт.

  • Angie делает запрос к Let's Encrypt и получает токен.

  • Angie с помошью acme_hook и скрипта изменяет YAML файл с добавлением токена в TXT запись.

  • Скрипт выкатывает изменения на DNS хостинг и дожидается обновления DNS записи _acme-challenge.example.com.

  • Let's Encrypt проверяет запись _acme-challenge.example.com и выдает сертификат.

  • Далее Angie снова делает сабреквест к скрипту и удаляет токен из TXT записи.

  • Angie записывает готовые сертификат и ключ в переменные и на диск (/var/lib/angie/acme/example/).

Итак, приступим к настройке:

Даем Angie права записи в новые файлы

sudo chown -R angie:angie /dns-conf

Помещаем скрипт в /usr/share/angie/cgi-bin/cert-deploy и делаем его исполняемым sudo chmod +x /usr/share/angie/cgi-bin/cert-deploy

#!/bin/bash
echo "Content-Type: text/plain" # Добавить заголовок в ответе
echo "" # Разделитель заголовков и тела ответа

# Из переменной переданной из ACME выдергиваем все кроме доменов первого и второго уровней
SUBDOM=$(echo "${DOMAIN}" | awk -F '.' 'BEGIN{OFS="."} {NF-=2; print}')
# Из переменной переданной из ACME выдергиваем только домены первого и второго уровней
ZONE=$(echo "${DOMAIN}" | awk -F '.' '{print $(NF-1) "." $NF}')
# Для поддоменов необходимо проставить точку в _acme-challenge
if [[ -n $SUBDOM ]]; then
  SUBDOM=".$SUBDOM"
fi

# Активируем виртуальную среду для запуска OctoDNS
python -m venv /dns/env
source /dns/env/bin/activate

# Файлы конфигурации
CONFIG_FILE="/dns-conf/$ZONE.prod.yaml"
RECORDS_FILE="/dns-conf/$ZONE.yaml"

if [[ $HOOKNAME = 'add' ]]; then
       # При добавлении записи TXT вставляем токен от Let's Encrypt в нужную запись _acme-challenge
     yq -yi ". \"_acme-challenge${SUBDOM}\" = [{\"ttl\": 64, \"type\": \"TXT\", \"value\": \"${KEYAUTH}\"}]" "$RECORDS_FILE"
       # Запускаем процесс синхронизации конфигурации с DNS хостером 
     octodns-sync --config-file="$CONFIG_FILE" --doit
       # Ждем обновления записи DNS (не более 1200 сек) и продолжаем
     loop=0
     while [ $loop -lt 1200 ]; do
          # Проверяем соответствует ли TXT запись DNS токену от Let's Encrypt; 8.8.8.8 указан чтобы исключить вздействие кеширующего DNS
        curchtxt=$(host -t txt _acme-challenge."${DOMAIN}" 8.8.8.8 | awk 'END {print $NF}' | tr -d '"')
          # Если соответствует, то выход из цикла с успехом.
        if [[ $curchtxt = $KEYAUTH ]]; then
           exit 0
        fi
        sleep 1
        loop=$((loop+1))
     done
  else
       # Очищаем ранее проставленный токен
     yq -yi ". \"_acme-challenge${SUBDOM}\" = [{\"ttl\": 64, \"type\": \"TXT\", \"value\": \" \"}]" "$RECORDS_FILE"
       # Запускаем процесс синхронизации конфигурации с DNS хостером 
     octodns-sync --config-file="$CONFIG_FILE" --doit
fi

YAML файл конфигурации исправляем в соответствии с TXT записью (/dns-conf/example.com.yaml)

'':
  - ttl: 86400
    type: A
    values:
      - IP_АДРЕС_ВАШЕГО_СЕРВЕРА
  - ttl: 86400
    type: MX
    values:
      - exchange: mail.example.com.
        preference: 10
'_acme-challenge':
  ttl: 64
  type: TXT
  value: 'NEW'
'mail':
  ttl: 86400
  type: A
  values:
    - IP_АДРЕС_ВАШЕГО_СЕРВЕРА
'ns':
  ttl: 86400
  type: A
  values:
    - IP_АДРЕС_ВАШЕГО_СЕРВЕРА
'www':
  ttl: 86400
  type: A
  values:
    - IP_АДРЕС_ВАШЕГО_СЕРВЕРА

Приводим конфигурацию (/etc/angie/angie.conf) к следующему виду:

user  angie;
worker_processes  auto;
worker_rlimit_nofile 65536;

error_log  /var/log/angie/error.log info;
pid        /run/angie.pid;

load_module modules/ngx_http_cgi_module.so;

events {
    worker_connections  65536;
}

http {

    # Конфигурация ACME-клиента
    acme_client example_com https://acme-v02.api.letsencrypt.org/directory
        challenge=dns;

    server {
        server_name *.example.com;
        acme example_com;

        ssl_certificate $acme_cert_example_com;
        ssl_certificate_key $acme_cert_key_example_com;

        location / {
            default_type text/plain;
            return 200 "Thank you for requesting $host\n";
        }

    	location @acme_hook_location {
    		acme_hook example_com;
              cgi_set_var DOMAIN $acme_hook_domain;
              cgi_set_var KEYAUTH $acme_hook_keyauth;
              cgi_set_var HOOKNAME $acme_hook_name;
            cgi_pass /usr/share/angie/cgi-bin/cert-deploy;
    	}
    }
}

Ваша система готова к полностью автоматизированному получению и обновлению TLS-сертификатов через Let's Encrypt с использованием:

  • Angie как ACME-клиента с  DNS-01 challenge

  • CGI-хука для динамического управления TXT-записями

  • OctoDNS для синхронизации изменений с DNS-хостингом

  • Локального CGI-сервера для безопасного взаимодействия компонентов

Что было достигнуто:

  1. Автоматизация

    • Сертификаты обновляются без ручного вмешательства (раз в 90 дней).

    • Хук самостоятельно добавляет/удаляет TXT-записи через OctoDNS.

  2. Безопасность

    • CGI-скрипт работает в изолированном окружении.

    • Доступ к хуку ограничен внутренним вызовом (именованный локейшен нельзя вызвать внешним запросом).

  3. Надежность

    • Скрипт проверяет распространение DNS-записи перед валидацией.

    • YAML-конфиги версионируются (если используется CI/CD).

  4. Гибкость

    • Решение адаптируется под любые DNS-провайдеры, поддерживаемые OctoDNS.

    • Легко масштабируется на дополнительные домены.

Проверка работоспособности:

Убедиться, что сертификаты получены: ls -la /var/lib/angie/acme/example/

Убедиться что получен верный сертификат: openssl x509 -in /var/lib/angie/acme/example/certificate.pem -noout -text

Посмотреть в логе /var/log/angie/error.log сообщение вида certificate renewed, next renewal date: Sun Jul 90 00:00:00 2025, ACME client: example

В виде заключения или почему это лучше ручного управления?

Как это работает технически?

Ключевые преимущества Angie

  1. Единая точка управления — вся конфигурация в одном файле

  2. Zero Downtime — обновление сертификатов без перезагрузки сервера

  3. Автоматизация — при использовании схемы с NS записью на поддомены не требует дополнительных скриптов

  4. Ресурсоэффективность — нет накладных расходов на внешние процессы

Чем это лучше/удобнее Certbot?

  • Список доменов формируется непосредственно из директив server_name, таким образом автоматически отслеживаются изменения в конфигурации и выпускаются сертификаты для новых доменов.

  • Обновление сертификатов происходит без перезагрузки конфигурации.

Я всё же привык использовать Certbot, будет ли он работать с Angie?

  • Да, будет. Вы можете использовать Certbot с Angie во всех режимах, включая автоматическую настройку опцией --nginx:

    ln -s /etc/angie/angie.conf /etc/angie/nginx.conf

    certbot --nginx-server-root=/etc/angie --nginx-ctl=angie

Главное - надежность — никаких просроченных сертификатов

  • Проблема: Ручное обновление требует внимания администратора. Даже крупные компании ошибаются:

    • 2010 год, Ростелеком: Просроченный сертификат на gosuslugi.ru привёл к проблемам для миллионов пользователей.

    • 2020 год, GitHub: Устаревший сертификат вызвал простой, нарушив работу у тысяч разработчиков.

  • Решение: Автоматическое обновление (каждые 60–90 дней) исключает человеческий фактор.

Комментарии (15)


  1. xSVPx
    26.05.2025 13:51

    Текст длинноват, чтобы переделывать что-то с уже работающего certbot...

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


  1. 13werwolf13
    26.05.2025 13:51

    люди забыли принцип "утилита должна выполнять только одну задачу, но делать это хорошо"
    алсо, на мой взгляд в статье не хватает ответа на вопрос: а в чём преимущество? способов автоматически получать/обновлять сертификаты нынче много, от банального bash скрипта на пару строчек и всем известного certbot до вот таких вот решений встроенных в приложение для которого сертификат нужен, и говоря о своём решении стоит сказать чем оно лучше.


    1. VBart
      26.05.2025 13:51

      В конце статьи есть ответ на вопрос чем лучше. Самое банальное - не нужно поддерживать список доменов в двух разных местах. Из небанального, что никогда в принципе не сможет скрипт на bash делать, так это выполнять ALPN-челендж, поддержку которого уже в ближайших версиях добавим.

      люди забыли принцип "утилита должна выполнять только одну задачу, но делать это хорошо"

      Сколько я работаю в индустрии, то постоянно сталкиваюсь, что реальные пользователи чаще всего хотят обратного, а именно, чтобы всё работало из коробки и желательно тратить на это как можно меньше сил. И в целом, в этом нет ничего плохого... есть в индустрии другие задачи, чем как сопряжение отдельных разрозненных компонентов между собой каждый раз.

      Так для чего повторять когда-то десятилетия назад выдвинутую догму, когда задачи и масштабы были совсем другие, снова и снова? Тем более, что тут возникает коллизия в том, а что есть утилита в части веб-сервера... должен ли он хорошо обрабатывать HTTPS трафик? Современному веб-серверу без этого никуда, а если да, то входит ли в эту задачу работа с сертификатами? Ведь если он не сможет обновлять сертификаты, то хорошо обрабатывать HTTPS трафик тоже не получится. Какая-то неполноценная утилита тогда выходит, не справляющаяся со свой задачей.


      1. 13werwolf13
        26.05.2025 13:51

        не сочтите за троллинг, но:

        поддержку которого уже в ближайших версиях добавим

        рановато заявлять о плюсе который ещё не в проде..

        реальные пользователи чаще всего хотят обратного

        1. ну nginx/angie это всё же не для пользователей а для тех кто делает этим пользователям сервисы.

        2. пользователям свойственно ошибаться, если вы утверждаете что так лучше для пользователя то снова вопрос: "чем?".

        чтобы всё работало из коробки и желательно тратить на это как можно меньше сил

        1. не вижу почему бы из коробки у меня бы не заработал lego/certbot/acme.sh/etc.

        2. меньше сил это когда ты добавляешь в свой ansible/puppet/etc проект ещё один хост с его варсами и запускаешь сто раз проверенный плейбук и уже и не помнишь какой там под капотом юзается acme.. а когда нужно копать новый инструмент это уже исследование, да оно может быть полезным и профитным, но чтобы это выяснить для начала надо чтобы появился на то интерес и причина.

        Так для чего повторять когда-то десятилетия назад выдвинутую догму

        потому что она провереная временем, эта догма строится на базе того что человек не всесилен и ему свойственно допускать ошибки, и на том как уменьшить возможное кол-во ошибок не более.

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

        ну не надо смешивать две задачи в одну всё же использовать сертификат и обслуживать его это независимые задачи. вообще если уж на то пошло хорошим тоном является выдавать на сертификаты такие права чтобы приложение могло их только читать, но не писать, а с вашим решением так не получится..


        1. VBart
          26.05.2025 13:51

          рановато заявлять о плюсе который ещё не в проде..

          Тут я скорее о том, что в принципе технически нормально не реализовать в случае отдельной утилиты, т.к. требует вмешательства в сам процесс TLS-хендшейка.

          ну nginx/angie это всё же не для пользователей а для тех кто делает этим пользователям сервисы.

          Мы пользователями привыкли называть тех, кто пользуется нашим ПО, т.е. устанавливает и занимается его настройкой. =)

          пользователям свойственно ошибаться, если вы утверждаете что так лучше для пользователя то снова вопрос: "чем?"

          Они по этой причине уходят на кадди, и не ощущают, что ошиблись. Опять же, кому не нужно и кто считает это ошибкой - может просто не пользоваться данным модулем и вообще его не собирать. Тем не менее, отставание от конкурентов в этом плане приводит только к потере пользователей. Кажется, это весомый аргумент, чтобы не отставать, если хочешь разрабатывать действительно популярное решение, а не что-то сугубо нишевое.

          не вижу почему бы из коробки у меня бы не заработал lego/certbot/acme.sh/etc.
          меньше сил это когда ты добавляешь в свой ansible/puppet/etc проект ещё один хост с его варсами и запускаешь сто раз проверенный плейбук

          Значит у вас уже есть какой-то плейбук, вы в этом однажды разобрались и его написали. Это не из коробки. Это не поставил apt install angie, а дальше добавил две директивы и всё работает, причем добавил в парадигме конфигурационного файла, который и так нужно изучать, чтобы пользоваться nginx/Angie.

          потому что она провереная временем, эта догма строится на базе того что человек не всесилен и ему свойственно допускать ошибки, и на том как уменьшить возможное кол-во ошибок не более.

          Да, и ошибки он допускает при настройке двух разных инструментов. Тратит время на изучение дополнительного инструмента, написание плейбука и пр. пр. Зачем этим заниматься, если можно воспользоваться встроенным решением, которое уже раз разработали те, кто разобрались в вопросе глубже, чем просто настройка Certbot и реализовали это автоматически.

          Тут нужно понимать, что в статье рассмотрен довольно комплексный и сложный случай настройки. В простейшем виде вся настройка заключается в добавлении пары директив в конфиг из документации:

              acme_client example https://acme-v02.api.letsencrypt.org/directory;
          
              server {
                  acme example;
          
                  ...


          При этом обновление сертификатов происходит без перезагрузки процессов веб-сервера. Для тех, у кого доменов и сертификатов очень много, необходимость чаще перезапускать процессы - становится отдельной проблемой.

          Вот вы спорите, а мы регулярно получаем благодарность от пользователей, которые пишут, что поддержка ACME в Angie - это стало для них одним из ключевых факторов, чтобы перейти с nginx и они очень довольны, благодарят за эту функциональность чаще, чем за многую другую.

          Это же не вот вдруг нам заняться было нечем. Это был нескончаемый поток просьб встроить поддержку ACME в веб-сервер, т.к. по той или иной причине пользователи не хотят возиться с отдельным Certbot/Acme.sh и др., предпочитая вместо этого даже сменить веб-сервер на такой, где поддержка ACME уже встроена. Можно конечно сидеть и заявлять, что такие пользователи ошибаются, не должен этим заниматься веб-сервер, но это странный способ кому-то что-то доказать, весьма не конструктивный в плане развития и популяризации проекта.


          1. 13werwolf13
            26.05.2025 13:51

            Вот вы спорите

            в спорах рождается истина)
            из нашего небольшого диалога я подчерпнул толику полезной инфы и тоже возможно перейду на angie если появится на это минутка.


      1. PaNick
        26.05.2025 13:51

        Выглядит так, как будто это должен быть доклад с презентацией. А теническая часть отдельно. За большим количеством контента сложно поймать основную тему. Но то, что вы сделали наконец авто сертификаты, это круто. Я в свое время из-за этого на Caddy перетащил мелкие проекты, чтобы скрипты не плодить.


        1. VBart
          26.05.2025 13:51

          Так чем простейший пример в документации плох: https://angie.software/angie/docs/configuration/acme/#http - зачем ждать, пока где-то в каком-то блоге появится какая-то заметка, цитирующая документацию? =)


    1. xenon
      26.05.2025 13:51

      У меня вот есть такая задача (которая как-то с трудом вкорячивается в концепцию unix-way с одной функцией на утилиту): Представим сервис для хранения статических файлов (типа хабрастораджа). Клиенты регаются, настраивают DNS запись и клиент cocacola.com получает (на нашем сервере) виртуальный хост static.cocacola.com. Потом регается intel и у нас сразу же (на том же сервере, с тем же IP) появляется static.intel.com.

      Традиционный путь - это держать где-то список доменов, и иногда перестраивать конфиги вебсервера из списк и запрашивать сертификаты. Но мне кажеся, это каким-то сложным, кривым путем. Вроде бы Caddy умеет так делать. Про Angie не знаю, я вот о нем только услышал.

      Еще, почему-то веб-сервера не умеют сами подбирать сертификаты. Мне кажется немного тупостью, что нужно для каждого виртхоста прописывать, где ему искать файлы с сертификатом и ключам - лишние хлопоты, громоздкий конфиг, лишние ошибки. Какой-то анахронизм, рудимент с тех времен, когда сертификат покупался за $100/год и это было редкостью. Гораздо проще было бы просто один раз в конфиге указать пути, где у нас лежат сертификаты, и веб-сервер по запросу к example.com сам сможет найти свежий сертификат для example.com.


      1. blind_oracle
        26.05.2025 13:51

        Традиционный путь - это держать где-то список доменов, и иногда перестраивать конфиги вебсервера из списк и запрашивать сертификаты. Но мне кажеся, это каким-то сложным, кривым путем. Вроде бы Caddy умеет так делать. Про Angie не знаю, я вот о нем только услышал.

        Не очень понял. Вы хотите чтобы, условно, папка с сертификатами была динамическим конфигом для сервера? Так себе идея, ибо кроме сертификатов там много ещё чего.

        Так что список доменов всё равно надо где-то держать. Меня бы устроило если бы nginx просто умел динамически перечитывать сертификаты по команде.

        Но он только умеет тушить старые процессы и запускать новые. Что приводит иногда к OOM если часто это делать т.к. старые ещё не закрылись (держим их 10 минут например чтобы клиенты успели всё доделать), а новых наоткрывали кучу уже.


      1. VBart
        26.05.2025 13:51

        Традиционный путь - это держать где-то список доменов, и иногда перестраивать конфиги вебсервера из списк и запрашивать сертификаты. Но мне кажеся, это каким-то сложным, кривым путем. Вроде бы Caddy умеет так делать. Про Angie не знаю, я вот о нем только услышал.

        Вам в любом случае придется хранить список доменов и проверять по нему, прежде чем выпустить сертификат. Попробую объяснить почему.

        Представим, что такого списка нигде нет. В SNI, как и в заголовке Host, клиент может указать вообще всё, что угодно, абсолютно любой домен. Таким образом злоумышленник сможет вывести ваш сервер из строя, начав запрашивать произвольные домены. Попытка выпустить сертификат на такой произвольный домен не увенчается успехом, однако вы попадете в черный список у ACME-сервера и не сможете получить сертификат для реального нужного домена.

        Ок, вы скажите, что ACME клиент должен перед тем, как идти получать сертификат на новый домен - сам попытаться его отрезолвить. А я отвечу, что ничего не мешает злоумышленнику зарегистрировать какой-то домен и прописать для него IP-адрес вашего сервера. И ваш сервер даже получит на него сертификат, но при определенном количестве таких запросов у того же Let's Encrypt сработает лимит и получение новых сертификатов на какое-то время будет далее невозможно, что опять приведет к DoS.

        Т.е. так или иначе, перед тем, как идти получать сертификат на какой-то домен с которым пришел клиент - неплохо бы проверить его по списку.

        Те, кто использует Caddy таким образом в проде, сильно рискуют, если они не поставили перед ним ещё какой-то прокси, который умеет фильтровать TLS-подключения по SNI и таким образом фильтруют их по списку, либо используют механизм проверки домена внешним запросом к хранилищу, который предоставляет Caddy. Т.е. так или иначе, список доменов где-то есть и по нему происходит сверка.

        Потенциально такой режим можно добавить и в Angie с соответствующими предупреждениями и инструкциями, как это безопасно настроить. Но какая-то проверка по списку доменов все равно будет, просто этот список будет храниться вне конфигурации сервера.

        Еще, почему-то веб-сервера не умеют сами подбирать сертификаты. Мне кажется немного тупостью, что нужно для каждого виртхоста прописывать, где ему искать файлы с сертификатом и ключам - лишние хлопоты, громоздкий конфиг, лишние ошибки.

        Абсолютно с вами согласен. Поэтому в свое время в NGINX Unit я реализовал это иначе. Там сертификат и ключ автоматически выбирается по SNI исходя из тех доменов, что прописаны в сертификате.

        nginx и многие сервера появились задолго до того, как появился SNI, отсюда и такая настройка. Можно подумать над тем, как это переделать в Angie, чтобы было проще и удобнее чем механизм, унаследованный от nginx, но это уже отдельная задача.


  1. StraNNicK
    26.05.2025 13:51

    99% статьи — про то, что такое ssl, wildcard-сертификаты и как их получить.
    ещё и написано чатботом. : (

    зашёл узнать, насколько удобнее angie, чем связка nginx+dehydrated именно для получения сертификатов с http-авторизацией (т.е., условно говоря, я добавляю новый server {}, а сертификаты для него получаю автоматически).
    вместо этого вода-вода-вода CF, OctoDNS, что угодно — только не Angie.

    Ну, хоть про OctoDNS узнал, тоже плюс.

    P.S. используйте в системном промпте что-нибудь вроде "не нужно слишком подробно, рассказывай для администраторов линукс среднего уровня", а то получилось молоко с водкой — вроде и тема IaC поднимается, которая начинающим скорее вредна, а вроде и разжёвано на уровне apt install… (чего тогда не "чтобы включить компьютер, воткните вилку в розетку"?)


    1. VBart
      26.05.2025 13:51

      зашёл узнать, насколько удобнее angie, чем связка nginx+dehydrated именно для получения сертификатов с http-авторизацией (т.е., условно говоря, я добавляю новый server {}, а сертификаты для него получаю автоматически).

      А чем в таком случае не устроила официальная документация?


      1. StraNNicK
        26.05.2025 13:51

        потому что документация описывает как настроить, так?
        а мне был интересен опыт практической эксплуатации. В духе "у нас был certbot, мы поставили angie, стало удобнее, потому что…"

        статьи на хабре тем и ценны. Иначе зачем они, есть же документация?


        1. VBart
          26.05.2025 13:51

          Такие сообщения регулярно в телеграм чате поддержки и комментариях в разных местах. Там просто не о чем писать: "поставили Angie, добавили пару директив, все работает автоматически, спасибо большое" - в таком духе. Пример: https://t.me/angie_support/7987 Если вдруг не работает, то обращаются за помощью и помогаем разобраться почему не работает.

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

          А тут коллега детально описал самый комплексный случай настройки, который только можно придумать, разобрался с OctoDNS и другими инструментами, которыми может кто-то захотеть воспользоваться, всё протестировал, написал скрипт и AFAIK никаких промптов. Людям теперь везде ИИ мерещатся. =)