Kubernetes NGINX Ingress: отключить внешнюю аутентификацию для указанного c пути - PullRequest
1 голос
/ 17 июня 2020

Я хотел бы иметь возможность отключить внешнюю авторизацию для указанного c пути моего приложения.

Аналогично этому SO: Kubernetes NGINX Ingress: Disable Basi c Auth для указанного c path

Единственное отличие заключается в использовании внешнего поставщика Auth ( OAuth через Microsoft Azure) и есть

Это путь, который должен быть доступен для публикации c

/MyPublicPath

Мой ingress.yaml:

apiVersion: extensions/v1beta1 
kind: Ingress
metadata:
  name: myIngressName
  annotations:
    nginx.ingress.kubernetes.io/auth-signin: https://externalprovider/oauth2/sign_in
    nginx.ingress.kubernetes.io/auth-url: https://externalprovider/oauth2/auth
    nginx.ingress.kubernetes.io/auth-request-redirect: https://myapp/context_root/
    nginx.ingress.kubernetes.io/auth-response-headers: X-Auth-Request-User, X-Auth-Request-Email, X-Auth-Request-Access-Token, Set-Cookie, Authorization
spec:
  rules:
  - host: myHostName
    http:
      paths:
      - backend: 
          serviceName: myServiceName
          servicePort: 9080
        path: /

Могу ли я сделать так, чтобы он не попадал по URL-адресу https://externalprovider/oauth2/auth только для этого пути?

Я пробовал использовать ingress.kubernetes.io/configuration-snippet, чтобы установить auth_basi c в значение «off», но похоже, что это связано с базовыми c директивами auth, а не с внешними.

Ответы [ 2 ]

1 голос
/ 21 июля 2020

Мой эксперимент показал, что не обязательно иметь два ingress-controllers подобных Crou , упомянутых в предыдущем ответе.

Один Nginx ingress-controller и два Ingress objects - это просто

Эксперимент не охватывал все решение: провайдер аутентификации не был развернут, поэтому мы увидим только запрос аутентификации, но для проверки части Ingress в этом нет необходимости.

Вот подробности [TL; DR]:

Ingress-controller был развернут в соответствии с официальным руководством .

Оба my1service и my2service перенаправляют трафик c в тот же Nginx Pod.

Я также добавил rewrite-target аннотацию , потому что мой целевой Pod обслуживает контент только по пути /.

Ingress1:

apiVersion: extensions/v1beta1 
kind: Ingress
metadata:
  name: myingress1
  annotations:
    nginx.ingress.kubernetes.io/auth-signin: https://externalprovider/oauth2/sign_in
    nginx.ingress.kubernetes.io/auth-url: https://externalprovider/oauth2/auth
    nginx.ingress.kubernetes.io/auth-request-redirect: https://myapp/context_root/
    nginx.ingress.kubernetes.io/auth-response-headers: X-Auth-Request-User, X-Auth-Request-Email, X-Auth-Request-Access-Token, Set-Cookie, Authorization
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: myhost.com
    http:
      paths:
      - backend: 
          serviceName: my1service
          servicePort: 80
        path: /

Ingress2 :

apiVersion: extensions/v1beta1 
kind: Ingress
metadata:
  name: myingress2
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: myhost.com
    http:
      paths:
      - backend: 
          serviceName: my2service
          servicePort: 80
        path: /somepath

Применение их к кластеру дает нам следующую конфигурацию ingress-controller: (я пропустил неважные строки из содержимого nginx .conf)

Как мы видим, для каждого местоположения используется разный набор правил, поэтому для некоторых path и пропустить аутентификацию для другого или даже иметь разных поставщиков аутентификации для разных мест на одном HTTP-узле.

ingress-controller's nginx .conf:

$ kubectl exec -n ingress-nginx ingress-nginx-controller-7fd7d8df56-xx987 -- cat /etc/nginx/nginx.conf > nginx.conf
$ less nginx.conf

http {
        
        ## start server myhost.com
        server {
                server_name myhost.com ;
                
                location /somepath {
                        # this location doesn't use authentication and responds with the backend content page.
                        
                        set $namespace      "default";
                        set $ingress_name   "myingress2";
                        set $service_name   "my2service";
                        set $service_port   "80";
                        set $location_path  "/somepath";
                        
                        set $proxy_upstream_name "default-my2service-80";
                        set $proxy_host          $proxy_upstream_name;
                        set $pass_access_scheme  $scheme;
                        
                }
                
                location = /_external-auth-Lw {
                        internal;
                        
                        # this location is used for executing authentication requests
                        
                        set $proxy_upstream_name "default-my1service-80";

                        proxy_set_header            Host                    externalprovider;
                        proxy_set_header            X-Original-URL          $scheme://$http_host$request_uri;
                        proxy_set_header            X-Original-Method       $request_method;
                        proxy_set_header            X-Sent-From             "nginx-ingress-controller";
                        proxy_set_header            X-Real-IP               $remote_addr;
                        
                        proxy_set_header            X-Forwarded-For        $remote_addr;
                        
                        proxy_set_header            X-Auth-Request-Redirect https://myapp/context_root/;
                        
                        set $target https://externalprovider/oauth2/auth;
                        proxy_pass $target;
                }
                
                location @64e7eef73f135f7a304693e85336f805005c5bc2 {
                        internal;
                        
                        # this location suppose to return authentication error page
                        
                        add_header Set-Cookie $auth_cookie;
                        
                        return 302 https://externalprovider/oauth2/sign_in?rd=$pass_access_scheme://$http_host$escaped_request_uri;
                }
                
                location / {
                        
                        # this location requests for authentication from external source before returning the backend content
                        
                        set $namespace      "default";
                        set $ingress_name   "myingress1";
                        set $service_name   "my1service";
                        set $service_port   "80";
                        set $location_path  "/";
                        
                        
                        set $balancer_ewma_score -1;
                        set $proxy_upstream_name "default-my1service-80";
                        set $proxy_host          $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;
                        
                        set $proxy_alternative_upstream_name "";
                        
                        # this location requires authentication
                        auth_request        /_external-auth-Lw;
                        auth_request_set    $auth_cookie $upstream_http_set_cookie;
                        add_header          Set-Cookie $auth_cookie;
                        auth_request_set $authHeader0 $upstream_http_x_auth_request_user;
                        proxy_set_header 'X-Auth-Request-User' $authHeader0;
                        auth_request_set $authHeader1 $upstream_http_x_auth_request_email;
                        proxy_set_header 'X-Auth-Request-Email' $authHeader1;
                        auth_request_set $authHeader2 $upstream_http_x_auth_request_access_token;
                        proxy_set_header 'X-Auth-Request-Access-Token' $authHeader2;
                        auth_request_set $authHeader3 $upstream_http_set_cookie;
                        proxy_set_header 'Set-Cookie' $authHeader3;
                        auth_request_set $authHeader4 $upstream_http_authorization;
                        proxy_set_header 'Authorization' $authHeader4;
                        
                        set_escape_uri $escaped_request_uri $request_uri;
                        error_page 401 = @64e7eef73f135f7a304693e85336f805005c5bc2;
                        
                        
                }
                
        }
        ## end server myhost.com
        
}

Давайте проверим, как это все работает:

# ingress-controller IP address is 10.68.0.8

# here I requested / path and internal error and 'externalprovider could not be resolved (3: Host not found)' 
# error tells us that authentication was required, but auth backend is not available. 
# It's expected.

master-node$ curl http://10.68.0.8/ -H "Host: myhost.com"
<html>
<head><title>500 Internal Server Error</title></head>
<body>
<center><h1>500 Internal Server Error</h1></center>
<hr><center>nginx/1.19.1</center>
</body>
</html>

#controller logs:
$ kubectl logs -n ingress-nginx ingress-nginx-controller-7fd7d8df56-xx987

10.68.0.1 - - [21/Jul/2020:13:17:06 +0000] "GET / HTTP/1.1" 502 0 "-" "curl/7.47.0" 0 0.072 [default-my1service-80] [] - - - - 158e2f959af845b216c399b939d7c2b6
2020/07/21 13:17:06 [error] 689#689: *119718 externalprovider could not be resolved (3: Host not found), client: 10.68.0.1, server: myhost.com, request: "GET / HTTP/1.1", subrequest: "/_external-auth-Lw", host: "myhost.com"
2020/07/21 13:17:06 [error] 689#689: *119718 auth request unexpected status: 502 while sending to client, client: 10.68.0.1, server: myhost.com, request: "GET / HTTP/1.1", host: "myhost.com"
10.68.0.1 - - [21/Jul/2020:13:17:06 +0000] "GET / HTTP/1.1" 500 177 "-" "curl/7.47.0" 74 0.072 [default-my1service-80] [] - - - - 158e2f959af845b216c399b939d7c2b6

# Then I sent a request to /somepath and got a reply without necessity 
# to provide any auth headers. 

$ curl http://10.68.0.8/somepath -H "Host: myhost.com"
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
</body>
</html>

#controller logs show the successful reply:
10.68.0.1 - - [21/Jul/2020:13:18:29 +0000] "GET /somepath HTTP/1.1" 200 612 "-" "curl/7.47.0" 82 0.002 [default-my2service-80] [] 10.68.1.3:80 612 0.004 200 3af1d3d48c045be160e2cee8313ebf42

0 голосов
/ 03 июля 2020

Поскольку у вас уже есть ingress, а путь равен /, не будет возможности отключить базовую c авторизацию на вашем https://externalprovider/oauth2/auth.

Для лучшего объяснения, пожалуйста обратитесь к ответу, предоставленному @ VAS ниже .

Для этого вам необходимо настроить другой ingress и настроить его, чтобы отключить basi c авт. Вы также можете проверить этот вопрос в стеке Два контроллера входа в одном кластере K8S и этот Kubernetes NGINX Ingress: отключить внешнюю аутентификацию для указанного c пути .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...