haproxytech / kubernetes-ingress

HAProxy Kubernetes Ingress Controller
https://www.haproxy.com/documentation/kubernetes/
Apache License 2.0
718 stars 201 forks source link

auth-tls equivalent for client side mtls? #438

Open fbdlampayan opened 2 years ago

fbdlampayan commented 2 years ago

Hi,

We are currently considering migrating from https://github.com/jcmoraisjr/haproxy-ingress to haproxytech.

Across our Ingress resources we have endpoints that use mTLS towards the clients while other clients are via plain TLS only. For mTLS Ingresses we are using the auth-tls-secret configuration key that binds the ca.crt checking at Host level... Is there any equivalent here in haproxytech?

The closest that we can find is client-ca but this is in configMap level that will affect all the Ingress resources.

ivanmatmati commented 2 years ago

Hi @fbdlampayan , Yes, the closest annotation to your need is indeed client-ca. Unfortunately this annotation is only applicable at global level.

Mo3m3n commented 2 years ago

@fbdlampayan Can you provide what a haproxy configuration binding ca.crt at Host level would look like ? AFAIK mTLS happens before receiving any http request so I don't see how we can bind a ca.crt to a Host header. Maybe with jcmoraisjr/haproxy-ingress you can add a ca.crt per host but in the end the controller will bundle all certificates in single ca.crt and use it in the main frontend so it is going to be used to every incoming connection requiring mTLS

fbdlampayan commented 2 years ago

@ivanmatmati I see, thank you for the confirmation!

@Mo3m3n the resulting bundled ca.crt is fine, rather concern is whether haproxytech is capable of selectively making specific Ingress into client-side mTLS while others remain TLS. So far, the understanding is that by using client-ca then all Ingresses served by haproxytech will become client-side mTLS.

with jcmoraisjr/haproxy-ingress this is done by putting annotations auth-tls-verify-client and auth-tls-secret on the Ingress definition... exclusively making that Ingress definition containing such annotations into client-side mTLS while others can remain being plain TLS. --- is something like this feasible with haproxytech at the moment?

Example configs below /1/ where:

/1/

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: foo-ingress
  annotations:
      kubernetes.io/ingress.class: "haproxy"
spec:
  tls:
  - hosts:
      - foo.server.com
    secretName: foo-tls-keypair
  rules:
  - host: foo.server.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: foo-service
            port:
              number: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: bar-ingress
  annotations:
      kubernetes.io/ingress.class: "haproxy"
      haproxy-ingress.github.io/auth-tls-verify-client: "on"  # enforcing mTLS for bar.server.com
      haproxy-ingress.github.io/auth-tls-secret: "bar-trusted-ca" # contains trusted ca that signed client cert
spec:
  tls:
  - hosts:
      - bar.server.com
    secretName: bar-tls-keypair
  rules:
  - host: bar.server.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: bar-service
            port:
              number: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: baz-ingress
  annotations:
      kubernetes.io/ingress.class: "haproxy"
      haproxy-ingress.github.io/auth-tls-verify-client: "on"   # enforcing mTLS for baz.server.com
      haproxy-ingress.github.io/auth-tls-secret: "baz-trusted-ca"  # contains trusted ca that signed client cert
spec:
  tls:
  - hosts:
      - baz.server.com
    secretName: baz-tls-keypair
  rules:
  - host: baz.server.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: baz-service
            port:
              number: 8080

/2/ outputs. where in mTLS ingresses, request never reaches the backend/server-app pod and client receives back 496 error.

fbdl@fbdl-VirtualBox:~/Desktop/mtls/client$ curl -k https://foo.server.com
Hello, world!

fbdl@fbdl-VirtualBox:~/Desktop/mtls/client$ curl -k https://bar.server.com
<html><body><h1>496 SSL Certificate Required</h1>
A client certificate must be provided.
</body></html>

fbdl@fbdl-VirtualBox:~/Desktop/mtls/client$ curl -k https://baz.server.com
<html><body><h1>496 SSL Certificate Required</h1>
A client certificate must be provided.
</body></html>
Mo3m3n commented 2 years ago

@fbdlampayan thanks for the clarification. So this is using the haproxy crt-list feature under the hood, which makes it possible to have different TLS behaviors based on the matched SNI (which is equivalent here to the host in the ingress resource). Unfortunately this is not supported for haproxytech Ingress Controller and definitely a good feature to add to the road map.

fbdlampayan commented 2 years ago

@Mo3m3n okay, thank you as well for the confirmation! How shall we proceed with this thread? Shall I keep it open and rename as a "feature request" to be considered for the road map?

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

DmitryMigunov commented 2 years ago

Can you add this feature to the road map? We are migrating from Nginx ingress and the lack of this feature is stopping us from completing the migration.

oktalz commented 2 years ago

I've added enhancement label so it won't go to stale state anymore. we will add it to the roadmap

adriannieto-attechnest commented 1 year ago

Any update on mTLS settings per frontend? This seems to be a big restriction as we need to configure something like previously mentioned:

foo.server.com = TLS bar.server.com = mTLS baz.server.com = mTLS

jisnardo commented 3 months ago

Hi @ivanmatmati, we are waiting too to have Client Certificate Authentication available at ingress level to migrate from Ingress Nginx, any update? Thanks in advance.

https://www.haproxy.com/documentation/haproxy-runtime-api/reference/add-ssl-ca-file/#verify-client-certificates

https://github.com/haproxytech/kubernetes-ingress/blob/master/documentation/annotations.md#client-ca

https://github.com/jcmoraisjr/haproxy-ingress/tree/master/examples/auth/client-certs