2

So, I have a CentOS 7.2 system and I used realmd to join the AD domain. I can do a # id {username}@{domain} which perfectly lists all of the AD information for that user. Awesome!

Using stock pam.d/system-auth and pam.d/password-auth files, I can ssh and login in as an AD user just fine.

But, when I attempt to use a hardened system-auth and password-auth, things get screwy. I have narrowed it down do the password-auth file, and specifically, the pam_faillock auth section.

Here is what I have for /etc/pam.d/password-auth

auth        required      pam_env.so
auth        [default=1 success=ok] pam_localuser.so debug
auth required pam_faillock.so preauth audit deny=5 unlock_time=900 
auth        sufficient pam_unix.so nullok try_first_pass audit
auth [default=die] pam_faillock.so authfail audit deny=5 unlock_time=900 
auth sufficient pam_faillock.so authsucc audit deny=5 unlock_time=900
auth        requisite     pam_succeed_if.so uid >= 1000 quiet_success
auth        sufficient    pam_sss.so forward_pass
auth        required      pam_deny.so

account     required      pam_unix.so
account     sufficient    pam_localuser.so
account     sufficient    pam_succeed_if.so uid < 1000 quiet
account     [default=bad success=ok user_unknown=ignore] pam_sss.so
account     required      pam_permit.so

password    requisite     pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtok
password    sufficient    pam_sss.so use_authtok
password    required      pam_deny.so

session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
-session     optional      pam_systemd.so
session     optional      pam_oddjob_mkhomedir.so umask=0077
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required      pam_unix.so
session     optional      pam_sss.so

When attempting to authenticate, either on the console or ssh, I get the following:

Oct 07 12:07:48 vmcentos72 sshd[8406]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=localhost  user=user@domain

If I remove those pam_faillock lines in the auth section, it works just fine.

Here is system-auth:

auth        required      pam_env.so
auth        [default=1 success=ok] pam_localuser.so
auth required pam_faillock.so preauth audit silent deny=5 unlock_time=900
auth        [success=done ignore=ignore default=die] pam_unix.so nullok try_first_pass
auth [default=die] pam_faillock.so authfail audit deny=5 unlock_time=900
auth sufficient pam_faillock.so authsucc audit deny=5 unlock_time=900
auth        requisite     pam_succeed_if.so uid >= 1000 quiet_success
auth        sufficient    pam_sss.so forward_pass
auth        required      pam_deny.so

account     required      pam_unix.so
account     sufficient    pam_localuser.so
account     sufficient    pam_succeed_if.so uid < 1000 quiet
account     [default=bad success=ok user_unknown=ignore] pam_sss.so
account     required      pam_permit.so

password    requisite     pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtok
password    sufficient    pam_sss.so use_authtok
password    required      pam_deny.so

session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
-session     optional      pam_systemd.so
session     optional      pam_oddjob_mkhomedir.so umask=0077
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required      pam_unix.so
session     optional      pam_sss.so

Any suggestions for getting this working? If only pam_faillock had a debug option :(

4
  • If you are using AD for accounts, do you need pam_faillock? Presumably your AD handles locking accounts for failed login attempts. Adding faillock to the mix can mix things all up. If the only local account logging in is root, I would say you don't need pam_faillock at all.
    – MikeA
    Oct 7, 2016 at 16:27
  • Unfortunately, the powers that be are probably going to want to keep faillock on. Unfortunately, the various hardening guides require it.
    – skinsbrew
    Oct 7, 2016 at 19:36
  • Well, that's usually how it goes. I'll have to dig through some old stuff, but one thing I notice is no pam_faillock.so line in your account stack. It should be the fist line of account with required.
    – MikeA
    Oct 7, 2016 at 19:54
  • password-auth and system-auth should also be identical. Are they? It's also recommended not to edit these directly. For example, use password-auth-ac for your specific config and make password-auth a soft link to password-auth-ac. Use the same logic for system-auth.
    – MikeA
    Oct 7, 2016 at 20:13

2 Answers 2

3

Your problem is that you did not adjust the PAM stack accordingly, specifically the "skip" counts on the lines using the bracket notation. If you're not familiar with that notation, RTFM pam.conf(5), which also lists the bracket notation equivalents of "required", sufficient", etc.

The default auth section for RHEL 7 with sssd configured looks like this:

auth        required      pam_env.so
auth        [default=1 success=ok] pam_localuser.so
auth        [success=done ignore=ignore default=die] pam_unix.so nullok try_first_pass
auth        requisite     pam_succeed_if.so uid >= 1000 quiet_success
auth        sufficient    pam_sss.so forward_pass
auth        required      pam_deny.so

The pam_localuser line says the default action is to skip one module (pam_unix in this case), but in case of success (i.e. the user is local), proceed normally. This is done so that domain (non-local) users do not generate a failed login attempt with pam_unix but instead skip directly to sssd (pam_sss, with a uid >= 1000 check beforehand).

Also note the default=die setting on pam_unix, which means a failed local login will abort the authentication stack right there (and not even try pam_sss). Similarly, success=done does the same for successful logins.

As has been already mentioned, pam_faillock does not apply to domain users, but if you're using it for local accounts and inserting three calls to it around pam_unix, you'll need to change the pam_localuser line to default=4, so that domain logins will continue to work. (With default=1, it will skip pam_faillock but proceed to pam_unix, which will obviously fail for domain accounts, and because of default=die, abort immediately. Setting default=4 will skip to pam_succeed_if, as it previously did.)

I'm not familiar with pam_faillock, so I can't say if calling it again after pam_unix is proper, but if that is correct, you'll also need to do something about the success=done and default=die on pam_unix, or else it will never make it to pam_faillock to lock/unlock accounts.

This is a complex PAM stack; you might consult the example configurations in pam_faillock(8). Make sure you don't accidentally let everyone in (hopefully, the pam_deny at the end takes care of that), and be sure to adjust any default=N counts when adding or remove subsequent lines.

TL;DR: [default=1] means skip one line afterwards (pam_unix in this case). Adding lines requires adjusting the count.

1

This is my password-auth file and it seems to work OK:

# Setup PAM Env
auth        required      pam_env.so
auth        required      pam_faildelay.so delay=4000000
# Check if Local User, if fail skip to SSSD part
auth        [success=ok default=4]  pam_localuser.so

# Local User - Load pre-auth, if fail end
auth        [success=ok default=2]  pam_faillock.so preauth deny=3 unlock_time=604800 fail_interval=900

# Local User - Attempt Auth, if fail end
auth        [success=ok default=1]  pam_unix.so

# Lcaol User - Sucess, clear lock tally, end
auth        [default=done]          pam_faillock.so authsucc

# Local User - Fail, update lock tally, end
auth        [default=die]           pam_faillock.so authfail deny=3 unlock_time=604800 fail_interval=900

# SSSD User  - Ensure uid is not system uid
auth        requisite     pam_succeed_if.so debug uid >= 1000

# SSSD User  - Attempt Auth
auth        sufficient    pam_sss.so

# Catchall   - Default result if nothin passes
auth        required      pam_deny.so

account     required      pam_faillock.so
account     required      pam_unix.so
account     sufficient    pam_localuser.so
account     sufficient    pam_succeed_if.so uid < 1000 quiet
account     [default=bad success=ok user_unknown=ignore] pam_sss.so
account     required      pam_permit.so

password    requisite     pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtok
password    sufficient    pam_sss.so use_authtok


password    required      pam_deny.so

session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
-session     optional      pam_systemd.so
session     optional      pam_oddjob_mkhomedir.so umask=0077
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required      pam_unix.so
session     optional      pam_sss.so

AD user does not appear in the faillock output after a failed login, local user does.

UPDATE: I added some comments explaining the important steps in the PAM config. Hope this helps.

2
  • Do you also have an explanation why that is so and which part of your config is essential to the answer and which isn't?
    – RalfFriedl
    May 28, 2019 at 17:18
  • Essential part is correctly setup the skip function via '[success=ok default=4]' to a correct next module.
    – John Smart
    Jun 5, 2019 at 20:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .