dexidp / dex

OpenID Connect (OIDC) identity and OAuth 2.0 provider with pluggable connectors
https://dexidp.io
Apache License 2.0
9.38k stars 1.68k forks source link

Redirect to HTTPS breaks K8s/Istio sidecar model #1593

Open mabushey opened 4 years ago

mabushey commented 4 years ago

I would like to run Dex in my K8s cluster with Istio. I only wish to use Dex to provide LDAP authentication to some applications. The only way in to the cluster besides a reverse SSH tunnel + k8s cert is through the Istio gateway which is an AWS ELB. Port 80 is immediately redirected to 443. I would like to call Dex internal to the cluster, which is non SSL. It appears that the only way I can do this is to route outside my cluster to the open Internet to the external LB. Forcing my traffic onto the Internet is less secure and considerably more cumbersome than accessing the service locally w/o SSL. Not even sure if this would work with Dex as the SSL is terminated at the ELB.

I would like to force Istio to route certain VirtualServices requests through Dex to authenticate via our LDAP server. I wish there was docs on this.

mabushey commented 4 years ago

Ugg just realized this was a CoreOS project. Are there any plans on letting it live on via a community fork like Flatcar did for CoreOS or is this just RedHat induced abandon-ware now?

bonifaido commented 4 years ago

Hi @mabushey, this is a community "fork" now, since the project was moved out under the @coreos GitHub organization to @dexidp. Active maintainers are from Chef, Pusher and Banzai Cloud, and more are free to join.

bonifaido commented 4 years ago

I would like to force Istio to route certain VirtualServices requests through Dex to authenticate via our LDAP server. I wish there was docs on this.

I think what you re looking for is some kind of proxy application, where dex sits at the backend, like https://github.com/pusher/oauth2_proxy am I right?

mabushey commented 4 years ago

@bonifaido Thanks for your response. I use the Banzai Istio Operator, it's amazing. Glad to hear some of those people are working on Dex, and that Dex didn't get killed by RedHat. :) Possibly oauth2_proxy might work, thank you for letting me know about it. I don't think I'm doing very good at explaining my use case, which I think is very common with k8s and Istio. I want a service like Dex internal to my k8s cluster. Ideally I would go to a service like grafana.example.com, and without a JWT Istio would internally redirect to a local LDAP -> JWT "converter" for log in with my LDAP password as there is no JWT token, and then a valid LDAP user/pass would issue a JWT token that would then allow direct access to Grafana. This is simple in concept, however it's mind boggling how convoluted all these auth protocols are. LDAP feels like it was designed on Flintstone computers centuries before hashs or common sense were invented. Anyway LDAP is the one part currently working. I greatly appreciate projects like Dex that aim to simplify things.

JoelSpeed commented 4 years ago

@mabushey To achieve what you are trying, you can use Dex and OAuth2 Proxy (or equivalent) running within your cluster. However, because of the way that these protocols are implemented, you will need to have them somewhat on the internet/intranet as there will be endpoints needed to be accessible by the users browser. These endpoints should be on HTTPS but you can use a self signed certificate if you prefer to keep it internal, your users will just need to trust this.

Dex acts as a bridge between LDAP and a protocol called OIDC (which creates the JWT you mention). OAuth2 Proxy can be queried by your ingress layer and check whether a user is authenticated or not, if not, the ingress layer can redirect to the OAuth2 Proxies sign in page and the user can start the LDAP authentication process via Dex. Once finished, they are redirected via Dex and then via the OAuth2 Proxy (where they then get an authenticated session) and back finally to the original application.

As for the original assertion that Dex forcing HTTPS is wrong, I have to disagree. A key part of the OIDC authentication flow that Dex uses it that parts of requests are made via HTTP calls. In these calls there is a sort of key exchange happening where two parties share some authentication data between them to perform the authentication flow. The encryption provided by using HTTPS is fundamental to the security model of OIDC and is actually key to the design of the protocol (https://openid.net/connect/faq/ <- there's a note here about it).

Because of this, I'm going to close the issue, hopefully with the advice I've given above you can reach a solution for your problem, I strongly recommend you check out the OAuth2 proxy and maybe even give my old blog post a read where I've explained the interactions between the two projects and how we achieved the same authentication process you desire

mabushey commented 4 years ago

@JoelSpeed

However, because of the way that these protocols are implemented, you will need to have them somewhat on the internet/intranet as there will be endpoints needed to be accessible by the users browser. These endpoints should be on HTTPS but you can use a self signed certificate if you prefer to keep it internal, your users will just need to trust this.

Not a problem, I have a real cert on a Load balancer which does the SSL termination. This is why I posted "Requirement Dex is running on HTTPS is wrong for K8s/Istio.". Has anyone using Dex actually worked on servers and/or know what Load Balancers / SSL termination is? Dex should be smart enough to look at the X-Forwarded-Proto header and figure out "yes, I was accessed via https".

JoelSpeed commented 4 years ago

Has anyone using Dex actually worked on servers and/or know what Load Balancers / SSL termination is?

Frankly, I find this comment incredibly rude. People are responding to an issue you opened, trying to help you to do your job, in their spare time. This is a community project and no one is paid to respond to issues on it,. Please be courteous to those who are tying to help you.

Typically, load balancers have an ability to connect to upstream servers on either HTTPS or HTTP, therefore I still maintain that Dex forcing requests onto HTTPS is a reasonable security action. It makes it harder for people who are not familiar with the complicated authentication protocols to expose themselves to insecure configuration.

Is there any reason, in your system, why you cannot run Dex internally, with a self signed certificate, and have the load balancer proxy requests via HTTPS to your Dex instance?

mabushey commented 4 years ago

@JoelSpeed First off thank you for your time responding and reopening this ticket. I apologize my comment was taken as rude, this was not my intent. "Security" enforcement that lowers my security level frustrates me and probably came out in that comment.

Is there any reason, in your system, why you cannot run Dex internally, with a self signed certificate, and have the load balancer proxy requests via HTTPS to your Dex instance?

Yes, I have a production K8s cluster with an api control plane that can only be accessed via an SSH tunnel. The rest of the traffic all goes through an ELB that does SSL termination into Istio ingress. I don't want to use a self signed cert for two reasons: 1. I have a real cert. 2. I would have to add another ELB (or ALB) to not terminate and try to get Istio to talk to both. I don't think I'm smart enough to make that work, plus I don't want double the attack vectors. Security is important to me, and It appears that DEX is enforcing insecurity. I could easily be wrong, and would be very happy if this is the case. If I'm looking at something wrong, please point this out to me. Having an ASIC in the load balancer handle SSL termination seems like a win/win to me. Istio is trying to do a lot with mTLS so maybe there is a solution there, but in a year of using Istio I've never seen mTLS actually work in a manner I would trust for production.

Thanks again for your time. If you ever make it to Missoula, MT I'll buy you a beer.

jdfalk commented 4 years ago

+1 to allowing it to run without https and looking at the header. We use istio for all mTLS intracluster so we are already securing the traffic. How about a compromise of a flag that says --i-know-what-im-doing-disable-tls. That way it's really apparent to people that this should only be done if you know what you are doing and why. People are still going to screw it up, but you can't protect everyone from themselves.

JoelSpeed commented 4 years ago

@mabushey As I understand your set up, you currently have something like internet -> (HTTPS) -> ELB -> (HTTP) -> Istio (Envoy) -> (HTTP) -> Dex, That last step inside the cluster could be TLS.Envoy supports TLS upstreams, you just need to specify insecure TLS or provide the CA on that internal connection

I'm think I may have been a little overly cautious in my previous comments. I could see an --insecure-serve-http flag being added and that would solve the problem. I'd been keen to get another maintainers opinion on this thread though (CC @sagikazarmark @bonifaido)

sagikazarmark commented 4 years ago

My only concern allowing to disable TLS:

It makes it harder for people who are not familiar with the complicated authentication protocols to expose themselves to insecure configuration.

But I understand that operationally it might be a bit strong requirement. As long as it's not the default and documentation clearly articulates that this is a loaded gun aimed at the leg, I'm okay with adding such option to the configuration.

jdfalk commented 4 years ago

Thank you. I would clarify that the setup is more akin to: internet -> (HTTPS) -> LB (passthrough) -> (HTTPS) -> Istio (ingress) -> ((HTTP) encapsulated in TLS by istio) -> Istio (Envoy) -> (HTTP in same pod) -> Dex The only time it's not encrypted is when it's going to localhost:service_port, and if you are listening in, inside my pod, I have much bigger security issues to worry about than not securing dex.