Выберите продукт

ACME EAB: External Account Binding в Certbot и lego

External Account Binding (EAB) — обязательный для ряда CA шаг привязки ACME‑аккаунта к вашему профилю. В статье — что такое ACME EAB, как получить KID/HMAC, как корректно включить EAB в Certbot и lego, как хранить секреты, отладка типичных ошибок и безопасная автоматизация продления SSL.
ACME EAB: External Account Binding в Certbot и lego

Если вы автоматизируете выпуск SSL через ACME, рано или поздно столкнётесь с требованием EAB (External Account Binding). Некоторые центры сертификации (CA) выдают креденшалы EAB для привязки нового ACME-аккаунта к вашему профилю в их системе. Без этой привязки запрос newAccount будет отклонён, и ваш привычный сценарий автоматизации развалится на самом первом шаге.

Разберёмся, как EAB устроен концептуально и как правильно включить его в практику с двумя популярными клиентами — Certbot и lego. Поговорим о хранении секретов, миграциях, отладке типичных ошибок и об операционной автоматике продлений.

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

External Account Binding — это способ CA убедиться, что создаваемый вами ACME-аккаунт связан с ранее выданной учёткой в их собственной системе (портал, API, биллинг). Для этого CA выдаёт вам пару значений:

  • KID — идентификатор внешнего аккаунта (Key ID).
  • HMAC-ключ — секрет для расчёта подписи привязки.

Когда ACME-клиент отправляет newAccount, он добавляет объект externalAccountBinding, который содержит JWS, подписанный по схеме HMAC с использованием выданного секрета. Таким образом CA получает гарантию, что ключи нового ACME-аккаунта (ваш JWK) действительно принадлежат вам как владельцу внешней учётной записи в их системе.

Коротко: EAB — это одноразовая проверка связки «внешний аккаунт в CA» ↔ «новый ACME-аккаунт» при создании последнего. После успешного создания аккаунта EAB повторно не требуется.

Что важно знать перед настройкой

  • Где взять KID/HMAC. Обычно в панели CA или их API. Чаще всего это единичный набор для вашей организации/подписки. Иногда выдаётся несколько наборов.
  • Формат HMAC-ключа. Как правило — base64url без паддинга (=). Уточните формат у CA. Если вам отдали обычный base64 или с переносами строк, приведите к требуемому виду.
  • Единовременность EAB. EAB нужен только при создании нового ACME-аккаунта на стороне данного CA. Если аккаунт уже создан локально и успешно использовался, переинициализация EAB не требуется.
  • Изоляция по CA. Аккаунт и EAB привязаны к конкретному CA и его directory-URL. Переход к другому CA потребует новой регистрации и нового EAB.
  • Хранение секрета. HMAC — это ключ с уровнем чувствительности токена API. Не помещайте его в репозитории в открытом виде; используйте секрет-хранилища и права доступа по принципу наименьших привилегий.

Внутренности потока ACME с EAB (в двух словах)

Клиент генерирует ключи аккаунта (JWK), формирует запрос newAccount, добавляя узел externalAccountBinding, где содержится JWS с полем kid и подписью по HMAC. Если EAB корректен, CA создаёт аккаунт и возвращает объект со статусом. Далее цикл обычный: заказ авторизаций, валидация (HTTP-01/DNS-01), заказ сертификата, выпуск, продление.

Если CA ожидает EAB, но вы его не предоставили, либо он неверен, типичный ответ — ошибка с типом проблемы externalAccountRequired или unauthorized с уточняющим описанием.

Пример регистрации Certbot с параметрами EAB

Подготовка окружения

Минимально вам понадобятся:

  • Доступ к серверам/контейнерам, где крутится ваш ACME-клиент (Certbot или lego).
  • Директория directory конкретного CA (prod или staging).
  • Креденшалы EAB: KID и HMAC-ключ.
  • Способ прохождения челенджей: HTTP-01 (webroot/standalone) или DNS-01 (через API провайдера DNS).

Certbot: включаем EAB

Разовая регистрация аккаунта с EAB

Для Certbot EAB включается параметрами --eab-kid и --eab-hmac-key. Укажите также --server на ваш CA и согласие с условиями использования:

certbot register --non-interactive --agree-tos --email admin@example.com --server https://acme.ca.example.invalid/directory --eab-kid "YOUR_KID_FROM_CA" --eab-hmac-key "BASE64URL_HMAC_KEY_FROM_CA"

Если вы сразу хотите выпустить сертификат, и аккаунт ещё не создан, можно передать те же флаги в certbot certonly или certbot run. Пример для HTTP-01 через webroot:

certbot certonly --non-interactive --agree-tos --email admin@example.com --server https://acme.ca.example.invalid/directory --eab-kid "YOUR_KID_FROM_CA" --eab-hmac-key "BASE64URL_HMAC_KEY_FROM_CA" --webroot -w /var/www/html -d example.com -d www.example.com

Для DNS-01 используйте соответствующий плагин Certbot (провайдер-зависимо), например:

export CF_DNS_API_TOKEN="cloudflare-token-with-dns-edit"
certbot certonly --non-interactive --agree-tos --email admin@example.com --server https://acme.ca.example.invalid/directory --eab-kid "YOUR_KID_FROM_CA" --eab-hmac-key "BASE64URL_HMAC_KEY_FROM_CA" --dns-cloudflare -d example.com -d "*.example.com"

После первого успешного запроса аккаунт будет создан и сохранён в /etc/letsencrypt/accounts/. Повторно указывать EAB не потребуется, если вы остаетесь с тем же CA и тем же локальным хранилищем.

Файл конфигурации Certbot

Чтобы не передавать флаги каждый раз, добавьте базовые параметры в /etc/letsencrypt/cli.ini (или свой конфиг):

server = https://acme.ca.example.invalid/directory
email = admin@example.com
agree-tos = true
non-interactive = true
# EAB только при первичном создании аккаунта, можно временно добавить:
# eab-kid = YOUR_KID_FROM_CA
# eab-hmac-key = BASE64URL_HMAC_KEY_FROM_CA

Совет: держите строки с EAB закомментированными и включайте их только на время первичной регистрации. Так меньше шанс случайно «засветить» ключ при отладке.

Где проверить, что аккаунт создан

Проверьте, что в /etc/letsencrypt/accounts/ появилась директория вашего CA, внутри — уникальный идентификатор аккаунта с файлом private_key.json и метаданными. Простейшая проверка:

sudo ls -l /etc/letsencrypt/accounts

lego: включаем EAB

lego поддерживает EAB флагами --eab, --kid и --hmac (или через переменные окружения). Ниже пример запуска для HTTP-01 через standalone:

lego --email admin@example.com --server https://acme.ca.example.invalid/directory --eab --kid "YOUR_KID_FROM_CA" --hmac "BASE64URL_HMAC_KEY_FROM_CA" --http --domains example.com run

Для DNS-01 укажите провайдера и его креденшалы (пример — Cloudflare):

export CF_DNS_API_TOKEN="cloudflare-token-with-dns-edit"
lego --email admin@example.com --server https://acme.ca.example.invalid/directory --eab --kid "YOUR_KID_FROM_CA" --hmac "BASE64URL_HMAC_KEY_FROM_CA" --dns cloudflare --domains example.com --domains *.example.com run

Управлять EAB можно и переменными окружения, это удобно в CI/CD:

export LEGO_EAB_KEY_ID="YOUR_KID_FROM_CA"
export LEGO_EAB_HMAC_KEY="BASE64URL_HMAC_KEY_FROM_CA"
lego --email admin@example.com --server https://acme.ca.example.invalid/directory --dns cloudflare --domains example.com run

Аккаунт и ключи lego по умолчанию сохраняет в директории .lego/ в текущем каталоге (или в указанном через --path):

ls -l .lego/accounts

Схема создания ACME-аккаунта с externalAccountBinding

Выбор челенджа: HTTP-01, TLS-ALPN-01 или DNS-01

EAB не зависит от выбранного способа валидации домена. Какой выбрать:

  • HTTP-01 — простой, если у вас есть доступ к веб-корню и прямой запрос снаружи достигает вашего сервера на 80 порту.
  • TLS-ALPN-01 — полезен, если 80 порт закрыт, но вы можете обработать специальный ALPN-хендшейк на 443.
  • DNS-01 — нужен для wildcard-сертификатов и когда HTTP-01 невозможен. Требует API-доступ к DNS-провайдеру.

Если идёте в wildcard, посмотрите материал о полной автоматизации DNS-01: пошаговая автоматизация Wildcard через DNS-01. Для сложных SAN-наборов пригодится разбор лимитов и практик: SAN и rate limits в автоматизации.

FastFox SSL
Надежные SSL-сертификаты
Мы предлагаем широкий спектр SSL-сертификатов от GlobalSign по самым низким ценам. Поможем с покупкой и установкой SSL бесплатно!

Хранение и безопасность KID/HMAC

  • Храните HMAC-ключ в секрет-хранилище: менеджеры секретов, vault, шифрованные переменные в CI, ограниченные права доступа.
  • Не коммитьте HMAC в репозиторий. Если очень нужно положить в файл, используйте шифрование (например, ansible-vault, sops) и доступ по принципу need-to-know.
  • Следите за форматом: многие CA выдают ключ в base64url без паддинга. Если клиент ожидает именно такой формат — удалите символы переноса, пробелы и = в конце.
  • Не переиспользуйте один набор EAB на разных окружениях без необходимости. Лучше завести отдельные наборы для prod и staging у CA, чтобы не смешивать события аудита.

Продление и автоматизация

После первичной регистрации и успешного выпуска сертификаты продлеваются стандартными средствами клиентов.

  • Certbot поставляет systemd-таймер, который вызывает certbot renew. Убедитесь, что в журнале есть успешные продления, а веб-сервер перезагружается после обновления цепочки.
  • lego можно запускать по cron или systemd timers, используя команду renew. Проверьте флаги для перезагрузки сервиса и пути деплоя сертификата (ключи, цепочка, fullchain).

Важно: EAB для продлений не нужен. Клиент уже имеет валидный ACME-аккаунт и просто повторяет авторизации и/или заказывает новый сертификат в рамках существующего аккаунта.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Миграции и клон-окружения

Нужно перенести автоматизацию на другой сервер или в контейнер?

  • Certbot: перенесите директорию /etc/letsencrypt/ (включая accounts, archive, live) и убедитесь, что права/владельцы совпадают. После переноса EAB не нужен.
  • lego: перенесите .lego/ (или каталог, указанный --path). Снова же, EAB не потребуется.

Меняете CA? Тогда придётся регистрировать аккаунт заново и применить новый EAB, полученный в новом CA (и указать другой server).

Типичные ошибки и как их диагностировать

  • externalAccountRequired: CA требует EAB, а вы его не передали. Добавьте --eab-kid/--eab-hmac-key (Certbot) или --eab/--kid/--hmac (lego).
  • unauthorized / account binding failed: неверный KID или неподходящий HMAC. Проверьте, что KID/HMAC соответствуют вашему CA и окружению (prod vs staging).
  • malformed / badSignatureAlgorithm: клиент или сервер не согласны с форматом ключа. Убедитесь, что HMAC — именно base64url без переносов и паддинга, и не содержит скрытых символов (проверяйте, нет ли \n в конце при экспорте через echo без опции).
  • wrong directory: указали URL другого CA или не то окружение. Убедитесь, что --server указывает правильный endpoint вашего CA.
  • reuse with different CA: пытаетесь использовать уже созданный аккаунт на другом CA — так нельзя. Нужен новый аккаунт и заново EAB.

Практические проверки

  • Проверьте, что KID — это именно строка из портала CA, а не внутренний идентификатор пользователя или проекта.
  • Проверьте HMAC-ключ: удалить переносы, пробелы, паддинг. В большинстве случаев строка выглядит как «безопасный для URL» base64 (- и _ вместо + и /).
  • Если ключ скопирован из UI — вставьте в чистый текстовый редактор, затем в переменную окружения через export KEY='...' (кавычки безопаснее, чем без них).

Интеграция с инфраструктурой: CI/CD, секреты и деплой

В реальных проектах EAB живёт рядом с остальными секретами инфраструктуры. Несколько практик:

  • Храните KID/HMAC в менеджере секретов (CI/CD secrets, vault). Передавайте их в рантайм через переменные окружения, не логируйте значения.
  • Разделите секреты по окружениям: staging, preprod, prod. Разные CA endpoint’ы и разные EAB-секреты помогут избежать неожиданных расходов или блокировок.
  • Логируйте только факт регистрации аккаунта, маскируя чувствительные данные.
  • После выпуска сертификата автоматически перезапускайте сервисы, которые его читают: nginx, apache, haproxy и т.п.

Если вам нужен коммерческий сертификат для продакшн‑систем, оформите SSL-сертификаты и подключите ACME‑автопродление там, где это доступно. Автоматика удобнее всего на отдельной машине — подойдёт управляемый VDS.

Особенности, на которые часто не обращают внимания

  • Алгоритм аккаунт-ключа. И Certbot, и lego по умолчанию используют современные кривые для ключей аккаунта и сертификата (EC). Это нормально, EAB от этого не меняется.
  • Права на файлы. Убедитесь, что пользователь, под которым запускается клиент, может записывать ключи аккаунта и сертификаты.
  • Срок действия сертификатов. При коротких сроках (например, 90 дней) убедитесь, что механизм продления срабатывает заблаговременно (за 30 дней), а перезапуск сервисов не ломает соединения.
  • Staging. Имеет смысл сначала отработать связку EAB + выпуск сертификата на тестовом окружении CA, не тратя лимиты продакшна.

Контрольная карта внедрения

  1. Получите у CA пару EAB: KID и HMAC (уточните формат ключа — base64url).
  2. Определите directory вашего CA для нужного окружения.
  3. Подготовьте метод валидации: HTTP-01, TLS-ALPN-01 или DNS-01.
  4. Создайте ACME-аккаунт с EAB в выбранном клиенте (Certbot или lego).
  5. Выпустите первый сертификат и проверьте, что деплой и перезапуски сервисов отрабатывают.
  6. Настройте автоматическое продление и мониторинг срока действия сертификатов.
  7. Зашивайте EAB-данные в безопасные секрет-хранилища, избегайте их попадания в логи и репозитории.

FAQ по acme eab, certbot, lego

Нужно ли указывать EAB при каждом запуске?
Нет. Только при создании нового аккаунта у конкретного CA. После этого клиент reutilизирует аккаунт.

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

Можно ли сменить EAB позже?
Если CA выпустил новый набор KID/HMAC, это касается последующих новых аккаунтов. Уже созданные аккаунты продолжат работать. Иногда CA может отозвать старый EAB и потребовать новый только для новых регистраций.

Почему клиент жалуется на неверную подпись?
Обычно это неверный формат HMAC: base64 vs base64url, лишние переносы, пробелы или паддинг. Проверьте точное требование CA и документацию клиента.

Краткие шпаргалки команд

Certbot: webroot + EAB

certbot certonly --non-interactive --agree-tos --email admin@example.com --server https://acme.ca.example.invalid/directory --eab-kid "YOUR_KID_FROM_CA" --eab-hmac-key "BASE64URL_HMAC_KEY_FROM_CA" --webroot -w /var/www/html -d example.com -d www.example.com

Certbot: dns-01 + EAB

export CF_DNS_API_TOKEN="cloudflare-token-with-dns-edit"
certbot certonly --non-interactive --agree-tos --email admin@example.com --server https://acme.ca.example.invalid/directory --eab-kid "YOUR_KID_FROM_CA" --eab-hmac-key "BASE64URL_HMAC_KEY_FROM_CA" --dns-cloudflare -d example.com -d "*.example.com"

lego: http + EAB

lego --email admin@example.com --server https://acme.ca.example.invalid/directory --eab --kid "YOUR_KID_FROM_CA" --hmac "BASE64URL_HMAC_KEY_FROM_CA" --http --domains example.com run

lego: dns-01 + EAB

export CF_DNS_API_TOKEN="cloudflare-token-with-dns-edit"
lego --email admin@example.com --server https://acme.ca.example.invalid/directory --eab --kid "YOUR_KID_FROM_CA" --hmac "BASE64URL_HMAC_KEY_FROM_CA" --dns cloudflare --domains example.com --domains *.example.com run

Итоги

External Account Binding — небольшой, но критичный для ряда CA шаг, без которого автоматизация выпуска SSL по ACME может не состояться. На практике всё сводится к корректному получению KID/HMAC, правильному формату HMAC (base64url, без лишних символов) и однократной регистрации аккаунта в Certbot или lego. Дальше всё привычно: выбор челенджа, выпуск, деплой, продления и мониторинг сроков.

Закладывайте EAB-учётные данные в ваш стандартный процесс управления секретами, используйте отдельные наборы для разных окружений, чётко отделяйте staging и production CA. Это позволит с первого раза пройти всё вплоть до автоматических продлений без «сюрпризов» и жить в режиме нормальной эксплуатации.

Поделиться статьей

Вам будет интересно

Debian/Ubuntu: mount: wrong fs type, bad option, bad superblock — как быстро найти и исправить причину OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: mount: wrong fs type, bad option, bad superblock — как быстро найти и исправить причину

Ошибка mount: wrong fs type, bad option, bad superblock в Debian/Ubuntu может означать и простую опечатку в имени раздела, и пробл ...
Debian/Ubuntu: XFS metadata corruption и emergency read-only — пошаговое восстановление OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: XFS metadata corruption и emergency read-only — пошаговое восстановление

Если XFS-раздел внезапно стал доступен только для чтения, а сервер ушёл в emergency mode, главное — не спешить. Разберём безопасны ...
Debian/Ubuntu: как исправить Failed to fetch при apt update OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как исправить Failed to fetch при apt update

Ошибка Failed to fetch при apt update в Debian и Ubuntu обычно связана не с самим APT, а с DNS, сетью, зеркалом, прокси, временем ...