В Kubernetes Helm chart собирает сертификаты, нужные для mutual TLS, через cert-manager и, по желанию, trust-manager. Эта страница объясняет иерархию УЦ, какой listener чему доверяет, куда монтируется каждый файл и на что смотреть, если подставить свой issuer. Про chart в целом см. Деплой в Kubernetes; про клиентскую сторону сертификатов — Клиентские сертификаты и их продление. Собственный справочник chart — k8s/README.md в репозитории продукта.
Требования
pki.enabled по умолчанию true, поэтому cert-manager и trust-manager нужно установить до chart: он рендерит их объекты ClusterIssuer, Certificate и Bundle, но сам их не ставит. Отключить можно через pki.enabled: false.
Один корневой УЦ, три промежуточных
pki создает корневой УЦ (<release>-versola-root-ca) и под ним три промежуточных УЦ, каждый как ClusterIssuer, по одному на роль:
| Промежуточный | Что подписывает |
|---|---|
server | Сертификаты listener’ов auth и central |
edge | Идентичности edge: URI-имена urn:versola:edge:<id> и urn:versola:edge-group:<group> |
client | Клиентские сертификаты |
Сертификат годится только там, где это разрешает его роль, потому что listener доверяет промежуточному УЦ, но не корневому: корневой допустил бы каждую роль везде.
| Listener | Чему доверяет | Bundle (ConfigMap) |
|---|---|---|
handshake auth | УЦ клиентов и УЦ edge (edge тоже предъявляет auth свою идентичность) | <release>-versola-client-ca |
проверка имени edge в auth (mutual-tls.edge-trusted-certificates) | Только УЦ edge: сертификат может нести urn:versola:edge:*, только если строится к нему | <release>-versola-edge-ca |
handshake central | Только УЦ edge, так что клиентский сертификат не проходит уже handshake, а не только проверку в приложении | <release>-versola-edge-ca |
Edge закрепляют листовые сертификаты listener’ов auth и central. Без trust-manager (pki.trustBundle.enabled: false) chart вместо этого монтирует ca.crt из каждого листового Secret, а это корневой УЦ: все соединяется, но ничего не разделено.
central подписывает выпускаемые им сертификаты edge издателем edge (EDGE_CERT_ISSUER_NAME), а клиентам издателем client (CLIENT_CERT_ISSUER_NAME). Его роль может создавать объекты CertificateRequest в namespace релиза и ничего больше. Листовые и промежуточные сертификаты продлеваются через cert-manager: у листовых duration: 2160h и renewBefore: 720h.
Файлы, которые монтируют pod’ы
Chart не генерирует env.conf; направьте свой на эти пути.
| Сервис | Смонтировано в | Использовать как |
|---|---|---|
auth | /app/mtls/server/tls.crt, tls.key | mutual-tls.certificate, private-key |
auth | /app/mtls/trust/ca.crt | mutual-tls.trusted-certificates (bundle УЦ клиентов и УЦ edge) |
auth | /app/mtls/edge-trust/ca.crt | mutual-tls.edge-trusted-certificates (только УЦ edge) |
edge | /app/mtls/auth-pin/tls.crt | native.trusted-certificates (закрепление листового сертификата; edge получает сертификат, но не ключ) |
central | /app/central-mtls/server/tls.crt, tls.key | mutual-tls.certificate, private-key |
central | /app/central-mtls/trust/ca.crt | mutual-tls.trusted-certificates (только УЦ edge) |
edge | /app/central-mtls/client/tls.crt, tls.key | central.mutual-tls.certificate, private-key (идентичность edge внутри кластера) |
edge | /app/central-mtls/server-pin/tls.crt | central.mutual-tls.trusted-certificates (закрепление листового сертификата central) |
Сервисы читают эти файлы один раз при запуске, поэтому после продления нужен перезапуск. Используйте Stakater Reloader (pki.reloader) или kubectl rollout restart после того, как cert-manager продлит сертификаты. Для ротации сертификата listener’а auth без простоя применяйте процедуру с двумя закреплениями (конфигурация edge), а не полагайтесь на автоматическое продление. Для смены УЦ добавьте Secret нового УЦ в pki.trustBundle.sources (или edgeSources) рядом с созданным при bootstrap, перевыпустите все, что подписывал этот УЦ, затем уберите уходящий источник.
Откуда EST берет свой УЦ
EST отдает УЦ клиентов через cacerts, и в этом файле должен быть только УЦ клиентов. Не направляйте est.ca-certificates на /app/mtls/trust/ca.crt: это bundle УЦ клиентов и УЦ edge, а клиенту нельзя велеть доверять УЦ edge. При EST_ENABLED=true chart монтирует только УЦ клиентов из bundle <release>-client-only-ca, а gen-env для таргета k8s записывает путь:
| Сервис | Смонтировано в | Использовать как |
|---|---|---|
auth | /app/mtls/client-trust/ca.crt | est.ca-certificates (только УЦ клиентов) |
См. блок est.
Свой issuer
pki.issuerRef направляет все роли на issuer, который у вас уже есть, а pki.issuerRefs.{server,edge,client} — одну роль. Роль со своим issuer’ом не создает УЦ при bootstrap, и тогда trustBundle.sources или edgeSources должны называть этот УЦ.
Если дать всем ролям один issuer, УЦ edge и УЦ клиентов окажутся одним УЦ. Так делать не рекомендуется. Разделение нужно, чтобы клиентский сертификат никогда не мог сойти за edge: auth доверяет УЦ edge ручаться, что вызов /userinfo пришел от edge, а УЦ, который подписывает и клиентские сертификаты, может подписать имя edge для клиента. При одном issuer’е на все роли файлы «только клиенты» и «только edge» — один и тот же УЦ, и EST велит клиенту доверять УЦ, который выпускает и идентичности edge: дайте роли edge собственный issuer (pki.issuerRefs.edge), прежде чем включать EST для партнеров. Если иначе нельзя, central все равно отказывает во вписывании имен urn:versola:edge: в клиентские сертификаты, а auth пишет предупреждение при запуске, но защита держится на этой единственной проверке. См. Токены с привязкой к отправителю.
Что дальше
- Деплой в Kubernetes: остальное про chart.
- Клиентские сертификаты edge: как
edgeполучает собственные сертификаты. - Автоматическое продление клиентского сертификата (EST)