【问题标题】:Kubernetes NGINX Ingress: Disable external auth for specific pathKubernetes NGINX Ingress:禁用特定路径的外部身份验证
【发布时间】:2020-10-07 19:38:49
【问题描述】:

我希望能够为我的应用程序的特定路径禁用外部授权。

与此类似:Kubernetes NGINX Ingress: Disable Basic Auth for specific path

唯一的区别是使用外部身份验证提供程序(通过 Microsoft Azure 进行 OAuth),并且有一个

这是公众应该可以到达的路径

/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: /

我可以让它不点击https://externalprovider/oauth2/auth url 吗?

我尝试使用 ingress.kubernetes.io/configuration-sn-p 将 auth_basic 设置为“off”,但这似乎与基本身份验证指令相关联,而不是外部指令。

【问题讨论】:

  • 尝试设置第二个ingress,它只配置用于禁用身份验证的路径。
  • @Crou 最终成为了解决方案。如果您添加为答案,可以将其标记为这样
  • 我已经发布了答案,如果您需要任何其他信息,请询问。

标签: nginx kubernetes oauth-2.0 kubernetes-ingress


【解决方案1】:

因为您已经有ingress 并且路径是/,所以无法在您的https://externalprovider/oauth2/auth 上禁用基本身份验证。

最好的解释请参考@VASbellow提供的答案。

为此,您需要设置另一个 ingress 并将其配置为禁用基本身份验证。 你也可以在 Stack Two ingress controller on same K8S cluster 和这个Kubernetes NGINX Ingress: Disable external auth for specific path 上查看这个问题。

【讨论】:

    【解决方案2】:

    我的实验表明不需要像上一个答案中提到的Crou那样有两个ingress-controllers

    一个 Nginx ingress-controller 和两个 Ingress objects 就足够了。

    该实验并未涵盖整个解决方案:未部署身份验证提供程序,因此我们只会看到身份验证请求,但对于检查 Ingress 部分,这并不是真正必要的。


    以下是详细信息 [TL;DR]:

    Ingress-controller是按照官方manual部署的。

    my1servicemy2service 都将流量转发到同一个 Nginx Pod。

    我还添加了 rewrite-target annotation,因为我的目标 Pod 仅在路径 / 上提供内容。

    入口1:

    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 内容中跳过了不重要的行)

    正如我们在此处看到的,每个位置使用不同的规则集,因此可以为某个路径设置身份验证,而为另一个路径跳过身份验证,甚至在同一 HTTP 主机上为不同位置设置不同的身份验证提供程序.

    ingress-controller 的 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
    
    

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题,我在 ingress.yaml 文件中添加了下面的 sn-p 代码及其工作。

      nginx.ingress.kubernetes.io/auth-snippet: | 
          if ( $request_uri = "/nonmember" ) {
              return 200;
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-11-30
        • 2021-05-03
        • 1970-01-01
        • 2019-10-08
        • 2021-05-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多