Если вы автоматизируете выпуск 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 с уточняющим описанием.

Подготовка окружения
Минимально вам понадобятся:
- Доступ к серверам/контейнерам, где крутится ваш 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

Выбор челенджа: 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 в автоматизации.
Хранение и безопасность 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-аккаунт и просто повторяет авторизации и/или заказывает новый сертификат в рамках существующего аккаунта.
Миграции и клон-окружения
Нужно перенести автоматизацию на другой сервер или в контейнер?
- 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, не тратя лимиты продакшна.
Контрольная карта внедрения
- Получите у CA пару EAB:
KIDиHMAC(уточните формат ключа — base64url). - Определите
directoryвашего CA для нужного окружения. - Подготовьте метод валидации: HTTP-01, TLS-ALPN-01 или DNS-01.
- Создайте ACME-аккаунт с EAB в выбранном клиенте (Certbot или lego).
- Выпустите первый сертификат и проверьте, что деплой и перезапуски сервисов отрабатывают.
- Настройте автоматическое продление и мониторинг срока действия сертификатов.
- Зашивайте 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. Это позволит с первого раза пройти всё вплоть до автоматических продлений без «сюрпризов» и жить в режиме нормальной эксплуатации.


