openziti / zrok

Geo-scale, next-generation peer-to-peer sharing platform built on top of OpenZiti.
https://zrok.io
Apache License 2.0
2.53k stars 99 forks source link

TLS passthrough support #387

Closed pmalek closed 1 year ago

pmalek commented 1 year ago

Problem statement

Trying to share a TLS endpoint e.g. a kubernetes cluster control plane like so:

$ k cluster-info
Kubernetes control plane is running at https://127.0.0.1:50930
CoreDNS is running at https://127.0.0.1:50930/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

$ zrok share public https://127.0.0.1:50930 --headless
...

And then trying to access the cluster via the zrok share URL, I'm getting

I0812 11:23:45.458003   79414 helpers.go:264] Connection error: Get https://ibmpditqijja.share.zrok.io/api?timeout=32s: tls: failed to verify certificate: x509: certificate signed by unknown authority

Proposed solution

I believe that supporting TLS passthrough would resolve this use case.

michaelquigley commented 1 year ago

As a workaround you can do one of two things:

zrok share public <address> --headless --insecure

The --insecure flag will disable TLS certificate validation.

Or, you can use a --backend-mode tcpTunnel and expose your TLS endpoint that way... but that will not work in a public context.

pmalek commented 1 year ago

I've tried --insecure but that still reports Unable to connect to the server: x509: certificate signed by unknown authority

zrok share public https://127.0.0.1:51463 --headless --insecure
[   1.607]    INFO main.(*sharePublicCommand).run: access your zrok share at the following endpoints:
 https://sssss7yslw1.share.zrok.io
[   1.766]    INFO sdk-golang/ziti.(*listenerManager).createSessionWithBackoff: {session token=[sssssssssssssssssssssss]} new service session
k config view  --minify --raw | yq '.clusters[0].cluster.server = "https://sssss7yslw1.share.zrok.io"' > /tmp/kubeconfig ; KUBECONFIG=/tmp/kubeconfig k cluster-info
E0828 11:25:29.618509   35507 memcache.go:238] couldn't get current server API group list: Get "https://sssss7yslw1.share.zrok.io/api?timeout=32s": x509: certificate signed by unknown authority

I then discovered that I can use --insecure-skip-tls-verify at the client but still I'm getting some errors due to authentication

$ k config view  --minify --raw | yq '.clusters[0].cluster.server = "https://sssss7yslw1.share.zrok.io"' > /tmp/kubeconfig ; KUBECONFIG=/tmp/kubeconfig k --insecure-skip-tls-verify=true get pods -v9
I0828 11:39:36.171181   38337 request.go:1154] Response Body: {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"forbidden: User \"system:anonymous\" cannot get path \"/api\"","reason":"Forbidden","details":{},"code":403}

But that is a different problem.

michaelquigley commented 1 year ago

That x509 error appears to be coming from your client, so --insecure wouldn't help with that. That makes sense.

So you're past connectivity issues and into application issues now, correct?

pmalek commented 1 year ago

I might be yes 🤔 Guess there's not much that can be done for my use case here

michaelquigley commented 1 year ago

Naively it looks like you just need to figure out how to authenticate with your application?

pmalek commented 1 year ago

I believe so. Perhaps there's more to it than I thought I believe we can close this one

michaelquigley commented 1 year ago

If you did want to try passthrough of TLS, you could share your service using zrok share private --backend-mode tcpTunnel, and then access it using a local zrok access private... you would then have a local port that passes TLS through to your service without any HTTP proxying.

Wondering if maybe your service is doing authentication using a client cert or something?

pmalek commented 1 year ago

Wondering if maybe your service is doing authentication using a client cert or something?

It does, the authentication is cert based. That could be a problem with the host that's used wouldn't it?

michaelquigley commented 1 year ago

That's not going to work with public share. I would try using zrok share private --backend-mode tcpTunnel and using zrok access private to access it. I would bet that would give you a better result.