Distroname and release: Debian Wheezy
OpenLDAP Server, authenticate linux users
OpenLDAP is a very big topic, and very abstract. So for this reason, this is no-way in a dept guide til OpenLDAP, but just a little quick note, that hopefully can help you getting started.In this example, we will setup LDAP to authenticate "local" users.
This will be updated, as I find or come across useful information.
I am using a similar setup, as a central authentication for several different machines.
LDAP = Leight Weight Access Protocol OU = Organisational Unit CN = Common Name DN = Distinguish Name RDN = Relative Distinguish Name DC = Domain Component L = location O = Organisation ST = State C = County dit = Directory Information Tree LDIF = Ldap Data Interchange Format OID = Object Identifier SN = SurnameWe will install the ldap-utils package which contains client utilities for administrering the OpenLDAP server and the package slapd, which is the OpenLDAP server itself.
Installation
apt-get install ldap-utils slapd
Automatically initial setup ("New PREFFERED" way) cn=config style
Debconf first asks for an password, so we will have to rerun the utility for the initial setup.dpkg-reconfigure slapdMy answers.
Omit OpenLDAP server configuration: no dns domain name: test.local Organization name: MyTestOrg password: XXXX
Initial Configuration
Create a basic LDIF file for the initial tree.This is the most important step, so think about how you will design the DIT.
There are some good info on this site: http://www.zytrax.com/books/ldap/ch5/index.html
My DIT will look like this.
dc=test.local | o=MyTestOrg | ______________/ \______________ / \ ou=Users ou=GroupsConfiguring the client config file, which sets default values for ldap client utilities like ldapsearch. This is needed to be done on the server, as well as clients which will use the LDAP server.
In example, if you have a client, that should auth against the LDAP server at login.
Edit the file, like below. Default port is 389.
Change dc and IP to your values.
/etc/ldap/ldap.conf
BASE dc=test,dc=local
URI ldap://10.0.2.1:389
Now from the client (which is STILL the server), lets see if this is working, the below command, should give you an output of the content on the LDAP server. Note the server could be the client in this case as well.
It should come with some information about our ldap server.
ldapsearch -x
OU and users, groups configuration
Now we will create the OUs, so it will match the DIT design above.Add data to ldap We will be using ldapadd from the openldap-clients package to create a simple structure.usersgroupsOU.ldif dn: ou=Users,dc=test,dc=local objectClass: organizationalUnit ou: Users description: test.local users dn: ou=Groups,dc=test,dc=local objectClass: organizationalUnit ou: Groups description: test.local groups
ldapadd expects ldif input, so we will create a file which we will import.
ldapadd -x -W -D 'cn=admin,dc=test,dc=local' < usersgroupsOU.ldif
Create a basic user
Again, we will use an ldif file, as an template to create a user, and a group with same name and id.Create a "local" user, witch a matching group, which can logon, and authenticate. We will need to use an posix account.
{crypt}, will encrypt the userPassword field in the OpenLDAP database using the systems crypt function.
There are more information about OpenLDAP encryption types here: http://www.openldap.org/doc/admin24/security.html
Creating the password "test":
slappasswd -s testhest -h "{CRYPT}" {CRYPT}7X91DC.VmRVu6Creating the ldif file. We have to use the password generated above.
Now add the user "jdoe", and the group "jdoe".user.ldif dn: uid=jdoe,ou=Users,dc=test,dc=local objectClass: inetOrgPerson objectClass: posixAccount cn: John Doe sn: Doe uidNumber: 10001 gidNumber: 10001 homeDirectory: /home/jdoe loginShell: /bin/bash userPassword: {crypt}7X91DC.VmRVu6 dn: cn=jdoe,ou=Groups,dc=test,dc=local objectClass: posixGroup cn: jdoe gidNumber: 10001
ldapadd -x -W -D 'cn=admin,dc=test,dc=local' -f user.ldif
Setting up the clients for LDAP logons
Note that the clients are using cleartext username / passwords now, read the Adding encrypted security section for encrypted logons.On the client install libnss-ldap,nscd and libpam-ldap.
The nsdc is a Name Service Caching Daemon, which caches NSS information. (user,group,hosts etc), and therefor NOT passwords.
It is possible to use libnss-ldapd and libpam-ldapd which uses nslcd instead of libnss-ldap and libpam-ldap. libnss-ldapd and libpam-ldapd, shares the same configuration file /etc/nslcd.conf which is also known in example CentOS.
libnss-ldapd and pibpam-ldapd should have better support for TLS/SSL.
Ref: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=579647
Answer the debconf answers that matches your needs.
apt-get install libnss-ldap nscd libpam-ldapNext configure libnss-ldap and libpam-ldap, so it can lookup the OpenLDAP directory.
Note A third slash have been removed from the URI section, so it is ldap:// and not ldap:/// or ldapi:///.
libnss-ldap answers:
I have added two ldap servers to the URI, so, if example the first server dies, i will request the second one. Requires replication!
LDAP server URI: ldap://10.0.2.1 ldap://10.0.2.15 Distinguished name of the search base: dc=test,dc=local LDAP Version To Use: 3libpam-ldap answers:
LDAP Account for root: cn=admin,dc=test,dc=local LDAP root account password: LDAP_server_password Allow LDAP admin account to behave like local root?: Yes Does The LDAP Database Require Login: No LDAP Administrative account: cn=admin,dc=test,dc=local LDAP Administrative password: LDAP_server_passwordThe file for libnss-ldap can be manually editet in /etc/libnss-ldap.conf, or by running:
dpkg-reconfigure libnss-ldapThe file for libpam-ldap.conf can manually be editet in /etc/libpam-ldap.conf, or by running:
dpkg-reconfigure libpam-ldapSetting up the NSSwitch file for ldap authentication, so we can login with an OpenLDAP user locally on the system.
Leave compat, so you still can login with the users that exists locally on the client, like example root!
putting ldap after compat, will first query local files, then LDAP, if no success
/etc/nsswitch.conf
passwd: compat ldap
group: compat ldap
shadow: compat ldap
pam.d config files
The below files, must have configured the ldap module, for pam to be able to talk with the LDAP server.In Debian Wheezy, the default files will work, and LDAP should be enabled by default, if not it is possible to reconfigure libpam-ldap, and under PAM profiles to enable select LDAP Authentication
If you have changed the files manually, you muse select "force overwrite" to enable ldap configurations in the files automatically! Then LDAP should be enabled in the below files.
- /etc/pam.d/common-account Verifies access. In example, account expiration
- /etc/pam.d/common-auth Verifies the password request
- /etc/pam.d/common-password Change password
- /etc/pam.d/common-session Manages user sessions, in example mounting home directory
/etc/init.d/nscd stop
Testing
Testing the login from the client, for our test users. It should prompt for informations about the user, if this is working.id jdoe uid=10001(jdoe) gid=10001(jdoe) groups=10001(jdoe)
getent passwd jdoe jdoe:*:10001:10001:John Joe:/home/jdoe:/bin/bash
ldapwhoami -h 10.0.2.1 -x -D "uid=jdoe,ou=Users,dc=test,dc=local" -W Enter LDAP Password: dn:uid=jdoe,ou=Users,dc=test,dc=local
Home directories
Since homedirectories, are not existing on machines that should logon to the OpenLDAP server, we will make sure that these homedirectories, are autocreated for the users at first logon, if they do not exist.Insert the following line into /etc/pam.d/common-session
/etc/pam.d/common-session
session required pam_mkhomedir.so skel=/etc/skel/ umask=0027
All done! You should now be able to login, from the local machine to the ldap server.If this fails check /var/log/auth.log on the local machine.
If the above tests, where sucessfull, and you are unable to login, I would check the libpam-ldap configuration!
Rembember to start the nsdc, when the test is OK.
/etc/init.d/nscd start
Adding SSL/TLS encryption
LDAPS is deprecated! I am to lazy, to do a rewrite of this.. BUT...You should use StartTLS instead of LDAPS. StartTLS listens on 389, so listener ldaps:// should NOT be added to /etc/default/slapd.
This also means, that you HAVE to set "ssl start_tls" in your nslcd.conf/libnss-ldap.conf/pam_ldap.conf files to initiate SSL on the default port 389.
Or else it, is basically the same as below....
For enhanced security we will use TLS, so we get the usernames and passwords encrypted. It is debatable whether to go with TLS or kerberos, read the link for info.:http://www.faqs.org/faqs/kerberos-faq/general/section-31.html
This will change the running default port from 389 to 636, so if required, you might have to open firewall ports.
Another option, is to use StartTLS/StartSSL which will make encrypted connections on the default port 389. I will not go through this step here, but is easy configurable.
On the OpenLDAP server change listening ports of the server in /etc/default/slapd, with this setup both SSL/TLS and unencryptet traffic will work.
Add ldaps:// to /etc/default/slapd on the server.
It is also possible to remove the default port 389 (ldap:///), if you do not want to listen to this port.
It will still though be possible to use NON-TLS on the TLS port (636), unless you directly configure the OpenLDAP server to require a certificate!
And restart the OpenLDAP server/etc/default/slapd SLAPD_SERVICES=SLAPD_SERVICES="ldap:/// ldapi:/// ldaps://"
/etc/init.d/slapd restartI asume you already have an working CA, if not, create one, because I will use my own CA in this example.
http://linuxlasse.net/linux/howtos/Use_OpenSSL_to_create_certificates.
Server certificate
Create the CSR, OR just the certificate!#CSR openssl req -new -key ca.key -out ldap01.test.local.csr #Certificate req -new -x509 -days 365 -nodes -out ldap01.test.local.crt -key ca.keyFill the info. It is important, that "Common Name (eg, YOUR name) []:" is set correctly, so i matches the server you are connecting to on the OpenLDAP server.
"ldap01.test.local" must resolve to the IP of the running the OpenLDAP server!
Common Name (eg, YOUR name) []:ldap01.test.localNext sign, the certificate, if you created an CSR, or skip if you just created the certificate!
./sign.sh openldap.csrNow copy the CA certificate, CA key and the newly signed certificate to a folder where slapd can read the files, chown and set correct rights.
mkdir /etc/ldap/certs/ cp openldap.crt ca.crt ca.key /etc/ldap/certs chown openldap:openldap /etc/ldap/certs/ldap01.test.local.crt /etc/ldap/certs/ca.crt /etc/ldap/certs/ca.key chmod 400 /etc/ldap/certs/ldap01.test.local.crt /etc/ldap/certs/ca.crt /etc/ldap/certs/ca.key
Adding TLS to the OpenLDAP Server
Next create an ldif file, which will add the certificate sections to our OpenLDAP server.Add the ldif fileldaps.ldif dn: cn=config add: olcTLSCACertificateFile olcTLSCACertificateFile: /etc/ldap/certs/ca.crt add: olcTLSCertificateKeyFile olcTLSCertificateKeyFile: /etc/ldap/certs/insecure_ca.key add: olcTLSCertificateFile olcTLSCertificateFile: /etc/ldap/certs/ldap01.test.local.crt
ldapmodify -Y EXTERNAL -H ldapi:// -f ldaps.ldifNow test, if the ldif is added.
ldapsearch -Y EXTERNAL -H ldapi:/// -b cn=config -s base | grep -i tlsShould output something like this.
SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 olcTLSCACertificateFile: /etc/ldap/certs.d/ca.crt olcTLSCertificateKeyFile: /etc/ldap/certs/insecure_ca.key olcTLSCertificateFile: /etc/ldap/certs/ldap01.test.local.crt
Adding TLS to the Clients
Now we must change our clients to use TLS/SSL instead!The certificate ca.crt MUST be readable from at least the service, or else you will get into trouble (make it world readable)
I have set mine to:
The certificate ca.crt MUST be readable from at least the service, or else you will get into trouble (make it world readable)/etc/libnss-ldap.conf base dc=test,dc=local uri ldaps://ldap01.test.local ldap_version 3 rootbinddn cn=admin,dc=test,dc=local tls_checkpeer yes tls_cacertfile /etc/ssl/ca.crt
And if ldap-utils is installed on the client, change default values./etc/libpam_ldap.conf base dc=test,dc=local uri ldaps://ldap01.test.local ldap_version 3 rootbinddn cn=admin,dc=test,dc=local pam_password crypt tls_checkpeer yes tls_cacertfile /etc/ssl/ca.crt
The certificate ca.crt MUST be readable from at least the service, or else you will get into trouble (make it world readable)
If you have issues, you can try to make the TLS connection less "critical"./etc/ldap/ldap.conf BASE dc=test,dc=local URI ldaps://ldap01.test.local TLS_CACERT /etc/ssl/ca.crt TLS_REQCERT demand
For /etc/ldap/ldap.conf, you can try to set "TLS_REQCERT never" instead of demand, and for pam_ldap.conf and libnss-ldap.conf "tls_checkpeer no"!
Remember to read the documentation!
Backup and Restore
While the system is running, it is possible to use slapcat. Remember if something is added while the backup is running, it is likely that it is not backed up.It is therefor recommended if possible, that slapd is stopped while running backup, but not required, or that you are completely sure that nothing is being changed in the database. It would be possible to stop a slave database and then backup of from here..
Doing so, will make the OpenLDAP server unavailable in this timeframe. Most likely just a couple of seconds.
/etc/init.d/slapd stop #backup the configurtaion. slapcat -n 0 -w slapdConfig.ldif #backup the database itself. slapcat -n 1 -w slapdDb.ldif #remove current database(s). rm /var/lib/ldap/* #import the data slapadd -n 0 -l slapdConfig.ldif slapadd -n 1 -l slapdDb.ldif #fix rights chown openldap:openldap /var/lib/ldap/* /etc/init.d/slapd start
Nice to have stuff, issues and fixes
Allow user to change password
If you want an user to allow to change passwords on the OpenLDAP Server, using the passwd command, you must remove use_authtok from /etc/pam.d/common-password.use_authtok disables the password prompt.
/etc/pam.d/common-password #password [success=1 user_unknown=ignore default=die] pam_ldap.so use_authtok try_first_pass password [success=1 user_unknown=ignore default=die] pam_ldap.so try_first_pass
Allow binding to config section
Normally, it is only possible to access the config section using ldapi://.Creating a password for the config section of Openldap, allows binding to it, and using ldapmodify.
In this example, the password will be "test", created by slappasswd.
slappasswd -s test {SSHA}e8b47PmRK3AeKLISgJkB3y6bdaXSvkZ2Ldif file.
Add it to the OpenLDAP server.configadminpass.ldif dn: cn=config changetype: modify dn: olcDatabase={0}config,cn=config changetype: modify add: olcRootPW olcRootPW: {SSHA}e8b47PmRK3AeKLISgJkB3y6bdaXSvkZ2
ldapmodify -Y EXTERNAL -H ldapi:// -f 0ldapconf.ldifNow it is possible to bind to the config section, in this example using StartTLS.
ldapmodify -ZZH ldap://ldap01.test.local -D "cn=admin,cn=config" -W
Forcing TLS / StartTLS serverside
Create an simple LDIF file.Adding the LDIF content to the server.forcetls.ldif dn: cn=config changetype: modify add: olcSecurity olcSecurity: tls=1
ldapmodify -Y EXTERNAL -H ldapi:// -f forcetls.ldifldapseach, should now show something like this, unless ldaps:// is specified in ldap.conf
ldapsearch -x ldap_bind: Confidentiality required (13) additional info: TLS confidentiality requiredTo force StartTLS ONLY, make sure that ldaps:// is removed from the slapd.conf file.
Requires tls=1 on the OpenLDAP server, as described above.
/etc/default/slapd SLAPD_SERVICES="ldapi:/// ldap://"
Forcing an complete sync
Quite simple, stop, delete, start. :)/etc/init.d/slapd stop rm /var/lib/ldap/* /etc/init.d/slapd start
OpenLDAP commands
Nice to know commandsChanging own password using ldapasswd command. (-ZZ forces StartTLS, despite whats in ldap.conf)
ldappasswd -h ldap01.test.local -D "uid=jdoe,ou=Users,dc=test,dc=local" -W -S -ZZChanging another users password as root / admin. (-ZZ forces StartTLS, despite whats in ldap.conf)
ldappasswd -h ldap01.test.local -D "cn=admin,dc=test,dc=local" "uid=jdoe,ou=Users,dc=test,dc=local" -W -S -ZZsearch and show all for specific users starting with jdoe
ldapsearch -h ldap01.test.local -D "cn=admin,dc=test,dc=local" "(uid=jdoe*)" -WDeleting an entry
ldapdelete -h ldap01.test.local -x -D "cn=admin,dc=test,dc=local" "cn=jdoe,ou=Groups,dc=test,dc=local" -W ldapdelete -H ldap://ldap01 -D "cn=admin,dc=test,dc=local" "uid=jdoe24,ou=Users,dc=test,dc=local" -WTesting TLS, if the default ldap.conf is not set for this!
ldapsearch -h ldap01.test.local -Z -x -D 'cn=admin,dc=test,dc=local' -W 'objectclass=*' -vChecking replication status. Must be done on all hosts, example on one host.
ldapsearch -x -H ldap://ldap2 -s base contextCSN -LLL contextCSN: 20150901182759.319689Z#000000#001#000000 contextCSN: 20150901182641.152254Z#000000#002#000000Happy LDAP'ing :)