Автоматический выпуск SSL-сертификатов. Используем Kubernetes и FreeIPA

—

от автора

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

Важно! Чтобы воспользоваться этим способом выпуска SSL-сертификатов, у вас должны быть лишний кластер Kubernetes и FreeIPA, между которыми настроена сетевая связность. Если это так, поздравляю, летим за сертификатами.

Коротко о задаче

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

Также можно использовать бесплатные способы, в том числе основанные на алгоритмах протокола Automated Certificate Management Environment (ACME). Благодаря им можно заказать SSL-сертификат типа domain-validated. Это самый простой сертификат, который можно получить бесплатно на 90 дней. Дальше требуется обновление. 

Упростить работу с сертификатами можно с помощью Kubernetes. А точнее — благодаря плагину cert-manager. Его задача как раз сводится к тому, чтобы автоматизировать выпуск и обновление SSL-сертификатов. 

Сделать процесс еще проще, как выяснилось, позволяет сетевая связность Kubernetes с решениями IdM (от identity management, если вдруг забыли). В моем случае это FreeIPA. 

Плюсы способа:

  • выпуск SSL-сертификата занимает максимум 5 минут (если делать все вручную, то можно зависнуть с задачей на полдня),

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

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

Переходим к делу

1. Для начала необходимо включить поддержку ACME во FreeIPA:

(idm)# ipa-acme-manage enable

2. Чтобы cert-manager добавил DNS-запись _acme-challenge во FreeIPA, используем провайдера cert-manager (в моем случае RFC-2136). Для этого мы должны создать новый ключ TSIG на нашем IPA-сервере:

tsig-keygen -a hmac-sha512 acme-update >> /etc/named/ipa-ext.conf

3. Далее необходимо подключить cert-manager к Kubernetes. Выполняется это действие следующей командой:

helm install \   cert-manager jetstack/cert-manager \   --namespace cert-manager \   --create-namespace \   --version v1.14.4 \

4. Как только у нас появятся все необходимые манифесты, нужно будет создать секрет в Kubernetes для ключа TSIG. Для этого берем ключ TSIG и создаем с его помощью секрет Kubernetes:

kubectl -n cert-manager create secret generic ipa-tsig-secret --from-literal=tsig-secret-key="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

На этом этапе заканчиваются основные настройки Kubernetes. При выпуске следующего сертификата начинаем с п. 5. 

5. Формируем ряд манифестов.

Переходим к ресурсу ClusterIssuer, который предоставляет сертификаты TLS. В нем указываем наш сервер IdM и зону, внутри которой мы будем выпускать сертификаты:

apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata:   name: myservice.testzone.nubes.ru spec:   acme:     email: test@testzone.nubes.ru     server: https://idm1.testzone.nubes.ru/acme/directory     privateKeySecretRef:       name: ipa-issuer-account-key     solvers:       - dns01:           rfc2136:             nameserver: idm.testzone.nubes.ru             tsigKeyName: acme-update             tsigAlgorithm: HMACSHA512             tsigSecretSecretRef:               name: ipa-tsig-secret               key: tsig-secret-key         selector:           dnsZones:             - 'testzone.nubes.ru'

7. Далее создаем NetworkPolicy.

NetworkPolicy представляет собой механизм управления сетевыми политиками. Он предназначен для определения правил доступа для сетевого трафика между подами в кластере. 

С помощью NetworkPolicy мы указываем нужные хуки в белые списки:

apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata:   annotations:   name: myservice-acme-http-solver   namespace: testzone spec:   ingress:   - {}   podSelector:     matchExpressions:     - key: acme.cert-manager.io/http-domain       operator: Exists     - key: acme.cert-manager.io/http-token       operator: Exists   policyTypes:   - Ingress

8. В сертификате указываем, к какому ClusterIssuer будем обращаться и на какой адрес хотим выпустить сертификат. Также прописываем secretName (это нам понадобится для последнего манифеста):

apiVersion: cert-manager.io/v1 kind: Certificate metadata:   name: myservice-cert   namespace: testzone spec:   commonName: 'myservice.testzone.nubes.ru'   dnsNames:     - myservice.testzone.nubes.ru   issuerRef:     name: myservice.testzone.nubes.ru     kind: ClusterIssuer   privateKey:     algorithm: RSA     encoding: PKCS1     size: 4096   secretName: myservice-tls

9. И, собственно, последний из манифестов представляет собой Ingress. Указываем аннотацию ‘kubernetes.io/tls-acme: «true»‘ и наш secretName:

apiVersion: networking.k8s.io/v1 kind: Ingress metadata:   annotations:     cert-manager.io/cluster-issuer: myservice.testzone.nubes.ru     kubernetes.io/tls-acme: "true"   name: myservice-ingress   namespace: testzone spec:   ingressClassName: nginx   rules:   - host: myservice.testzone.nubes.ru     http:       paths:       - backend:           service:             name: myservice-service             port:               number: 8080         path: /         pathType: Prefix   tls:   - hosts:     - myservice.testzone.nubes.ru     secretName: myservice-tls

10. На стороне IdM получаем:

А в Kubernetes видим:

kubectl -n testzone describe certificaterequests.cert-manager.io ... ... ...   Conditions:     Last Transition Time:  2024-04-17T12:19:01Z     Message:               Certificate request has been approved by cert-manager.io     Reason:                cert-manager.io     Status:                True     Type:                  Approved     Last Transition Time:  2024-04-17T12:20:03Z     Message:               Certificate fetched from issuer successfully     Reason:                Issued     Status:                True     Type:                  Ready

Все, сертификат выпущен. В целом, конечно, можно заморочиться и делать все через Helm, и так даже правильнее. Но это уже совсем другая история…


ссылка на оригинал статьи https://habr.com/ru/articles/808035/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *