Kubernetes Ingress Nginx and AWS API Gateway client certificate

4/7/2018

I have an AWS API Gateway and an Ingress Nginx.

I want my Ingress to only accept trafic from the API Gateway : so I have used the AWS API Gateway client certificate.

I've created the secret of the client certificate :

kubectl create secret generic api --from-file=api-gateway-client-certificate.crt

My Ingress Service has the following configuration (it's a TCP AWS classic ELB):

kind: Service
apiVersion: v1
metadata:
  name: ingress-nginx
  namespace: ingress
  labels:
    app: ingress-nginx
  annotations:
    ingress.kubernetes.io/server-alias: 'dev.ingress.website.com'
    service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: '3600'
    service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*"
spec:
  type: LoadBalancer
  selector:
    app: ingress-nginx
  ports:
  - name: https
    port: 443
    targetPort: http

And my Ingress rule looks like that :

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/auth-tls-verify-client: "on"
    nginx.ingress.kubernetes.io/auth-tls-secret: "default/api"
    nginx.ingress.kubernetes.io/auth-tls-verify-depth: "1"
  name: items
spec:
    tls:
    - hosts:
      - dev.ingress.website.com
      secretName: ingress-website-com-tls
    rules:
    - host: dev.ingress.website.com
      http:
        paths:
        - backend:
            serviceName: items
            servicePort: 80
          path: "/items"

But it doesn't work. I can access dev.ingress.website.com/items from my browser : only the API Gateway should have access.

Here is the output of the nginx.conf :

location /items {

            if ($scheme = https) {
            more_set_headers                        "Strict-Transport-Security: max-age=15724800; includeSubDomains;";
            }

            port_in_redirect off;

            set $proxy_upstream_name "default-items-80";

            set $namespace      "default";
            set $ingress_name   "items";
            set $service_name   "items";

            # enforce ssl on server side
            if ($redirect_to_https) {

                return 308 https://$best_http_host$request_uri;

            }


            proxy_set_header Host                   $best_http_host;

            # Pass the extracted client certificate to the backend

            proxy_set_header ssl-client-cert        "";
            proxy_set_header ssl-client-verify      "";
            proxy_set_header ssl-client-dn          "";

It's seems that ssl-client-cert and ssl-client-verify are empty. So I guess it's because of that ?

But I can't figure out why. Does anyone has insight about how to fix it ?

Thanks in advance ! J.

-- J. Doe
aws-api-gateway
kubernetes
kubernetes-ingress
nginx

1 Answer

5/17/2018

I had the same scenario in Azure so I ended up running ingress with Internal LB ... placing the Api GW in the same VNET so I can access. I think this is an overhead anyways.

-- Hugo Marcelo Del Negro
Source: StackOverflow