ingress-nginx: ssl-passthrough returning ingress cert

Is this a request for help? Yes

What keywords did you search in NGINX Ingress controller issues before filing this one? grpc ssl-passthrough ingress


Is this a BUG REPORT or FEATURE REQUEST? bug?

NGINX Ingress controller version: 0.10.0

Kubernetes version (use kubectl version):

Client Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.1", GitCommit:"3a1c9449a956b6026f075fa3134ff92f7d55f812", GitTreeState:"clean", BuildDate:"2018-01-04T11:52:23Z", GoVersion:"go1.9.2", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"7+", GitVersion:"v1.7.11-gke.1", GitCommit:"3500f53730c1fea7b57901977df165c3eb317bce", GitTreeState:"clean", BuildDate:"2017-12-08T18:05:07Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/amd64"}

Environment:

  • Cloud provider or hardware configuration: GKE

What happened: openssl s_client returns cert default ingress cert

What you expected to happen: openssl s_client returns cert from application

How to reproduce it (as minimally and precisely as possible):

Ingress controller, there is another ingress that does not use ssl-passthrough that comes after this one, there is no overlap in the hosts

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: grpc-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/ssl-passthrough: "true"
spec:
  rules:
  - host: rpc.host.tld
    http:
      paths:
      - backend:
          serviceName: svc-grpc
          servicePort: 443
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: gateway-ingress
  annotations:
    # set for letsencrypt support
    kubernetes.io/tls-acme: "true"
    kubernetes.io/ingress.class: "nginx"
spec:
  tls:
  - hosts:
    - api.host.tld
    secretName: api-tls
  rules:
  - host: api.host.tld
    http:
      paths:
      - backend:
          serviceName: gateway
          servicePort: 8080

Service for this. The application’s gRPC server is listening on 443 as well (previosuly this service forwarded 443 to 10000, changed the gRPC listening port to tes if that was the issue)

apiVersion: v1
kind: Service
metadata:
  name: svc-grpc
  labels: ...
spec:
  ports:
  - name: grpc-proxy-port
    port: 443
    targetPort: 443
  selector: ...

To test that the application and service were set up right, I set the service to type: LoadBalancer and ran openssl s_client against the service’s IP directly and the correct cert was returned

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 33 (4 by maintainers)

Most upvoted comments

I found out you need to add annotation

nginx.ingress.kubernetes.io/secure-backends: "true"

It feels like I’m running into this issue.

Here’s my (non-working) ingress.yaml:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    nginx.ingress.kubernetes.io/server-alias: ".domain.tld"
    # nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
    nginx.ingress.kubernetes.io/ssl-passthrough: "true"
spec:
  rules:
  - host: "domain.tld"
    http:
      paths:
      - backend:
          serviceName: my-service
          servicePort: 443

The weird thing is, when I remove the server-alias and instead define the subdomains individually I’m getting the correct certificate that is presented by my-service. I have tried to remove the forced (or unforced) SSL redirect that happens automagically (see commented nginx.ingress.kubernetes.io/force-ssl-redirect: "false") but to no avail.

[EDIT] I have double-checked and verified that the nginx ingress controller has the --enable-ssl-passthrough flag. The second part would not work otherwise (as to my understanding, anyway) [/EDIT]]

So, this is a working configuration (certificate is coming from the my-service):

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    # nginx.ingress.kubernetes.io/server-alias: ".domain.tld"
    # nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
    nginx.ingress.kubernetes.io/ssl-passthrough: "true"
spec:
  rules:
  - host: "sub.domain.tld"
    http:
      paths:
      - backend:
          serviceName: my-service
          servicePort: 443

But since I have many subdomains I would rather not have to list each of them in the ingress. This would be a nightmare to maintain.

[EDIT #2] I’m using RKE to provision my cluster and the Docker image for the nginx ingress controller is rancher/nginx-ingress-controller:nginx-0.25.1-rancher1. It looks like the used version is some month behind official releases? [/EDIT]

[EDIT #3] I have removed the RKE nginx-ingress controller and have it replaced with the official helm chart stable/nginx-ingress. Yet the results are the same. [/EDIT]

Secure backends DEPRECATED (since 0.18.0) nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" replaced, and removed 0.21.0

https://github.com/kubernetes/ingress-nginx/blob/nginx-0.20.0/docs/user-guide/nginx-configuration/annotations.md#secure-backends-deprecated-since-0180

I have tested TLS passthrough with 0.10.1 and 0.10.2 versions and TLS passthrough does not work. Although TLS passthrough works with 0.9.0-beta.17 version. I am 100% certain that #1947 is not fixed with 0.10.1 and 0.10.2. Please reopen #1947

@paulbdavis are you using openssl s_client -servername rpc.host.tld?

I suppose it was, but my setup has since magically started to work fine! Thank you for the reply!

I’m seeing similar behavior to @sands6. Works on version 0.9.0-beta.17 but broken on 0.10.1.

On version 0.10.1 I get a 400 error on the backend: The plain HTTP request was sent to HTTPS port and the default ingress cert is returned to the client.

Environment: AWS

$ kubectl version
Client Version: version.Info{Major:"1", Minor:"8", GitVersion:"v1.8.7", GitCommit:"b30876a5539f09684ff9fde266fda10b37738c9c", GitTreeState:"clean", BuildDate:"2018-01-16T21:59:57Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"8+", GitVersion:"v1.8.4+coreos.0", GitCommit:"4292f9682595afddbb4f8b1483673449c74f9619", GitTreeState:"clean", BuildDate:"2017-11-21T17:22:25Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/amd64"}

Ingress controller args:

      containers:
        - name: nginx-ingress-lb
          #image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.10.1
          image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.9.0-beta.17
          args:
          - /nginx-ingress-controller
          - --configmap=$(POD_NAMESPACE)/ingress-controller-config
          - --default-backend-service=$(POD_NAMESPACE)/default-http-backend
          - --publish-service=$(POD_NAMESPACE)/test-lb
          - --enable-ssl-passthrough

Ingress object:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx
  namespace: test
  annotations:
    ingress.kubernetes.io/ssl-passthrough: "true"
spec:
  tls:
  - hosts:
    - nginx.example.com
  rules:
  - host: nginx.example.com
    http:
      paths:
      - backend:
          serviceName: nginx
          servicePort: 443

Backend nginx deployment, service:

apiVersion: v1
kind: Service
metadata:
  name: nginx
  namespace: test
  labels:
    app: nginx
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
    name: http
  - port: 443
    targetPort: 443
    protocol: TCP
    name: https
  selector:
    app: nginx
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: nginx
  namespace: test
spec:
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nginx
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: nginx:1.13.8
        imagePullPolicy: "IfNotPresent"
        ports:
        - name: http
          containerPort: 80
        - name: https
          containerPort: 443
        livenessProbe:
          httpGet:
            path: /index.html
            port: 80
          initialDelaySeconds: 30
          timeoutSeconds: 1
          failureThreshold: 6
        readinessProbe:
          httpGet:
            path: /index.html
            port: 80
          initialDelaySeconds: 30
          timeoutSeconds: 1
          failureThreshold: 6
        resources:
          limits:
            memory: 512Mi
            cpu: 200m
          requests:
            cpu: 100m
            memory: 256Mi
        volumeMounts:
        - mountPath: /etc/nginx/conf.d
          name: configmap
        - mountPath: /etc/nginx/ssl
          name: tls
      volumes:
      - name: configmap
        configMap:
          name: nginx-config
          defaultMode: 0744
      - name: tls
        secret:
          secretName: nginx-tls

All issues fixed, thanks for the quick response