5

I'm trying to set up Chef-managed accounts for a group of machines with the following characteristics:

  • If there is no local account, login is blocked.
  • If there is a local account with SSH keys, use those for authentication is possible.
  • If there is a local account that has a local password, that password is used for authentication.
  • If there is a local account with no local password, Kerberos is used.

I've got that much working.

But the last thing I want to be able to do is to disable login on the account by locally locking the password (e.g. using usermod -L). The problem is that when the local password is locked, PAM is falling back to Kerberos ... and allowing access.

Is there a way to configure PAM so that if a local password exists but it is locked that it won't try Kerberos?

The best I can think of so far is to lock the account by clobbering the local password with something unguessable. But that is a bit crude, and doesn't play well if someone does not "follow the procedure" ...

Stephen C
  • 541
  • 4
  • 18
  • You have Kerberos, why aren't you using it? – Michael Hampton May 24 '13 at 07:17
  • Because I/we don't have any control over who gets added / removed from the Kerberos system. I don't want to go into the details because they are not relevant, but the net effect is that the obvious "best technical solution" is not open to me/us. – Stephen C May 25 '13 at 00:06

4 Answers4

5

I agree with Michael Hampton's comments - you can and should use Kerberos to do this. But if you do want to do it by changing things on the local machine, here's a solution that should work.

In your sshd_config, add the line

DenyGroups blocked

Create a group named "blocked". When locking a user's local password, also add them to the group "blocked".

WARNING! This is a horribly ugly kludge that shouldn't exist in a sane world. It may, however, be useful in the one we live in.

Jenny D
  • 27,358
  • 21
  • 74
  • 110
  • Hmm ... that looks like it will work for SSH, but I'm not sure about the other systems I was planning to integrate (Trac, Tomcat, Django, Samba) – Stephen C May 25 '13 at 00:10
  • But you've given me the clue that I need, 'cos I think a group-based block can actually be implemented in the PAM stack; see my answer – Stephen C May 25 '13 at 01:10
  • At a risk of stating the obvious (but not wanting the random passerby to make the mistake), this will have no effect on non-ssh services that share the same PAM stack. FTP, IMAP, etc. will not be blocked if they are present. – Andrew B Jun 07 '13 at 01:03
1

This problem is mostly a consequence of the fact that pam_unix.so checks for account lockouts in the auth stack instead of account, which is a little counter-intuitive for PAM newbies. Accounting decisions should be made in account, not auth, but shadow based account locks are performed based on the password field. This makes it a necessary compromise.

Before continuing from there and deciding how to implement your fix, let's review the management groups defined by PAM:

  • auth -- Authentication concerns. Limit your tweaks to decisions based on credentials the user is submitting to authenticate, particularly since programs may choose to bypass this module entirely if they implement their own authentication scheme. (the example everyone forgets: sshd skips auth if SSH key authentication is enabled and succeeds)
  • account -- The one that most people new to PAM overlook. If authentication succeeded but the user should be denied access anyway, that decision should be made here. (sshd will not skip this module if SSH key authentication succeeds, unlike auth)
  • passwd -- Changing passwords related to services you defined in auth.
  • session -- Miscellaneous tasks that generally have little to do with whether or not authentication succeeds. Logging, mounting stuff, etc.

Based on your problem description:

  1. We need an auth stack that prioritizes local credentials over krb5 credentials, but one of the two must succeed. Sounds like you've got that covered.
  2. We need an account stack that denies access if no local user is defined. As stated earlier, pam_unix.so fails us in this regard.
  3. passwd defaults are probably fine for changing local passwords.
  4. We have no immediate reason to touch session.

Based on your proposed self-answer, it looks like you have an idea of where to take it from here.

Andrew B
  • 31,858
  • 12
  • 90
  • 128
0

I need to check this at work, but I think I could add a "pam_exec" entry to the stack after "pam_krb5" entry. This could run a script that uses "passwd -S" to check that the password entry for the user has not been locked.

Or I could do it by placing the user a "blocked" group and using pam_succeed_if like this:

auth required pam_succeed_if.so quiet_success user notingroup blocked
Stephen C
  • 541
  • 4
  • 18
  • Avoid putting access controls in `auth` or you risk unintentionally introducing holes into your security policy. I explain this a bit more in my answer. – Andrew B Jun 07 '13 at 01:07
0

For general use, I don't recommend mixing local and kerberos accounts. However, this auth pam stack should work for our purposes. (You may have other piece e.g. pam_env.so that you'll include.)

auth     requisite     pam_unix.so nullok
auth     sufficient    pam_krb5 ignore_root use_first_pass
auth     required      pam_deny.so

If the user's local password is incorrect, or locked, authentication will fail. If the user has no local password, authentication uses kerberos (not GSSAPI), if that fails authentication will fail.

84104
  • 12,698
  • 6
  • 43
  • 75
  • This enforces that the local password be identical to upstream krb5 password. It may be fine for a small business, but in larger ones the security team will seriously frown upon it. – Andrew B Jun 07 '13 at 01:01