RFC 7030 — Enrollment over Secure Transport (EST) — Versola Docs
/docs
До 1.00.7.5versola.ioGitHub

RFC 7030 — Enrollment over Secure Transport (EST)

EST в том виде, в каком Versola его обслуживает, чтобы mTLS-клиент сам получал и продлевал клиентский сертификат: проверенные пункты и отличия от RFC.

Спецификация: RFC 7030

Через EST клиент запрашивает сертификат X.509 по HTTPS. Versola использует его для одной цели: клиент, зарегистрированный с tls_client_auth и estEnrollment, сам получает и продлевает клиентский сертификат, которым аутентифицируется на /token (RFC 8705), с ключом, который создал сам. auth обслуживает эндпоинты и не хранит учетных данных УЦ; central решает, что выпускать, и поручает подписать УЦ, стоящему за client-certificates. Пошаговая инструкция — Автоматическое продление клиентского сертификата (EST), идея описана в Клиентские сертификаты и их продление, а API — это est.yaml в справочнике OpenAPI.

Статус

Реализован частично. Отмечено пунктов: 16 из 20. Маршруты отвечают 404, пока блок est у auth их не включит (справочник конфигурации).

Эндпоинты

  • GET /.well-known/est/cacerts (§4.1) — УЦ клиентов в виде PKCS#7 только с сертификатами, учетные данные не нужны
  • GET /.well-known/est/csrattrs (§4.5) — отвечает 204: запрос просят не нести атрибутов
  • POST /.well-known/est/simpleenroll (§4.2.1) — первый сертификат, для клиента, у которого его нет
  • POST /.well-known/est/simplereenroll (§4.2.2) — новый сертификат взамен того, что есть у клиента
  • Запрос application/pkcs10, base64 от DER; ответ application/pkcs7-mime; smime-type=certs-only с Content-Transfer-Encoding: base64
  • Subject и альтернативные имена запроса на продление должны совпадать с теми, что у продлеваемого сертификата (§4.2.2); запрос с другим subject отклоняется с 400 и причиной

Аутентификация

  • simpleenroll по HTTP Basic: client id как имя пользователя и одноразовый токен выдачи как пароль (§3.2.3)
  • simplereenroll по текущему сертификату клиента в TLS handshake (§3.3.2), проверяется по mutual-tls.trusted-certificates; сертификат в заголовке запроса никогда не читается
  • Токен выдачи одноразовый, истекает (по умолчанию 24 часа, не больше 168), хранится только как хеш и показывается один раз. Неизвестный, использованный, истекший или чужой токен дает один и тот же 401
  • Тело запроса не больше 16 КиБ

Что решает Versola

  • В сертификате стоит subject, по которому клиент зарегистрирован (mtlsAuth или CN=<client>,OU=<tenant>,O=Versola, если он не задан), а не тот, что назван в запросе
  • Ключи: EC P-256 или RSA не короче 2048 бит
  • Каждое продление требует нового ключа; запрос, который повторно использует ключ заменяемого сертификата, отклоняется с 400
  • Сертификат продлевается только в последней трети срока жизни (client-identity.renew-window); раньше будет 403 с указанием, когда окно откроется
  • Продления образуют цепочку, которая заканчивается на client-identity.max-age; конец цепочки есть в каждом ответе в заголовке Versola-Chain-Ends-At
  • Повторная выдача или POST /configuration/clients/est/revoke лишают права продлевать все прежние сертификаты (401)

Отличия от RFC

  • Два origin. simpleenroll обслуживается на origin issuer’а, а simplereenroll только на origin mutual-TLS (на другом 404), поэтому клиенту нужны два базовых URL, чего §3.2.2 не предполагает. Стандартный EST-клиент с одним базовым URL получит 404 на simplereenroll на origin issuer’а и ошибку TLS handshake на simpleenroll на origin mutual-TLS; запускайте его отдельно для каждого origin.
  • Новый ключ при каждом продлении. §4.2.2 допускает тот же ключ (renew) наравне с новым (rekey); Versola тот же ключ отклоняет. Клиент, чей HSM не умеет создавать новый ключ для каждого сертификата, этим профилем пользоваться не может.
  • Bearer-токены. Кроме Basic, токен выдачи можно отправить как Authorization: Bearer. Это расширение: §3.2.3 называет Basic и Digest, а WWW-Authenticate объявляет только Basic.
  • cacerts и csrattrs на обоих listener’ах. На основном listener’е они не требуют учетных данных, и именно там их забирает клиент без сертификата. На mutual-TLS listener’е они тоже обслуживаются, но его handshake требует клиентский сертификат, поэтому там они доступны только с действительным.
  • Расширения Versola в ответах. 429 с Retry-After при более чем 30 попытках simpleenroll в минуту на client id и реплику, заголовок Versola-Chain-Ends-At и 403 «слишком рано» для продления до открытия окна.
  • Channel binding. §3.5 требует, чтобы сервер проверял значение tls-unique, которое включает клиент, а tls-unique не определен для TLS 1.3, поэтому запрос с challengePassword отклоняется с 400.
  • Не объявляется в mtls_endpoint_aliases. Документ метаданных не перечисляет эндпоинты EST; клиент настраивается с обоими базовыми URL.

Не реализовано

  • Channel binding (§3.5, tls-unique): запрос с атрибутом challengePassword отклоняется
  • Полный CMC (§4.3, fullcmc)
  • Произвольные метки (/.well-known/est/<label>/...): один УЦ, без иерархии; csrattrs всегда 204
  • Генерация ключа на стороне сервера (§4.4, serverkeygen): ключ всегда клиентский

Куда смотреть

Клиентские сертификаты и их продление объясняет цепочку, поколения и отзыв. RFC 8705 описывает, для чего используется сертификат.