CentOS/RHEL 6u5 with Two-Factor Authentication Google Authenticator and SELinux

As already announced on several Social Media Platforms, I got Google Authenticator PAM-module enabled on a Centos(/RHEL) 6u5 box.


This implementation includes:



  • SELinux can run in enforcing mode;

  • Certain IP-ranges or users in certain groups can be excluded from Two-Factor Authentication;


Please note that it does not require the Google Authentication Service, the Google Authenticator is just a PAM module that enables HMAC-Based One-time Password (HOTP) algorithm specified in RFC 4226 and the Time-based One-time Password (TOTP) algorithm specified in RFC 6238, which is license under the Apache License 2.0.



Installing Google Authenticator PAM Module


First step is to install the (additional) required packages; just to be sure they’re there…

# yum -y install git pam-devel


Download and compile the code:


# cd $HOME

# git clone https://code.google.com/p/google-authenticator/

# cd $HOME/google-authenticator/libpam

# make

# make install


Modify /etc/ssh/sshd_config so the following setting is active:



ChallengeResponseAuthentication yes

UsePAM yes


But also disable pubkey authentication, to avoid bypassing 2FA (one of the nice caveats I run into)



PubkeyAuthentication no


Restart the SSH Daemon



# service sshd restart


Change the /etc/pam.d/sshd so it has the following contents (please note that the secret is stored in the $HOME/.ssh folder, this has the correct SELinux Context):


#%PAM-1.0
auth [success=1 default=ignore] pam_access.so accessfile=/etc/security/group-2fa.conf
auth required pam_google_authenticator.so secret=${HOME}/.ssh/google_authenticator
auth required pam_sepermit.so
auth include password-auth
account required pam_nologin.so
account include password-auth
password include password-auth
# pam_selinux.so close should be the first session rule
session required pam_selinux.so close
session required pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session required pam_selinux.so open env_params
session optional pam_keyinit.so force revoke
session include password-auth



Now configure the /etc/security/group-2fa.conf, this file controls who/what are exempted from 2FA:


# This file controls which exemptions are made for
# disabling two factor authentication
#
# Users that are member of the usergroup no2fa are
# exempted of the requirement providing 2FA
+ : (no2fa) : ALL

# And we also trust the systems from the Subnet 192.168.100.0/24
# This subnet also contains hosts that are very secure
+ : ALL : 192.168.100.0/24
# Keep this line, to enforce non matching entries
# to enforce 2FA
- : ALL : ALL


Setting up the users


I created two users, one who is member of the no2fa group and one not.


# id pieter
uid=500(pieter) gid=500(pieter) groups=500(pieter)
# id testuser
uid=502(testuser) gid=502(testuser) groups=502(testuser),503(no2fa)


$ ssh [email protected]
Password: ********
Password: ********
Password: ********


As you can see, without luck... /var/log/secure gives you the following errors:



Jun 18 10:11:41 centos-testvm sshd[2896]: error: PAM: Cannot make/remove an entry for the specified session for pieter from workstation.example.com
Jun 18 10:11:41 centos-testvm sshd[2906]: pam_access(sshd:auth): access denied for user `pieter' from `workstation.example.com'
Jun 18 10:11:41 centos-testvm sshd(pam_google_authenticator)[2906]: Failed to read "/home/pieter/.ssh/google_authenticator"
Jun 18 10:11:41 centos-testvm sshd[2898]: Postponed keyboard-interactive for pieter from 172.31.3.250 port 16055 ssh2
Jun 18 10:11:42 centos-testvm sshd[2898]: Connection closed by 172.31.3.250


This is caused because google-authenticator is not configured yet…


The user testuser can login (which is in the no2fa group): 


$ ssh [email protected]
Password: ******
Last login: Wed Jun 18 09:51:05 2014 from workstation.example.com
[testuser@centos-testvm ~]$


So now we have to configure google-authenticator for the user pieter.


# sudo su - pieter
$ google-authenticator --label=${USER}@example.com --time-based --disallow-reuse --force
--window-size=6 --rate-limit=3 --rate-time=30 --secret=${HOME}/.ssh/google_authenticator
https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/[email protected]%3Fsecret%3DABHNLFFWEOJPPL5QQ
Your new secret key is: DABHNLFFWEOJPPL5QQ
Your verification code is 408011
Your emergency scratch codes are:
60523746
71110301
00006670
78000814
75909110


Now the user pieter can log in using 2FA:


$ ssh [email protected]
Verification code: [Token]
Password: ********
Last login: Fri Jun 20 11:30:37 2014 from workstation.example.com
[pieter@centos-testvm ~]$