-
Notifications
You must be signed in to change notification settings - Fork 75
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
Unexpected checking of principals #15
Comments
How about replacing
with
This seems better than a using fixed string since the cert is guaranteed to contain
|
I don't think that works. The overall test becomes:
But that simplifies to:
i.e. the other members of ValidPrincipals are pointless. |
My suggestion is to stop checking principals in I haven’t written a test with this change so I could definitely be missing something obvious. |
Oh I understand now, sorry. Yes, that cheat will work, pretty ugly though |
pam_ussh.go actually used to do that: I'm trying to remember why I changed this behavior, 3+ years ago now (the internal commit logs probably have more detailed information, but I don't have access to those anymore :)) |
@pmoody- that internal commit log reads "check cert is good for the user trying to use it", and wasn't reviewed. Your guess is as good as mine! |
I think there is a solution here that could resolve multiple concerns at once:
I'm going to work on a PR that does this. |
I confirm that what you says is true for CheckCert, but this is a divergence from OpenSSH behaviour. See
The only way I know to permit authentication where the certificate has no principals, is to add an entry to I think it would be very dangerous to accept a certificate without principals as a sort of super-certificate that matches all principals. For example, if you are using Hashicorp Vault to issue certs, the client can request the set of principals to be included, and each one is checked to see if the user is authorized to request it. However they can request no principals - and if no default principal has been set in the signing role, then they'll get a certificate with no principals. If pam_ussh were to reject certificates with no principals, I'd be much more comfortable with that. |
Oh, that is very interesting. The spec and OpenSSH's implementation are disagreeing. The spec says a certificate with no principals should be valid for all principals: https://cvsweb.openbsd.org/src/usr.bin/ssh/PROTOCOL.certkeys?rev=1.19&content-type=text/x-cvsweb-markup
Which I agree is a massive foot-gun given how ssh-keygen will happily create principal-less certs if you omit (edit: I have tested that OpenSSH does indeed work as documented, too) Okay, I'll change course and add rejection of principal-less certs to the PR I have in progress. |
Thank you for that! I ought to test it with host certificates too, i.e. whether a host certificate with no principals acts as a "wildcard" that matches all hosts (and would be equally dangerous). |
I am testing pam-ussh. I am logging in to the target machine as user "web", and my certificate has principals
["web@anywhere" "database@anywhere" "root@anywhere"]
. This works for ssh login because mysshd_config
has:and the script
/etc/ssh/authprinc.sh
isThis gives me a way of authorizing access to machines in groups, similar to zones described here.
So far so good. However, pam-ussh refuses to permit sudo. I have configured it with default options:
Note in particular that I have not specified
authorized_principals
orauthorized_principals_file
, and the documentation says they both default to""
Initially, pam-ussh logs only "no valid certs found". So I made a small patch to log some more info:
Now what I get is this:
(My ssh agent has three private keys and one cert)
It appears that
ssh.CertChecker.CheckCert
is rejecting the certificate on the basis that it requires a particular principal, equal to the logged-in username. Digging further, it's the "username" argument being passed intoCheckCert
, which is checked against the list of principals in the certificate, if this list is non-empty. This is taking place before pam-ussh does its own principal checks.As a result, there seems to be a hard-coded policy that if the certificate contains principals, then the bare ssh login name must exist as a principal in that certificate - which unfortunately doesn't work with my scheme for principals.
As far as I can see, this restriction is in the go ssh library, and there's not much that pam-ussh can do about it short of re-implementing the CheckCert function. I could propose a change to the go library here so that if the principal you pass in is empty string, this check is skipped:
A better option might be to have a setting for pam-ussh to pass a fixed string, e.g.
"sudo"
to CheckCert. This would then accept any certificate which includes that principal.However, assuming that neither of the above happens, I still think it would be worthwhile to:
authorized_principals
orauthorized_principals_file
The text was updated successfully, but these errors were encountered: