Давайте зашифруем контроллер входа kubernetes, выдающий поддельный сертификат

#nginx #kubernetes #lets-encrypt #kubernetes-helm #alibaba-cloud

#nginx #kubernetes #давайте зашифруем #kubernetes-helm #alibaba-облако

Вопрос:

Не уверен, почему я получаю поддельный сертификат, даже если сертификат правильно выдан Let’s Encrypt с помощью certmanager

введите описание изображения здесь

Установка выполняется на консоли Alibaba Cloud ECS, где один Kube-master и один cube-minion образуют кластер Kubernetes.

введите описание изображения здесь

Сведения об услуге

 root@kube-master:~# kubectl get svc 
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP   3h20m
my-nginx     ClusterIP   10.101.150.247   <none>        80/TCP    77m
  

Подробности модуля

 root@kube-master:~# kubectl get pods --show-labels
NAME                        READY   STATUS    RESTARTS   AGE   LABELS
my-nginx-6cc48cd8db-n6scm   1/1     Running   0          46s   app=my-nginx,pod-template-hash=6cc48cd8db
  

Развернут Helm Cert-manager

 root@kube-master:~# helm ls 
NAME            REVISION    UPDATED                     STATUS      CHART               APP VERSION NAMESPACE  
cert-manager    1           Tue Mar 12 15:29:21 2019    DEPLOYED    cert-manager-v0.5.2 v0.5.2      kube-system
kindred-garfish 1           Tue Mar 12 17:03:41 2019    DEPLOYED    nginx-ingress-1.3.1 0.22.0      kube-system
  

Сертификат выдан правильно

 root@kube-master:~# kubectl describe certs 
Name:         tls-prod-cert
Namespace:    default
Labels:       <none>
Annotations:  <none>
API Version:  certmanager.k8s.io/v1alpha1
Kind:         Certificate
Metadata:
  Creation Timestamp:  2019-03-12T10:26:58Z
  Generation:          2
  Owner References:
    API Version:           extensions/v1beta1
    Block Owner Deletion:  true
    Controller:            true
    Kind:                  Ingress
    Name:                  nginx-ingress-prod
    UID:                   5ab11929-44b1-11e9-b431-00163e005d19
  Resource Version:        17687
  Self Link:               /apis/certmanager.k8s.io/v1alpha1/namespaces/default/certificates/tls-prod-cert
  UID:                     5dad4740-44b1-11e9-b431-00163e005d19
Spec:
  Acme:
    Config:
      Domains:
        zariga.com
      Http 01:
        Ingress:        
        Ingress Class:  nginx
  Dns Names:
    zariga.com
  Issuer Ref:
    Kind:       ClusterIssuer
    Name:       letsencrypt-prod
  Secret Name:  tls-prod-cert
Status:
  Acme:
    Order:
      URL:  https://acme-v02.api.letsencrypt.org/acme/order/53135536/352104603
  Conditions:
    Last Transition Time:  2019-03-12T10:27:00Z
    Message:               Order validated
    Reason:                OrderValidated
    Status:                False
    Type:                  ValidateFailed
    Last Transition Time:  <nil>
    Message:               Certificate issued successfully
    Reason:                CertIssued
    Status:                True
    Type:                  Ready
Events:
  Type    Reason        Age   From          Message
  ----    ------        ----  ----          -------
  Normal  CreateOrder   27s   cert-manager  Created new ACME order, attempting validation...
  Normal  IssueCert     27s   cert-manager  Issuing certificate...
  Normal  CertObtained  25s   cert-manager  Obtained certificate from ACME server
  Normal  CertIssued    25s   cert-manager  Certificate issued successfully
  

Сведения о входе

 root@kube-master:~# kubectl describe ingress
Name:             nginx-ingress-prod
Namespace:        default
Address:          
Default backend:  my-nginx:80 (192.168.123.202:80)
TLS:
  tls-prod-cert terminates zariga.com
Rules:
  Host  Path  Backends
  ----  ----  --------
  *     *     my-nginx:80 (192.168.123.202:80)
Annotations:
  kubernetes.io/ingress.class:        nginx
  kubernetes.io/tls-acme:             true
  certmanager.k8s.io/cluster-issuer:  letsencrypt-prod
Events:
  Type    Reason             Age    From                      Message
  ----    ------             ----   ----                      -------
  Normal  CREATE             7m13s  nginx-ingress-controller  Ingress default/nginx-ingress-prod
  Normal  CreateCertificate  7m8s   cert-manager              Successfully created Certificate "tls-prod-cert"
  Normal  UPDATE             6m57s  nginx-ingress-controller  Ingress default/nginx-ingress-prod
  

Давайте зашифруем производственное определение Nginx

 apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress-prod
  annotations:
    kubernetes.io/ingress.class: nginx
    certmanager.k8s.io/cluster-issuer: letsencrypt-prod
    kubernetes.io/tls-acme: 'true'
  labels:
    app: 'my-nginx'
spec:
  backend:
    serviceName: my-nginx
    servicePort: 80
  tls:
  - secretName: tls-prod-cert
    hosts:
    - zariga.com
  

Комментарии:

1. Какого DNS-провайдера вы используете? Можете ли вы также опубликовать свои файлы yaml?

2. Поставщиком DNS является godaddy

3. Несколько вещей, используете ли вы http01, как я вижу в описании вашего сертификата? Также следует отметить, что сертификат создает секрет tls только в том случае, если старый сертификат не существует. Итак, если вы только что переключились с промежуточного URL на prod URL, удалите секрет.

Ответ №1:

Возможно, было бы полезно для кого-то, кто испытывает подобные проблемы. Что касается меня, я забыл указать имя хоста в файле Ingress yaml для обоих разделов rules и tls . После дублирования имени хоста он начал отвечать соответствующим сертификатом.

Пример:

 apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: test-web-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  tls:
  - hosts:
    - my.host.com                # <----
    secretName: tls-secret
  rules:
    - host: my.host.com          # <----
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              serviceName: my-nginx
              servicePort: 80
  

Комментарии:

1. Это был именно мой случай. Спасибо за этот ответ!

2. Точно мой случай!

3. в моем случае я добавил больше доменов в раздел tls, а затем в раздел моих правил. Потому что я пытался обслуживать будущие домены, которые еще не готовы. Итак, я получаю ошибку поддельного сертификата. После удаления этих доменов, которые еще не готовы, сертификат работает.

Ответ №2:

Иногда это может произойти, если вы используете URL-адрес clusterissuer в качестве промежуточного URL.

Проверьте URL-адрес letsencrypt, установленный в вашем эмитенте.yaml или clusterissuer.yaml и измените его на рабочий URL:https://acme-v02.api.letsencrypt.org/directory

Однажды я столкнулся с такой же проблемой, и изменение URL на рабочий URL решило ее.

Также убедитесь, что используемые вами входные секреты tls верны.

Фактический эмитент кластера должен быть чем-то вроде для производства :

 apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: dev-clusterissuer
spec:
  acme:
    email: harsh@example.com
    privateKeySecretRef:
      name: dev-clusterissuer
    server: https://acme-v02.api.letsencrypt.org/directory       # <----check this server URL it is for Prod and use this only
    solvers:
    - http01:
        ingress:
          class: nginx
  

Если вы используете сервер: https://acme-staging-v02.api.letsencrypt.org/directory вы столкнетесь с проблемой, лучше замените его на server: https://acme-v02.api.letsencrypt.org/directory

Комментарии:

1. Это полезный совет для других, но из скриншота в вопросе не похоже, что у OP есть промежуточный сертификат. Это покажет организацию так, (STAGING) Let's Encrypt как если бы она была.

2. да, если это поддельный сертификат ingress, неверный tls, входящий в конфигурацию ingress или даже промежуточный сертификат let’s encrypt, отсутствует и должным образом не задан в секрете.

Ответ №3:

Если вы уверены, что все настроено правильно, и это все еще не работает, попробуйте это.

Отредактируйте развертывание вашего nginx-контроллера. Почему? Потому что, если он не находит секрет в пространстве имен, в котором он развернут, контроллер Nginx развертывает свой собственный сертификат (поддельный сертификат). Незнание этого (я новичок в игре) стоило мне нескольких дней моей жизни.

Итак, либо измените пространство имен, в котором находится ваш входной контроллер Nginx, и получите имя развертывания, тогда:

 kubectl edit deployment nginx-ingress-ingress-nginx-controller -n nginx-ingress
  

Или, если в этом пространстве имен есть только одно развертывание, вы можете просто сделать

 kubectl edit deployment
  

И вы должны быть в режиме редактирования для развертывания вашего контроллера nginx. Найдите раздел: спецификация -> контейнеры: -> аргументы:

  spec:
  containers:
  - args:
    - /nginx-ingress-controller
    - --publish-service=$(POD_NAMESPACE)/nginx-ingress-ingress-nginx-controller
    - --election-id=ingress-controller-leader
    - --ingress-class=nginx
    - --configmap=$(POD_NAMESPACE)/nginx-ingress-ingress-nginx-controller
    - --validating-webhook=:8443
    - --validating-webhook-certificate=/usr/local/certificates/cert
    - --validating-webhook-key=/usr/local/certificates/key
    - --default-ssl-certificate=app-namespace/letsencrypt-cert-prod
  

Вы можете добавить сертификат по умолчанию для использования, если ваш контроллер nginx не находит его (как у меня выше), поэтому он будет искать секрет в пространстве имен, добавив:

 --default-ssl-certificate=your-cert-namespace/your-cert-secret
  

your-cert-namespace: пространство имен, в котором находится секрет вашего сертификата
your-cert-secret: имя вашего сертификата, содержащего секретный

Как только вы сохраните и закроете свой редактор, его следует обновить. Затем проверьте журналы вашего модуля cert manager:

 kubectl logs cert-manager-xxxpodxx-abcdef -n cert-manager
  

Чтобы убедиться, что все работает как обычно.

Вероятно, у вас не возникнет этой проблемы, если все ваши ресурсы развернуты в одном пространстве имен.

Ответ №4:

Важно отметить, что спецификация ClusterIssuer для решателей изменилась. Для людей, использующих cer-manager>0.7.2 , этот комментарий сэкономил мне так много времени: https://github.com/jetstack/cert-manager/issues/1650#issuecomment-518953464 . Специально о том, как настроить ClusterIssuer и сертификат.

Ответ №5:

Для меня проблема заключалась в имени класса ingress, поскольку я использую microk8s, имя класса ingress public :

 apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    email: "your@email.tld"
    privateKeySecretRef:
      name: letsencrypt-prod
    server: "https://acme-v02.api.letsencrypt.org/directory"
    solvers:
      - http01:
         ingress:
           class: public
  

Ответ №6:

В моем случае проблема заключалась в доступе к домену через неправильный порт, мой порт https по умолчанию был не 443, а 4443

Ответ №7:

Для меня проблема заключалась в том, что я забыл kubectl apply секрет (в моем случае 'tls-secret.yml' ). При ручном развертывании K8S такая ошибка возникает редко. Однако я использую gitlab CICD для развертывания приложений, и я забыл добавить - kubectl apply -f ./kube/secret в свой .gitlab-ci.yml .

Ответ №8:

В моем случае я неправильно ввел имя моего tls-секрета в своих правилах входа.

вместо secretName: my-homepage-tls я набрал secretName: myy-homepage-tls

Ответ №9:

Это случилось со мной сегодня, у меня было 2 входа в одно и то же пространство имен, и я использовал letsencrypt-prod в качестве секретного имени для обоих. Один сработал, другой — нет. Секреты генерируются автоматически и должны иметь уникальное имя, чтобы избежать конфликтов