Как исправить ответы менеджера сертификатов на вызовы Let’s Encrypt ACME при использовании аутентификации по сертификату клиента в Kubernetes с nginx ingress?

#authentication #ssl #nginx #kubernetes #cert-manager

#аутентификация #ssl #nginx #kubernetes #cert-manager

Вопрос:

Мы настроили новый входной маршрут, для которого требуется аутентификация по сертификату TLS, и мы разместили его на собственном поддомене, но мы обнаруживаем, что cert-manager не может выдать для него сертификат.

Используя приведенные здесь примеры, мы сгенерировали сертификат CA и ключ CA, а затем настроили сертификат клиента: https://github.com/kubernetes/ingress-nginx/tree/master/docs/examples/auth/client-certs

В журналах я вижу, что все .acme-challenge запросы возвращают значение 403. Я предполагаю, что nginx отклоняет запросы, потому что Let’s Encrypt не может предоставить сертификат клиента для запроса запроса. Что мне нужно сделать, чтобы обойти требование к сертификату клиента для ACME?

Ответ №1:

Проблема здесь заключалась в том, что мы на самом деле неправильно настроили nginx.ingress.kubernetes.io/auth-tls-secret аннотацию. Это должно быть в namespace/name формате — где namespace это пространство имен, содержащее секрет, содержащий сертификат CA клиента, и name это имя этого секрета — но мы указали только имя, поскольку секрет находится в том же пространстве имен, что и входящий.

Я смог диагностировать проблему, сбросив конфигурацию контроллера входа nginx в nginx.conf.txt с помощью:

   kubectl exec <NAME OF INGRESS CONTROLLER POD> -n <INGRESS NAMESPACE> -- nginx -T | tee nginx.conf.txt
  

(Адаптировано из https://docs.nginx.com/nginx-ingress-controller/troubleshooting/#checking-the-generated-config ).

Это включало следующий фрагмент:

     ## start server the.hostname.com
    server {
        server_name the.hostname.com ;
        
        listen 80;
        
        set $proxy_upstream_name "-";
        set $pass_access_scheme $scheme;
        set $pass_server_port $server_port;
        set $best_http_host $http_host;
        set $pass_port $pass_server_port;
        
        listen 443  ssl http2;
        
        # PEM sha: 66c07c44ba9637a23cd3d7b6ebce958e08a52ccb
        ssl_certificate                         /etc/ingress-controller/ssl/default-fake-certificate.pem;
        ssl_certificate_key                     /etc/ingress-controller/ssl/default-fake-certificate.pem;
        
        ssl_certificate_by_lua_block {
            certificate.call()
        }
        
        # Location denied, reason: invalid format (namespace/name) found in 'the-secret-name'
        return 403;
        
    }
    ## end server the.hostname.com
  

Ключом являются эти две строки:

         # Location denied, reason: invalid format (namespace/name) found in 'the-secret-name'
        return 403;
  

Это указало мне на аннотацию для секретного имени. Как только я это исправил, ACME заработал должным образом.