Conversation
|
The PR changelog entry failed validation: Changelog entry not found in the PR body. Please add a "no-changelog" label to the PR, or changelog lines starting with |
| // user, the user should not be allowed on | ||
| if createHostUserMode == types.CreateHostUserMode_HOST_USER_MODE_OFF { | ||
| return nil, trace.AccessDenied("user is not allowed to create host users") | ||
| return nil, trace.AccessDenied("role %q prevents creating host users", role.GetName()) |
There was a problem hiding this comment.
Is there any concern around exposing the role that blocked an action like this? It was requested in the original issue and it definitely makes troubleshooting a lot simpler, but I'm not 100% sure if it's wise to write the role back to the client? Nothing bad immediately comes to mind, but just calling it out in case someone else can think of a good reason not to
There was a problem hiding this comment.
I believe that users have the ability retrieve and view their own roles, so I don't know that this poses any problems.
16952e4 to
c5648f2
Compare
rosstimothy
left a comment
There was a problem hiding this comment.
Can we add test coverage?
| existsErr := s.users.UserExists(identityContext.Login) | ||
| if existsErr != nil { | ||
| if trace.IsAccessDenied(accessErr) { | ||
| return false, nil, trace.WrapWithMessage(accessErr, "Insufficent permission for host user creation") |
There was a problem hiding this comment.
We need to be really careful not to introduce a regression here. Previously, we returned no error if trace.IsAccessDenied(accessErr) && existsErr != nil, now we do. Which I know is the entire point of this PR but I think there are cases where the SSH connection should actually succeed:
- the
UserExistsimplementation might return an error even though the user does, in fact, exist (it would on non-linux, butGetCreateHostUser()above would protect us there. Maybe there are other cases) - the user doesn't exist now, but will be created just-in-time by a PAM module https://goteleport.com/docs/enroll-resources/server-access/guides/ssh-pam/#create-local-unix-users-on-login
I think we should probably only return the access denied error if the SSH connection actually fails because the user doesn't exist. Hopefully there's a way to catch that error and add the extra context
0daf04d to
3794f44
Compare
|
|
||
| // Create host user. | ||
| created, userCloser, err := s.termHandlers.SessionRegistry.TryCreateHostUser(identityContext) | ||
| created, userCloser, err := s.termHandlers.SessionRegistry.UpsertHostUser(identityContext) |
There was a problem hiding this comment.
Dropping the Try nomenclature since these functions return errors. Eventually I'd like to change the public interface of usermgmt to avoid this confusion, but for now renaming it is easy
3794f44 to
4fc352d
Compare
4ae56ad to
4502dd5
Compare
| created, userCloser, err := s.termHandlers.SessionRegistry.UpsertHostUser(identityContext) | ||
| if err != nil { | ||
| return ctx, trace.Wrap(err) | ||
| log.Warnf("error while creating host users: %s", err) |
There was a problem hiding this comment.
I'm not sure what this PR is really getting us now, weren't we already logging warnings? But the user rarely sees those logs. If we are going to close the linked issue I would love to see in the PR description what the user actually sees when encountering the error now and how we've improved it
I'm also against logging at the warning level for conditions that we totally expect, like not creating a host user for a teleport user that has no permissions to create host users, which is the expected path for most SSH connections probably
I wonder if we could instead update (*Server).replyError to try to detect errors related to the user not existing and add context to the error we send back to the user there
There was a problem hiding this comment.
Oh I just saw we're not actually trying to close #40370 with this anymore
There was a problem hiding this comment.
Yeah part of this solution ended up overlapping with a bugfix for the second issue now linked in the description. I plan on opening another PR with the work to propagate errors appropriately to the client. For now I can at least reduce the log level, because I agree we shouldn't be warning for something expected out of a healthy system 👍
4502dd5 to
c3018d3
Compare
5785b7f to
f1be7da
Compare
…cking for create_host_user_mode and surfacing for helpful error logging server side
f1be7da to
61e8c3c
Compare
|
@nklaassen I think I've addressed all of your comments. Let me know if there's anything else you'd like to see changed, otherwise I'll plan on merging this tomorrow afternoon 👍 |
| created, userCloser, err := s.termHandlers.SessionRegistry.UpsertHostUser(identityContext) | ||
| if err != nil { | ||
| return ctx, trace.Wrap(err) | ||
| log.Infof("error while creating host users: %s", err) |
There was a problem hiding this comment.
I suggest making the function only return unexpected errors and returning them here
| log.Infof("error while creating host users: %s", err) | |
| return ctx, trace.Wrap(err, "creating host user") |
There was a problem hiding this comment.
The intent with logging errors here is to try and always permit access. Even if the users session is degraded in some way, I think that would be preferred over some error in host user creation completly preventing access to hosts. We really want to avoid forcing users to use their break glass mechanism if they don't need to because something went wrong here.
There was a problem hiding this comment.
I'm operating under the assumption that nobody is ever going to see these logs, especially if they don't have access to the box. But I agree that we should try to allow access if we can. Hopefully we can add some visibility in a later PR if the SSH connection does fail
| }, | ||
|
|
||
| expectCreated: false, | ||
| expectErrIs: trace.AccessDenied("test"), |
There was a problem hiding this comment.
I suggest this is not an error and it should return nil
| expectErrIs: trace.AccessDenied("test"), |
There was a problem hiding this comment.
Similar to this, I'm not sure we should assume these aren't errors in this context. If we could verify that they weren't at this level I would agree, but since we only know for sure at a later time I think this case (and the one below) should still return errors
There was a problem hiding this comment.
I guess I was a bit hung up on this because it's, like, the default way that teleport works. for probably 99% of successful SSH connections the host user already exists and the teleport user is not allowed to create host users. I wish we were differentiating "this is definitely an error" from "this is 99% probably fine but if the connection fails for a specific reason this might be why". But for now I guess it's fine to keep returning it as an error that only gets logged
nklaassen
left a comment
There was a problem hiding this comment.
alright thanks for putting up with all my comments. I see the net improvement here, let's ship it, hopefully we can add more visibility later on if the connection actually fails
| }, | ||
|
|
||
| expectCreated: false, | ||
| expectErrIs: trace.AccessDenied("test"), |
There was a problem hiding this comment.
I guess I was a bit hung up on this because it's, like, the default way that teleport works. for probably 99% of successful SSH connections the host user already exists and the teleport user is not allowed to create host users. I wish we were differentiating "this is definitely an error" from "this is 99% probably fine but if the connection fails for a specific reason this might be why". But for now I guess it's fine to keep returning it as an error that only gets logged
| created, userCloser, err := s.termHandlers.SessionRegistry.UpsertHostUser(identityContext) | ||
| if err != nil { | ||
| return ctx, trace.Wrap(err) | ||
| log.Infof("error while creating host users: %s", err) |
There was a problem hiding this comment.
I'm operating under the assumption that nobody is ever going to see these logs, especially if they don't have access to the box. But I agree that we should try to allow access if we can. Hopefully we can add some visibility in a later PR if the SSH connection does fail
Related to #40370
Fixes #46252
Adds more descriptive error logging when a role blocks user creation on a host, including the name of the role that blocked them. The role included in the message isn't necessarily the only role blocking access since the
AccessCheckerfails fast, but this should provide enough info for debugging purposes.changelog: Fixed an issue preventing session joining while host user creation was in use.