Authentication via LDAP - shawfdong/hyades GitHub Wiki
UCSC runs two directory services: Blue & Gold, on ldap-blue.ucsc.edu & ldap-gold.ucsc.edu respectively. The Blue service seems to be open to the world:
# nmap -A -T4 -Pn ldap-blue.ucsc.edu PORT STATE SERVICE VERSION 389/tcp open ldap (Anonymous bind OK) 636/tcp open ssl/ldap (Anonymous bind OK) | ssl-cert: Subject: commonName=ldap-blue.ucsc.edu/organizationName=University of California, Santa Cruz/stateOrProvinceName=California/countryName=US | Not valid before: 2011-11-21T22:40:01+00:00 |_Not valid after: 2014-11-21T22:40:01+00:00 |_ssl-date: 2014-08-22T23:13:30+00:00; 0s from local time. | sslv2: | SSLv2 supported |_ ciphers: none Device type: general purpose Running (JUST GUESSING): FreeBSD 6.X|7.X|8.X|9.X (96%), OpenBSD 4.X (92%), IBM AIX 7.X (86%) OS CPE: cpe:/o:freebsd:freebsd:6.3 cpe:/o:openbsd:openbsd:4.0 cpe:/o:freebsd:freebsd:7.0 cpe:/o:freebsd:freebsd:8.1 cpe:/o:freebsd:freebsd:9 cpe:/o:ibm:aix:7 Aggressive OS guesses: FreeBSD 6.3-RELEASE (96%), OpenBSD 4.0 (92%), FreeBSD 7.0-RELEASE (90%), FreeBSD 7.1-PRERELEASE 7.2-STABLE (90%), FreeBSD 8.1-RELEASE (90%), FreeBSD 9.0-RELEASE (90%), FreeBSD 6.2-RELEASE (88%), FreeBSD 8.0-RELEASE (88%), FreeBSD 7.0-RELEASE-p5 (88%), FreeBSD 9.1-RELEASE (87%)
while Gold is heavily firewalled; and is probably accessible only from a handful of hardened servers at UCSC.
In this article, I document how to enable Authentication[1] via OpenLDAP to the Blue directory service, on my HP xw8600 Workstation running CentOS 7. The same procedure should work on a RHEL/CentOS 6 box as well, with no or minimal modification.
# yum -y install openldap openldap-clients openssh-ldap sssd-ldap
Anonymous access to the Blue directory service, over unencrypted LDAP, works fine, e.g.:
$ ldapsearch -x -H ldap://ldap-blue.ucsc.edu -b "ou=groups,dc=ucsc,dc=edu" '(cn=sysadmins)'
But if we try to specify a distinguished name with which to authenticate to the server, over unencrypted LDAP, the access will fail (which is good security practice!):
$ ldapsearch -x -H ldap://ldap-blue.ucsc.edu -D 'uid=xxxx,ou=people,dc=ucsc,dc=edu' -W -b "ou=groups,dc=ucsc,dc=edu" '(cn=sysadmins)' Enter LDAP Password: ldap_bind: Invalid credentials (49)
However, LDAPS (LDAP over SSL) doesn't work out of box on a CentOS 7 box, while it does on my iMac 2010 (running OS X 10.9):
$ ldapsearch -x -H ldaps://ldap-blue.ucsc.edu -b "ou=groups,dc=ucsc,dc=edu" '(cn=sysadmins)' ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1)
Enabling debugging (-d1) gives us some hint:
$ ldapsearch -x -H ldaps://ldap-blue.ucsc.edu -b "ou=groups,dc=ucsc,dc=edu" '(cn=sysadmins)' -d1 TLS: certdb config: configDir='/etc/openldap/certs' tokenDescription='ldap(0)' certPrefix='' keyPrefix='' flags=readOnly TLS: cannot open certdb '/etc/openldap/certs', error -8018:Unknown PKCS #11 error. TLS: certificate [CN=GlobalSign Organization Validation CA - G2,O=GlobalSign nv-sa,C=BE] is not valid - error -8179:Peer's Certificate issuer is not recognized.. TLS: error: connect - force handshake failure: errno 0 - moznss error -8179 TLS: can't connect: TLS error -8179:Peer's Certificate issuer is not recognized..
Essentially, it complains that the certificate of the CA (GlobalSign Organization Validation CA - G2) is not installed in /etc/openldap/certs. So let's install the CA certificate.
Tip: We need the CA certificate, rather than the server certificate for Blue.
Download both of the certificates:
# openssl s_client -showcerts -connect ldap-blue.ucsc.edu:636 </dev/null>2>/dev/null |\ sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' |\ tee ldap-blue-bundle.crtwhere the switch -showcerts is required, otherwise we'll only get the server certificate. ldap-blue-bundle.crt is comprised of two certificates, the first for the server and the second for the CA.
Save the CA certificate as /etc/openldap/certs/GlobalSign.crt.
Note that the stock /etc/openldap/ldap.conf says:
TLS_CACERTDIR /etc/openldap/certs
Create a softlink between the CA certificate and its hash:
# cd /etc/openldap/certs/ # HASH=$(openssl x509 -in GlobalSign.crt -hash -noout) # ln -s GlobalSign.crt $HASH.0
Finally, LDAPS (LDAP over SSL) runs without error, e.g.:
$ ldapsearch -x -H ldaps://ldap-blue.ucsc.edu -b "ou=groups,dc=ucsc,dc=edu" '(cn=sysadmins)' ### and ### $ ldapsearch -x -H ldap://ldap-blue.ucsc.edu -D 'uid=xxxx,ou=people,dc=ucsc,dc=edu' -W -b "ou=groups,dc=ucsc,dc=edu" '(cn=sysadmins)'
To enable LDAP authentication on CentOS 7, the hard way is to manually edit a myriad of configuration files, which can be time-consuming and error-prone. The easy way is to use the command-line tool authconfig, which is provided by the eponymous RPM package; the easiest is to use the GUI tool authconfig-gtk (or system-config-authentication), provided by the package authconfig-gtk. Here we use the command-line tool authconfig.
Before we proceed, it is prudent to back up all the configuration files:
# /usr/sbin/authconfig --savebackup CentOS7-defaultwhich saves the old configuration files in /var/lib/authconfig/backup-CentOS7-default/.
Run as root:
# /usr/sbin/authconfig --enableldap --enableldapauth \ --ldapserver="ldaps://ldap-blue.ucsc.edu" \ --ldapbasedn="ou=people,dc=ucsc,dc=edu" \ --enablesssd --enablesssdauth --update
For no particular reason at all, the above command has changed TLS_CACERTDIR in /etc/openldap/ldap.conf, which now reads as follows:
TLS_CACERTDIR /etc/openldap/cacerts URI ldaps://ldap-blue.ucsc.edu BASE ou=people,dc=ucsc,dc=edu TLS_CACERTDIR /etc/openldap/cacerts
LDAPS will again fail. To fix it, we can either rerun authconfig with the switch --ldaploadcacert=file:///etc/openldap/certs/GlobalSign.crt; or simply copy the CA certificate over:
# cd /etc/openldap/cacerts # cp -a ../certs/* .
Let's test it. My UCSC account name is shaw. Given the configurations in /etc/openldap/ldap.conf (see above), we can now run a much shortened command to retrieve my entry:
$ ldapsearch -x -LLL 'uid=shaw' dn: uid=shaw,ou=people,dc=ucsc,dc=edu cn: Shawfeng Dong homeDirectory: /afs/cats.ucsc.edu/users/t/shaw loginShell: /usr/bin/bash objectClass: posixAccount uid: shaw uidNumber: 16348 gidNumber: 100000
getent can now get my password entry from the Blue server:
$ getent passwd shaw shaw:*:16348:100000:Shawfeng Dong:/afs/cats.ucsc.edu/users/t/shaw:/usr/bin/bash
getent can get group entry too:
$ getent group sysadmins sysadmins:*:100465:cliffp,emulder,garges,jhoman,jsonstro,tjwright,wkoontz
Let's see if we can log in as user shaw:
[dong@hpc ~]$ su - shaw Password: Last login: Wed Aug 27 13:39:14 PDT 2014 on pts/1 su: warning: cannot change directory to /afs/cats.ucsc.edu/users/t/shaw: No such file or directory id: cannot find name for group ID 100000 mkdir: cannot create directory '/afs': Permission denied -bash-4.2$ id uid=16348(shaw) gid=100000 groups=100000 -bash-4.2$ pwd /home/dong
Well, the LDAP authentication is successful; but the main problem is that the home directory is nonexistent — the other warnings are harmless and can be safely ignored. Let's create some scripts that automatically add a home directory when it doesn't exist (in /home rather than in /afs).
Create /etc/profile.d/00-add-home.sh:
if [ ! -d "$HOME" ]; then HOME=/home/$USER if [ ! -d "$HOME" ]; then mkdir -p $HOME # to copy the hidden files and directories in /etc/skel/ cp -r /etc/skel/. $HOME fi cd $HOME fi
and /etc/profile.d/00-add-home.csh:
if ( ! -d $HOME ) then setenv HOME /home/$USER if ( ! -d "$HOME" ) then mkdir -p $HOME cp -r /etc/skel/. $HOME endif cd $HOME endif
For this to work, we also need to change the permission of /home/ (turning on the sticky bit):
# chmod 1777 /home
Now LDAP authentication works fine, albeit still with some innocuous warnings:
[dong@hpc ~]$ su - shaw Password: Last login: Wed Aug 27 15:17:15 PDT 2014 on pts/1 su: warning: cannot change directory to /afs/cats.ucsc.edu/users/t/shaw: No such file or directory id: cannot find name for group ID 100000 [shaw@hpc ~]$ pwd /home/shaw
Here we employ the System Security Services Daemon (SSSD) to provide access to the identity and authentication provider Blue. SSSD is an intermediary between local clients and any configured data store. What SSSD does is allow a local service to check with a local cache in SSSD, but that cache may be taken from any variety of remote identity providers — an LDAP directory, an Identity Management domain, Active Directory, possibly even a Kerberos realm.[2]
The following configuration files have been modified by authconfig: /etc/sysconfig/authconfig, /etc/nsswitch.conf, /etc/openldap/ldap.conf, /etc/pam.d/password-auth-ac, /etc/pam.d/system-auth-ac, /etc/pam.d/fingerprint-auth-ac, /etc/pam.d/smartcard-auth-ac.
The old-fashioned approach is to configure PAM[3] to access the OpenLDAP service directly, via pam_ldap.so. The basic rule of thumb is to include pam_ldap.so wherever pam_unix.so is included.[4] However, I can't find a package that provides pam_ldap.so in CentOS 7.
Here LDAP is the provider for both identity and authentication. Alternatively, we can use LDAP solely as the identity provider, but use Kerberos as the authentication provider.