Using LDAP for single authentication
Version 0.9
Ever think how nice it would be if you didn’t have 9 usernames and passwords to remember for all of the different services on all the different servers you use. Well you can if you have a LDAP directory with you username and password in it, and you configure all the services to use LDAP. This how-to is not the most comprehensive source for doing this, rather a step by step guide that should be enough to get you going in the right direction. This will let users have one account in LDAP and use any service on any server that you choose to allow. i.e. ssh, email, web permissions, samba file shares, ftp, and on and on… And if you need deeper information than I provide in this article, here’s a great resource.
Although I’m explaining this for Debian Linux, it is almost identical for RedHat and most other Linux distributions.This assumes you already have a working install and you’re somewhat familiar with Linux system administration and Pluggable Authentication Modules, or PAM. You should also know a little about LDAP syntax. For example, the domain fatofthelan.com would be dc=fatofthelan,dc=com. The username dstrangelove in the People OU would have the DN of uid=dstrangelove,ou=People,dc=fatofthelan,dc=com. dstrangelove’s group would be cn=dstrangelove,ou=Groups,dc=fatofthelan,dc=com.
First things first, you need to install the LDAP server software and its dependencies. We will be using OpenLDAP for our LDAP server. So non-Debian users install your RPM’s or from source. You’ll need OpenLDAP, PADL’s NSS_LDAP and PAM_LDAP, OpenSSL if you’re planning on using SSL for security, Samba if you want that functionality. Most likely some of this is already on your system. Debian users, all you need to do is enter this:
[root@crm114]# apt-get install libnss-ldap slapd ldap-utils libpam-ldap ca-certificates
…and answer the questions when prompted. When installing slapd, OpenLDAP’s daemon, the Debian install automatically adds an admin user called admin (cn=admin,dc=fatofthelan,dc=com) to the directory and add this user to the ACL’s accordingly. The only problem with this is that if the directory is down or damaged you can’t access it. slapd has a configuration file, /etc/ldap/slapd.conf, that we’ll be adding a new admin to shortly called Manager (cn=Manager,dc=fatofthelan,dc=com) that has full access to the directory. To ease the use of some of our ldap tools, edit your /etc/ldap/ldap.conf file and add the following lines:
HOST 127.0.0.1 BASE dc=fatofthelan, dc=com
The installer should have created a “slapd.conf” located in /etc/ldap/ for Debian users. We need to open it and change some things. First we need to find the schema section and make sure that we have the following schema included:
# Schema and objectClass definitions include /etc/ldap/schema/core.schema include /etc/ldap/schema/cosine.schema include /etc/ldap/schema/nis.schema include /etc/ldap/schema/inetorgperson.schema
This will give us the ability to add the various objectclasses and attributes we’ll need for our users. Next we need to add the “Manager” user that I mentioned earlier. After the “database bdb” entry, add the following:
rootdn “cn=Manager,dc=fatofthelan,dc=com”
rootpw {SSHA}ioFLRifu436G9WiRdfA2ua2wy9+R6ivF
Save and exit. If you’re were wondering how I got “{SSHA}ioFLRifu436G9WiRdfA2ua2wy9+R6ivF” for my rootpw, I used the “slappasswd” command. You could use a plain text password, but that would be very insecure. If security didn’t matter, we’d be using Active Directory. So to get your hashed password with “slappasswd” issue the following command:
[root@crm114]# slappasswd -h {ssha} -s yourPasswdGoesHere
…and it’ll return {SSHA}AyDy6ToNn9h86xgAuI0nMFeb+qLHzayD. Copy this value to your slapd.conf.
The installer will also create the files libnss_ldap.conf, pam_ldap.conf, nsswitch.conf, ldap.secret under /etc with the values you entered during the install. It’s a good idea to verify that they exist and have the correct values. Also you may want to change some of the values you entered sometime, so this is where to do it.
Note to non-Debian users; Debian splits up these files so you may not have them for your distribution. Most likely all of the settings Debian users put in libnss_ldap.conf and pam_ldap.conf will be located in your ldap.conf.
To have PAM use the LDAP libraries we’ll have to edit the /etc/nsswitch.conf file. This file tells PAM what mechanisms to use and in what order. Find these lines and append ldap to them (Some systems will have “files” instead of “compat”. Leave this intact):
passwd: compat ldap group: compat ldap shadow: compat ldap
You’ll also have to add the following information to the PAM files for the services you’d like to use LDAP (located in /etc/pam.d/) . NOTE: RedHat users can use a utility called “authconfig” to do this for them, but be sure to verify the results! Some Linux distributions just have one file called “login” whereas Debian splits them up into several called common-auth, common-account, common-session, common-password. If a service has it’s own file in /etc/pam.d/ it will use that file, otherwise it will user other, which points to the “common-*” files. Be aware that order DOES matter in here. You’ll want to add the pam_ldap entries ABOVE the pam_unix entries. Now add…
auth sufficient pam_ldap.so use_first_pass to /etc/pam.d/common-auth account sufficient pam_ldap.so to /etc/pam.d/common-account session sufficient pam_ldap.so to /etc/pam.d/common-session password sufficient pam_ldap.so to /etc/pam.d/common-password
You may want to take advantage of the pam_mkhomedir library that will automatically create the user’s home directory upon first logon. I do NOT like this and make user’s home directories with my ldapuser tool. But if you want to use it enter:
session required pam_mkhomedir.so skel=/etc/skel/ umask=0022
to the /etc/pam.d/common-session file.
To keep things tidy I make the directory /root/ldap to make/import/alter my ldif files. LDIF is the format that we’ll be using to import/export/modify/delete records in the LDAP directory. Be aware that the LDIF format is VERY sensitive to white space. Spaces and newlines matter!
…so [root@crm114]# mkdir /root/ldap
The Debian installer scripts will automatically create the root DN (dc=fatofthelan,dc=com). If installing from source or another distribution be sure to create this. Debian users skip to the next section on creating ou’s. Create the file mkBase.ldif and enter the following with your settings:
#mkBase creates the base of the LDAP tree dn: dc=fatofthelan,dc=com dc: fatofthelan objectClass: dcObject objectClass: organizationalUnit ou: Fat of the LAN
Now create the base by entering the following:
[root@crm114]# slapadd –v –l /root/ldap/mkBase.ldif (that is a lower case L)
If all has been done correctly, you should see something like this:
added: “dc=fatofthelan,dc=com” (00000001)
To keep users and groups organized we’ll be creating organizational units (OU) to hold our users and groups. You can copy the following file and enter your values. To build the People and Group ou’s create the file mkOu.ldif with the following contents:
## Build the People and Groups ous dn: ou=People,dc=fatofthelan,dc=com ou: People objectClass: organizationalUnit dn: ou=Groups,dc=fatofthelan,dc=com ou: Groups objectClass: organizationalUnit
Now add mkOu.ldif to LDAP. Note that the “slap*” tools access the database directly and the “ldap*” tools access the LDAP server. So the “slap*” tools work when slapd isn’t running. To add mkOu.ldif to LDAP using slapadd, run:
[root@crm114]# slapadd –v –l /root/ldap/mkOu.ldif (that is a lower case L)
Alternatively, to add mkOu.ldif to LDAP using “ldapadd” run:
[root@crm114]# ldapadd -x -D “cn=admin,dc=fatofthelan,dc=com” -W -f mkOu.ldif
Note that the cn=admin user only exsists on Debian systems.
To have all of this stuff running securely and not sending cleartext usernames and passwords we’ll be installing some self-signed certificates and enabling TLS. To generate the certificates we’ll be using a script that exists on just about every system that has OpenSSL installed called CA.pl. I think it may just be CA on RedHat systems.
First navigate to /usr/lib/ssl/misc/ and execute the command:
[root@crm114]# ./CA.pl –newcert
To generate your CA certificate, it will ask you for site specific values, so just answer appropriately, noting that CommonName is the FQDN of your server, i.e. ldap.fatofthelan.com.
We want slapd to start without any intervention so we’ll need to remove the password from our key. To remove the password from our key, run the following command, entering the password when prompted that you used in the previous step:
[root@crm114]# openssl rsa -in newreq.pem -out newkey.pem
We’ll want to store these key in /etc/ldap/ssl, so:
[root@crm114]# mkdir /etc/ldap/ssl
Now move your private LDAP key:
[root@crm114]# mv newkey.pem /etc/ldap/ssl/slapd-key.pem
…and secure it by making it readable by root only:
[root@crm114]# chmod 600 /etc/ldap/ssl/slapd-key.pem
Now we must remove our private key from newreq.pem. Using a text editor, open newreq.pem and remove private key, the section starting with:
—–BEGIN RSA PRIVATE KEY—–
…and ending with:
—–END RSA PRIVATE KEY—–
Now move our new public certificate to it’s home:
[root@crm114]# mv newreq.pem /etc/ldap/ssl/slapd-cert.pem
To have slapd use these keys we need to add the following to our /etc/ldap/slapd.conf:
# Certificate/ssl TLSCipherSuite HIGH TLSCertificateFile /etc/ldap/ssl/slapd-cert.pem TLSCertificateKeyFile /etc/ldap/ssl/slapd-key.pem
Have slapd start using ldaps (ldap over SSL), open /etc/default/slapd and add the following line:
SLAPD_SERVICES=”ldap://127.0.0.1:389/ ldaps:///”
What this does is let all localhost traffic go plaintext and all remote traffic will be encrypted. You must restart slapd to make effective:
[root@crm114]# /etc/init.d/slapd restart
Note: Since this is a self-signed certificate, other systems won’t be able to verify the CA in your certificate. To remidy this you can either purchase a certificate from a trusted root CA, import your self-signed CA to the other systems, or tell the other systems to not verify the root by adding this to your ldap.conf:
TLS_REQCERT allow
If this is a new network install or you don’t have any current users in /etc/passwd that you want to import, you can skip to the next section.
To migrate current users from /etc/passwd to an easily importable ldif file, we’ll be using PADL’s Miration tools. To get them, just download them form padl.com into our /root/ldap directory:
[root@crm114]# wget ‘http://www.padl.com/download/MigrationTools.tgz’
Untar them:
[root@crm114]# tar -zxvf MigrationTools.tgz
and cd into the MigrationTools-45 directory.
Locate and edit the defaults file “migrate_common.ph”, entering your settings.
Adjust these:
$DEFAULT_MAIL_DOMAIN $DEFAULT_BASE $DEFAULT_MAIL_HOST
…and save. I had to adjust the migrate_passwd.pl script a little to produce the output that I needed for my network. You may not need to do this. I wanted to alter and add some attributes for my environment and have the output look like the record below. Edit migrate_passwd.pl to taste.To test the results we’ll have it print to the screen to see the output. Run:
[root@crm114]# ./migrate_passwd.pl /etc/passwd
You should see a list of names like this:
dn: uid=dstrangelove,ou=People,dc=fatofthelan,dc=com uid: dstrangelove cn: Dr. Strangelove givenName: Dr. sn: Strangelove mail: dstrangelove@fatofthelan.com objectClass: inetOrgPerson objectClass: posixAccount objectClass: shadowAccount userPassword: {crypt}$1$iorFDDPCfdadfd7yyXjLg7StvxBGJ1D5ON. shadowLastChange: 12477 shadowMax: 99999 shadowWarning: 7 loginShell: /bin/bash uidNumber: 1001 gidNumber: 1001 homeDirectory: /home/dstrangelove gecos: Dr. Strangelove,,,
Now direct the output to the LDIF file /root/ldap/allUsers.ldif:
[root@crm114]# ./migrate_passwd.pl /etc/passwd > /root/ldap/allUsers.ldif
You’ll want to get the groups too, so:
[root@crm114]# ./migrate_group.pl /etc/group > /root/ldap/allGroups.ldif
Edit the output files and remove any users you don’t want added to LDAP. Now import them to LDAP:
[root@crm114]# ldapadd -x -D “cn=admin,dc=fatofthelan,dc=com” -W -f /root/ldap/allUsers.ldif
[root@crm114]# ldapadd -x -D “cn=admin,dc=fatofthelan,dc=com” -W -f /root/ldap/allGroups.ldif
You should now be able to see the contents with “getent”.
For example:
[root@crm114]# getent passwd dstrangelove
…should give: dstrangelove:x:1001:1001:Dr.Strangelove,109,555-1212,555-2121:/home/dstrangelove:/bin/bash
If you still have the user dstrangelove in your local /etc/passed file it won’t pull from LDAP. If you want to check that it’s really working, delete the user from /etc/passwd and /etc/group or create and import a new ldif file using an entry from the allusers.ldif as your template. After you’ve successfully created and imported your new user, issue the “getent” command for the name you just added. If this doesn’t work do not proceed! Go back and find what’s wrong.
At this point you should have a working LDAP directory to authenticate against. You may want to download my “ldap tools” to aid in the creation/deletion/modification of users and groups. Get them here:
http://www.fatofthelan.com/downloads/index.php?did=28
Samba Integration
If you would like to also tie Samba into your LDAP directory, you will need to complete a few extra steps. First you’ll need tell OpenLDAP how to handle the new objectclasses and attributes by adding the samba.schema to your slapd.conf. This will most likely not be on the system.
Note: Samba 2.x and 3.x use VERY different schema! Be sure to use the proper schema. This how-to explains the procedure for Samba 3.x.
To get the samba.schema, as well as lots of great documentaion, just “apt-get install samba-doc” and gunzip the /usr/share/doc/samba-doc/examples/LDAP/samba.schema.gz. For non-Debian users (who are probably wishing that they were right now 😉 ) you’ll probably need to download the Samba 3.x source, untar, and locate the samba.schema in the examples/LDAP/ directory. Once you have the samba.schema copied into your schema directory you need to edit your “slapd.conf” file. Add this to the schema section:
include /etc/ldap/schema/samba.schema
…and restart slapd.
We’ll now need a “Computers” ou, so create it using the mkOu.ldif as your template. Make and import your new ldif file, thus creating the new ou. Now locate your “smb.conf” which is located in /etc/samba for us Debian folk. Since we have to really alter it quite a bit, it’s a good idea to make a copy of it, just in case. Open smb.conf and add the following to it, noting that you may already have some of these settings in the file. Be sure to comment out the old values!
# Samba config file [global]
## Browsing/Identification ###
# Change this to the workgroup/NT-domain name your Samba server will part of workgroup = FATLAN netbios name = CRM114 # server string is the equivalent of the NT Description field server string = %h server (Samba %v)
# LDAPsam part ldap admin dn = "cn=Manager,dc=fatofthelan,dc=com" passdb backend = ldapsam:ldap://127.0.0.1:389 ldap ssl = off ldap suffix = dc=fatofthelan,dc=com ldap delete dn = no unix password sync = yes #(leave commented out due to bug)ldap filter = (&(uid=%u)(objectclass=sambaSamAccount))
ldap user suffix = ou=People ldap group suffix = ou=Groups ldap machine suffix = ou=Computers
To allow Samba to edit the LDAP directory you probably noticed that we’ve added the “ldap admin dn = “cn=Manager,dc=fatofthelan,dc=com”” line. Just for simplicity I used the same Manager user. This is a big security risk! Do create a user that can only access the appropriate ou’s via ACL’s in your slapd.conf and use that user here. Although this how-to is written assuming all services will be on one server, it doesn’t have too. You will most likely have several servers in the equation. Since Samba and LDAP are on the same server it isn’t necessary to encrypt the traffic passing between them, hence the line “ldap ssl” is off. If communications are passing over the network your should set this to start_tls. You have been warned.
To have the ability to write to the directory the Manager (or the user you SHOULD have added) has to authenticate to LDAP. You probably noticed there isn’t any passwd line in the smb.conf. The password is stored elseware, so you’ll have to use the “smbpasswd” utility to add it. Enter this:
[root@crm114]# smbpasswd –w yourUsersPassword
…and you should see this:
Setting stored password for “cn=Manager,dc=fatofthelan,dc=com” in secrets.tdb
The nice thing about Samba is that it updates the LDAP records for you and adds all the new objectclasses and attributes. To see what I mean look at the record for dstrangelove.
[root@crm114]# ldapsearch –x –D “cn=Manager,dc=fatofthelan,dc=com” “(uid=dstrangelove)” –W
…results:
dn: uid=dstrangelove,ou=People,dc=fatofthelan,dc=com uid: dstrangelove cn: Dr. Strangelove givenName: Dr. sn: Strangelove mail: dstrangelove@fatofthelan.com objectClass: inetOrgPerson objectClass: posixAccount objectClass: shadowAccount userPassword: e2NyeXB0fSQxJFBNDFdsfFDF99SdfyRzFZTVB1cGFIWURJYjA=. shadowLastChange: 12477 shadowMax: 99999 shadowWarning: 7 loginShell: /bin/bash uidNumber: 1001 gidNumber: 1001 homeDirectory: /home/dstrangelove gecos: Dr. Strangelove,,,
Now update dstrangelove with the “smbpasswd” command and compare the differences.
[root@crm114]# smbpasswd -a dstrangelove -s SecretPasswd
dn: uid= dstrangelove,ou=People,dc=fatofthelan,dc=com uid: dstrangelove cn: Dr. Strangelove givenName: Dr. sn: Strangelove mail: dstrangelove @fatofthelan.com objectClass: inetOrgPerson objectClass: posixAccount objectClass: shadowAccount objectClass: sambaSamAccount userPassword:: e2NyeXB0fSQxJFBNDFdsfFDF99SdfyRzFZTVB1cGFIWURJYjA= shadowLastChange: 12558 shadowMax: 99999 shadowWarning: 7 loginShell: /bin/bash uidNumber: 1001 gidNumber: 1001 homeDirectory: /home/dstrangelove gecos: Dr. Strangelove,,,, sambaSID: S-1-5-21-1344450970-2161234372-36654443257-3034 sambaPrimaryGroupSID: S-1-5-21-1383250970-2163672372-3665153257-3035 displayName: Dr. Strangelove,,,, sambaPwdCanChange: 1085753893 sambaPwdMustChange: 2147483647 sambaLMPassword: 2E025795A2EFE447AC3CB3EC7G38287 sambaNTPassword: 416DFFA3FF0D4019E5BD5FFSA4166 sambaPwdLastSet: 1085753893 sambaAcctFlags: [U ]
You should see a lot of additions. Notice the sambaLMPassword and sambaNTPassword attributes. Since these Microsoft (weak) hashes can be cracked by a Commadore 64, you’ll want to change the ACL’s in your slapd.conf only letting the Samba Manager user (that you already created, right?) to have any kind of access. No one else should be able to see them! Again, edit your slapd.conf and enter this:
# Setting access for Samba passwords. ## allow the "ldap admin dn" access, but deny everyone else access to attrs=sambaLMPassword,sambaNTPassword by dn="cn=Manager,dc=aorganise,dc=com" write by * none
You’ll need to update slapd’s indices to improve performamce, so change your slapd.conf indices to:
# Indices to maintain index objectclass eq index cn pres,sub,eq index sn pres,sub,eq # required to support pdb_getsampwnam index uid pres,sub,eq # required to support pdb_getsambapwrid() index displayName pres,sub,eq index uidNumber eq index gidNumber eq index memberUid eq index sambaSID eq index sambaPrimaryGroupSID eq index sambaDomainName eq index default sub
You’ll have to let slapd know about the new indices by running the command:
[root@crm114]# slapindex -f /etc/ldap/slapd.conf
I have some shares that I want only “Admins” to have access to. To do this we have to make a new UNIX group and map it to a Samba group. Make and import the following group with your settings and gidNumber:
dn: cn=admins,ou=Groups,dc=fatofthelan,dc=com objectClass: posixGroup objectClass: top cn: admins userPassword: {crypt}x gidNumber: 1002
Now you’ll need to map UNIX group “admins” to the NT group “Domain Admins” even if you’re not using Samba in a domain. This adds the neccesary attributes in LDAP. In case you’re wondering, the NT group RID number is 512 (See appendix D). Issue the command:
[root@crm114]# net groupmap add rid=512 ntgroup=”Domain Admins” unixgroup=admins
Check that is was successful with the “net” command:
[root@crm114]# net groupmap list
Domain Admins (S-1-5-21-3442250970-2163992372-367753257-512) -> admins
Now I add dstrangelove to the admins group with the ldapuser tool:
[root@crm114]# ldapuser dstrangelove admins
To set up the share I enter this in my smb.conf:
[Doomsday] comment = Secret Software valid users = @admins delete readonly = yes writeable = yes path = /home/doomsday write list = @admins
I don’t think that Samba (or Windows) should ever be exposed to the internet, but I like to give web-based Samba access to my users so they can access their home shares from anywhere. I also think that web-based is the way to go because it will work on any platform that can open a web browser. There is an excellent PHP script that I like to use called SmbWebClient and you can get it here:
http://www.nivel0.net/SmbWebClient
It’s a snap to setup. Download and untar it to a directory in your webservers path, for example, /var/www/samba/. Now open it with your favorite editor and configure for your environment. You’ll probably only need to edit the cfgSambaRoot line. Here is what I’ve set mine to:
@define (‘cfgSambaRoot’, ‘FATLAN/CRM114’);
…to have access to all allowable shares. To limit users to their home shares, change it to:
@define (‘cfgSambaRoot’, ‘FATLAN/CRM114/homes’);
You may want to restrict access to the “Samba” web directory with Apache’s PAM module. See the next section for details.
Apache Integration
To tie Apache in to the mix, you have several options. You can have Apache query the LDAP server on its own, or have Apache use PAM for authentication. I like to use PAM so users on the system that aren’t in LDAP can still have access. Go ahead and apt-get install libapache-mod-auth-pam. (Debian users obviously) The install script doesn’t update the /etc/apache/modules.conf file properly so you are instructed to use “modules-config apache” to add it. I just added this to my modules.conf AFTER the auth_module:
LoadModule pam_auth_module /usr/lib/apache/1.3/mod_auth_pam.so
Now open your /etc/apache/httpd.conf file and add the following stanza:
AuthPAM_Enabled on AllowOverride None AuthName "User Files" AuthType "basic" require group users
Edit your /etc/pam.d/httpd file to allow it to use PAM. For Debian users add the following ABOVE the current entries:
@include common-auth @include common-account
You’ll need to create the “Domain Users” group in LDAP and map it to the UNIX users group. Do it like we did the admins group and add it with the “net” command, and use Appendix A for the proper RID.
[root@crm114]# net groupmap add rid=513 ntgroup=”Domain Users” unixgroup=users
Now restart Apache and uses the ldapusers tool to add your users to the proper group. Note: You don’t have to use the groups I did, this is just an example.
Email Integration
My article How To Install Postfix, Amavis, ClamAV, and Spamassassin will guide you through setting this all up. It is written to be PAM enabled so nothing more needs to be done to work with within this framwork.
Summery
As you’ve seen, configuring your system to use LDAP will let you centralize your users and easily leverage the directory for all sorts of services and applications. Next I’ll be using this system and PHP’s robust LDAP functions to build a web-based company directory.
From the Samba docs:
Table 12.1. Well-Known User Default RIDs
Well-Known Entity | RID | Type | Essential |
---|---|---|---|
Domain Administrator | 500 | User | No |
Domain Guest | 501 | User | No |
Domain KRBTGT | 502 | User | No |
Domain Admins | 512 | Group | Yes |
Domain Users | 513 | Group | Yes |
Domain Guests | 514 | Group | Yes |
Domain Computers | 515 | Group | No |
Domain Controllers | 516 | Group | No |
Domain Certificate Admins | 517 | Group | No |
Domain Schema Admins | 518 | Group | No |
Domain Enterprise Admins | 519 | Group | No |
Domain Policy Admins | 520 | Group | No |
Builtin Admins | 544 | Alias | No |
Builtin users | 545 | Alias | No |
Builtin Guests | 546 | Alias | No |
Builtin Power Users | 547 | Alias | No |
Builtin Account Operators | 548 | Alias | No |
Builtin System Operators | 549 | Alias | No |
Builtin Print Operators | 550 | Alias | No |
Builtin Backup Operators | 551 | Alias | No |
Builtin Replicator | 552 | Alias | No |
Builtin RAS Servers | 553 | Alias | No |