Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for HTTP basic auth to the kube-apiserver. #6508

Closed
wants to merge 1 commit into from

Conversation

roberthbailey
Copy link
Contributor

Part 1 of getting rid of nginx.

@smarterclayton
Copy link
Contributor

Assigned to @liggitt or @deads2k

@smarterclayton smarterclayton self-assigned this Apr 7, 2015
@deads2k
Copy link
Contributor

deads2k commented Apr 7, 2015

Having basic auth support is useful, but there are a couple gotchas along the way. The big one is that allowing basic auth authentication in a way that browser can use is a dangerous thing to do. The problem is that browsers will cache the basic auth credentials, so any request to the API server would contain the credentials allowing you to perform an action and there's no reasonable way for a user to be able to log out (force the browser to forget the credentials). For command line clients, basic auth is convenient, so forcing the inclusion of some sort of header into the request or other content that a browser link cannot emulate would protect a browser from getting stuck in an authenticated state while still allowing it from the CLI.

As for this particular implementation, I would encourage you to consider using something like an htpasswd file. It will allow you to easily support hashed passwords instead of having a cleartext file. You can see an implementation (that happens to be almost fully compatible with yours) in openshift here: https://github.com/openshift/origin/blob/master/pkg/auth/authenticator/password/htpasswd/htpasswd.go. Using an implementation would like this would allow for a more secure format that is still easily managed like this:

touch /etc/openshift-passwd
htpasswd -b /etc/openshift-passwd joe redhat
htpasswd -b /etc/openshift-passwd alice redhat

@smarterclayton
Copy link
Contributor

Maybe I missed the context, but before we said we would not support basic auth at all, only token auth. And that when we pulled nginx we would be using tokens.

@smarterclayton
Copy link
Contributor

https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/design/access.md The authentication section describes our original agreed path here.

@roberthbailey
Copy link
Contributor Author

@smarterclayton This was meant as a way to keep our current authentication but get rid of nginx. I'd rather get rid of basic auth all together, but we need an auth mechanism that can be used by browsers, and we currently support basic auth so I don't see this as creating any change in our security posture.

@deads2k I understand your point about gotchas re: basic auth. But don't we have all these issues already since we are using it with nginx? For the implementation, I didn't think it was worth the trouble to bother with hashed passwords. If you can read this password file on the master, you can also read the token auth file (which is sitting next to it with the same permissions) and get the same level of access to the master. Right now the two auth mechanisms are on different ports, but that's just historical. There isn't any reason we shouldn't have the apiserver bind to port 443 and have the kubelets use port 443 instead of 6443 to talk to the master.

@smarterclayton
Copy link
Contributor

----- Original Message -----

@smarterclayton This was meant as a way to keep our current authentication
but get rid of nginx. I'd rather get rid of basic auth all together, but we
need an auth mechanism that can be used by browsers, and we currently
support basic auth so I don't see this as creating any change in our
security posture.

Why do our APIs need to be supported by browsers? Given the known problems with BASIC Auth and CSRF attacks, I don't think it's advisable we recommend users use our API via the browser. Token auth can easily be done from XHR calls, which is the accepted practice for this.

@deads2k I understand your point about gotchas re: basic auth. But don't we
have all these issues already since we are using it with nginx? For the
implementation, I didn't think it was worth the trouble to bother with
hashed passwords. If you can read this password file on the master, you can
also read the token auth file (which is sitting next to it with the same
permissions) and get the same level of access to the master. Right now the
two auth mechanisms are on different ports, but that's just historical.
There isn't any reason we shouldn't have the apiserver bind to port 443 and
have the kubelets use port 443 instead of 6443 to talk to the master.


Reply to this email directly or view it on GitHub:
#6508 (comment)

@roberthbailey
Copy link
Contributor Author

@smarterclayton Reading through https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/design/access.md I don't see that any of the more full featured auth design there is currently being considered for v1.0.

Right now folks use the proxy in the apiserver as a convenient way to access pods, services, and even the kubelet's interface. See #5339, #6387, #4440, #5897 for a few examples of issues opened where folks were pointing their browser at the api server.

@liggitt
Copy link
Member

liggitt commented Apr 7, 2015

All the more reason not to make it easy to get browsers authenticated to the API server... basic auth leaves you wide open for CSRF attacks

@roberthbailey
Copy link
Contributor Author

I'm not seeing how this is any different from the status-quo except that it allows us to get rid of nginx sitting between users and the api server (nginx is only providing SSL termination and basic auth and we can already do SSL termination in the api server).

It's only enabled if you specify a flag and drop a properly formatted file on the master, so if you don't want to have basic auth in a particular deployment it's easy to disable (and it's off by default). If we update kubectl to use bearer tokens instead of basic auth and we have a better solution for browsers (like OAuth), then we can take it out.

@smarterclayton
Copy link
Contributor

On Apr 7, 2015, at 4:07 PM, Robert Bailey notifications@github.com wrote:

I'm not seeing how this is any different from the status-quo except that it allows us to get rid of nginx sitting between users and the api server (nginx is only providing SSL termination and basic auth and we can already do SSL termination in the api server).

It's only enabled if you specify a flag and drop a properly formatted file on the master, so if you don't want to have basic auth in a particular deployment it's easy to disable (and it's off by default). If we update kubectl to use bearer tokens instead of basic auth and we have a better solution for browsers (like OAuth), then we can take it out.

Kubectl already supports bearer auth. I don't know that browsers are our primary use case, but swagger for instance can already provide tokens and so can most json explorer plugins.


Reply to this email directly or view it on GitHub.

@roberthbailey
Copy link
Contributor Author

After chatting with @smarterclayton I believe there may be a better way to get rid of nginx than adding basic auth to the apiserver. I'll reopen this PR if I don't make any headway and this seems like the only remaining way forward.

@brendandburns
Copy link
Contributor

I would really like to add this into the apiserver. The user experience w/o Basic Auth isn't great. We all agree oauth is a better way to go, but I'm not willing to step backwards before we step forward.

@roberthbailey
Copy link
Contributor Author

I just rebased this on master and opened #7383 to continue this discussion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants