skip to Main Content

I am adding the external authentication using auth-url annotation. How to set conditional request headers for the auth-url api which depends on incoming calls? Can I set the request headers in nginx controller according to incoming calls?

Edited:

Hi,
This is about adding a custom header(Id) which is expected into auth-url. I am setting the Id header which is required in authorize api of auth-url but not receiving in the api. Is this the right method to set? My next question is If it is set how can I set it conditionally depending on from which host server the request is coming through?

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: hello-kubernetes-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/auth-url:  http://ca6dd3adc439.ngrok.io/authorize
    nginx.ingress.kubernetes.io/auth-method: POST
    nginx.ingress.kubernetes.io/auth-snippet: |
      proxy_set_header Id "queryApps";
spec:
  rules:
  - host: "hw1.yourdomain"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          serviceName:  hello-netcore-k8s
          servicePort: 80
  - host: "hw2.yourdomain"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          serviceName: hello-kubernetes-second
          servicePort: 80


 

2

Answers


  1. Your question is not pretty clear so I assume that it was something related to authentication and header injection. For NGINX ingress, there are a couple ways for you to setup the authentication. The second ways in the following will talk about the header injection.

    The first method will be the easiest one. You simply setup the secret and the annotation on the ingress.

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: auth-ingress
      annotations:
        nginx.ingress.kubernetes.io/auth-secret: my-secret
        nginx.ingress.kubernetes.io/auth-type: basic
    spec:
      rules:
      - http:
          paths:
          - path: /auth-url
            backend:
              service:
                name: test
                port:
                  number: 80
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: normal-ingress
    spec:
      rules:
      - http:
          paths:
          - path: /
            backend:
              service:
                name: test
                port:
                  number: 80
    

    The second one will be more complicated but it will be useful if you do your authentication with a particular header. You can inject the snippet of NGINX configuration to the ingress. Of course, if you want to do more manipulation like header adding, you can do it in this way as well.

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: auth-ingress
      annotations:
        nginx.ingress.kubernetes.io/server-snippet: |
            if ( $some_condtion ) {
              return 403;
            }
    spec:
      rules:
      - http:
          paths:
          - path: /auth-url
            backend:
              service:
                name: test
                port:80
    
    Login or Signup to reply.
  2. My next question is If it is set how can I set it conditionally depending on from which host server the request is coming through?

    The best way would be to create two ingress objects with one where the external auth enabled for host hw1.yourdoman. For some reason while testing this the auth-snippet was not passing the header but with it works fine with configuration-snippet:

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: hello-kubernetes-ingress-auth-on
      annotations:
        kubernetes.io/ingress.class: nginx
        nginx.ingress.kubernetes.io/auth-url:  http://ca6dd3adc439.ngrok.io/authorize
        nginx.ingress.kubernetes.io/auth-method: POST
        nginx.ingress.kubernetes.io/configuration-snippet:  |
           proxy_set_header Id  "queryApps";
    spec:
      rules:
      - host: "hw1.yourdomain"
        http:
          paths:
          - pathType: Prefix
            path: "/"
            backend:
              serviceName:  hello-netcore-k8s
              servicePort: 80
    

    As you can see here it passes the desired header:

      "path": "/",
      "headers": {
        "host": "hw1.yourdomain",
        "x-request-id": "5e91333bed960802a67958d71e787b75",
        "x-real-ip": "192.168.49.1",
        "x-forwarded-for": "192.168.49.1",
        "x-forwarded-host": "hw1.yourdomain",
        "x-forwarded-port": "80",
        "x-forwarded-proto": "http",
        "x-scheme": "http",
        "id": "queryApps",
        "user-agent": "curl/7.52.1",
        "accept": "*/*"
      },
      "method": "GET",
      "body": "",
      "fresh": false,
    

    Moving on, the second ingress object has to be configured the auth disabled for host hw2.yourdomain:

    
    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: hello-kubernetes-ingress-auth-off
      annotations:
        kubernetes.io/ingress.class: nginx
    spec:
      rules:
      - host: "hw2.yourdomain"
        http:
          paths:
          - pathType: Prefix
            path: "/"
            backend:
              serviceName: hello-kubernetes-second
              servicePort: 80
    

    You can then have a look at the nginx.conf to check how the those two ingresss objects are configure at controller level. This is the first ingress:

           ## start server hw1.yourdomain
            server {
                    server_name hw1.yourdomain ;
    
                    listen 80  ;
                    listen 443  ssl http2 ;
    
               set $proxy_upstream_name "-";
                    
                    location = /_external-auth-Lw {
                            internal;
    
              set $proxy_upstream_name "default-hello-netcore-k8s-80";
    
                 hello-netcore-k8s.default.svc.cluster.local;
                 proxy_set_header            X-Original-URL          $scheme://$http_host$request_uri;
    --------
    --------
                            # Pass the extracted client certificate to the auth provider
    
                            set $target http://hello-netcore-k8s.default.svc.cluster.local;
                            proxy_pass $target;
                   location / {
    
                            set $namespace      "default";
                            set $ingress_name   "hello-kubernetes-ingress-auth-on";
                            set $service_name   "hello-netcore-k8s";
                            set $service_port   "80";
                            set $location_path  "/";
    
    
                            set $balancer_ewma_score -1;
                            set $proxy_upstream_name "default-hello-netcore-k8s-80";
    
                            # this location requires authentication
                            auth_request        /_external-auth-Lw;
                            auth_request_set    $auth_cookie $upstream_http_set_cookie;
                            add_header          Set-Cookie $auth_cookie;
    
    
                            # mitigate HTTPoxy Vulnerability
                            # https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/
                            proxy_set_header Proxy                  "";
    
                            # Custom headers to proxied server
    --------
                            proxy_set_header Id "queryApps";
    ----
    

    And this is the second one:

            ## start server hw2.yourdomain
            server {
                    server_name hw2.yourdomain ;
    
                    listen 80  ;
                    listen 443  ssl http2 ;
    
                    set $proxy_upstream_name "-";
    
                    ssl_certificate_by_lua_block {
                            certificate.call()
                    }
    
                    location / {
    
                            set $namespace      "default";
                            set $ingress_name   "hello-kubernetes-ingress-auth-off";
                            set $service_name   "hello-kubernetes-second";
                            set $service_port   "80";
                            set $location_path  "/";
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search