Workarounds for mixed HTTPS/TLS ingress on a listener?

The use case:

We have a service that listens on port 443 with a self-signed certificate. Replacing this with Istio mTLS is not viable because clients external to the cluster/Istio mesh need to connect and both present a client certificate and verify the one served. Port 443 can also receive “browser” traffic, which does not require a client certificate.

Because Istio, at least as of 1.1.1, does not currently support mixed TLS-passthrough and terminating HTTPS on the same listener (0.0.0.0_443) even with different SNIs, if we connections using the “public” SNI to serve a browser-friendly certificate, it seems like we’re limited to the following options for now:

  1. Create a separate ingressgateway deployment/service for the second type of connection.
  2. Use TLS passthrough at the gateway for all incoming connections, pass them to some sort of proxy service running in the mesh that can either terminate TLS or do passthrough to the end service as needed. (haproxy maybe?)

Are there other options? What about using an EnvoyFilter on the ingressgateway with an sni_cluster match, either terminating and reconnecting via HTTPS SIMPLE or doing TLS PASSTHROUGH based on the SNI value? Is that a possibility?

This doesn’t have to be production-grade at this point, but it does need to work more or less. Eventually I’d hope Istio would just handle mixed TLS/HTTPS listeners natively.

In Istio’s authentication config language, what you’re talking about is an “origin” authentication method of client certificates minted outside Istio. @diemtvu have you given any thought to supporting this use case?

I’m not as worried about importing the self-signed cert into the ingress, unless that would help work around the listener issue. If so, great. We still want a different certificate for the public, browser endpoint with an SNI that matches the DNS entry, which will generally be independent of the self-signed certificate CN for various reasons.

I think the common pattern we have at the moment is having external traffic go to through ingress-gateway, inside the mesh, everything use mTLS only. More or less this is the same as option 1. Does it cause any trouble for you?

The app is issuing its own client certs to clients because most of them are not in the same cluster/service mesh. They’re used for identification of the data being sent, so they cannot be replaced.

I don’t really want to remove the service completely from the istio mesh, whether by selectively turning off sidecar injection or disabling mTLS auth, because we need to run in on Istio somehow and I’d like to be able to get some benefit from the telemetry, but from my experiments and reading, it sounds like there’s no simple alternative to get both the TLS passthrough and TLS termination/origination to the HTTPS backend working simultaneously.

Does the same port for PASSTHROUGH and HTTPS not work?

@karen can you provide a sample config that you would expect to work ? I am trying to understand the resulting envoy configuration that would be required to support your use case. We can then work our way backwards to the api.