ldap installation with ssl -------------------------- Download the latest release of openldap from openldap.org and openssl from openssl.org. I work with openldap-2.0.11 and openssl 0.9.6b. First compile and install openssl. ./config --prefix:/opt/openssl --openssldir=/opt/openssl make make test make install Edit Compile and install openldap. ./configure --prefix=/opt/openldap --with-tls I didn't find a way to say where the openssl include files were located, so I edited the configure script (line 612) and added -I/opt/openssl/include to ac_flags . export CFLAGS=-I/opt/openssl/include/ export CPPFLAGS=-I/opt/openssl/include/ export LDFLAGS=-L/opt/openssl/lib/ Running the configure script as above, here's what I see in the output: checking for sys/un.h... yes checking for openssl/ssl.h... yes checking for ssl.h... no checking for SSLeay_add_ssl_algorithms in -lssl... no checking for SSL_library_init in -lssl... yes make depend make make test make install Configure slapd (dc, admin access, ...) --------------- Edit /opt/openldap/etc/openldap/slapd.conf specify your suffix: suffix "dc:myorg,dc=be" The root distinguished name: rootdn "cn=admin,dc=myorg,dc=be" and the admin password rootpw {crypt}result-of-mkpasswd SASL use is recommended, but I didn't look at that yet :-) You can use mkpasswd to get the encrypted password from the cleartext one. Just run mkpasswd and type in the password. At this time, you should be able to run slapd. Just enter the directory /opt/openldap/libexec and run slapd -h "ldap://0.0.0.0/" -d 1 We first make tests without SSL. You can already test the access to the ldap server: ldapsearch -x -D "cn=admin,dc=myorg,dc=be" -h ip.addr.of.srv -W You'll be prompted for the root pasword as set in the slapd.conf. ---------------- fill the database ----------------- create a ldif file and put it into the db thanks to slapadd (the ldap server does not have to run) or with ldapadd (you add entries through the ldap server. here is a file I could add so I have my org in the db: ************************************ dn: dc=myorg, dc=be objectClass: top dn: ou=People, dc=myorg, dc=be objectClass: top objectClass: organizationalUnit ou: People ************************************* I used the command: ldapadd -D "cn=admin,dc=myorg,dc=be" -h IP.ADDR.OF.SRV -W -x -f file.ldif Now, I can add people to the db. They will be part of the People ou. For info on the schema, go to: http://ldap.hklc.com . (Note: For the posixAcount: In OpenLDAP, it's in the file "nis.schema" in your openldap/schema directory. So I add the line include /opt/openldap/etc/openldap/schema/nis.schema to slapd.conf ) If you want to do authentication with LDAP (like I will do with pam_ldap), you have to use the objectlcasses posixAccount and shadowAccount. Those are located in the nis.schema. If you only put nis.schema in you slapd.conf, you'll get a message 'AttributeType not found: manager'. Manager is defined in cosine.schema, so you'll have to include this one too (BEFORE the nis.schema). So here is the include section of my slapd.conf: **************************************** include /opt/openldap/etc/openldap/schema/core.schema include /opt/openldap/etc/openldap/schema/cosine.schema include /opt/openldap/etc/openldap/schema/nis.schema ***************************************** I then create the structure for Posix accounts (I create the groups organisationalUnit and the group named staff) and I create a user for me that is memeber of the group staff. I do it thanks to this file and the subsequent command: *************people.ldif****************************** dn: ou=groups, dc=myorg, dc=be objectclass: top objectclass: organizationalUnit ou: groups dn: cn=staff, ou=groups, dc=myorg, dc=be objectclass: top objectclass: posixGroup cn: staff gidnumber: 50 dn: cn=Raphael Bauduin, ou=people, dc=myorg, dc=be cn: Raphael Bauduin sn: Bauduin objectclass: top objectclass: person objectclass: posixAccount objectclass: shadowAccount uid: rbauduin userpassword:{crypt}my_crypted_password uidnumber: 1037 gidnumber: 50 gecos: Raphael Bauduin loginShell: /bin/bash homeDirectory: /home/rbauduin shadowLastChange: 10877 shadowMin: 0 shadowMax: 999999 shadowWarning: 7 shadowInactive: -1 shadowExpire: -1 shadowFlag: 0 ********************************************************* ldapadd -D "cn=admin,dc=myorg,dc=be" -h IP.ADDR.OF.SRV -W -x -f people.ldif Ececuting slapcat, you will see the content of the DB of the LDAP server. ///////////////////////////////////////////////////////////////////////// root@ldap1:/br/ldap-data# slapcat dn: dc=Tiscali, dc=be objectClass: top creatorsName: cn=admin,dc=myorg,dc=be createTimestamp: 20010914101450Z modifiersName: cn=admin,dc=myorg,dc=be modifyTimestamp: 20010914101450Z dn: ou=People, dc=myorg, dc=be objectClass: top objectClass: organizationalUnit ou: People creatorsName: cn=admin,dc=myorg,dc=be createTimestamp: 20010914101450Z modifiersName: cn=admin,dc=myorg,dc=be modifyTimestamp: 20010914101450Z dn: ou=groups, dc=myorg, dc=be objectClass: top objectClass: organizationalUnit ou: groups creatorsName: cn=admin,dc=myorg,dc=be createTimestamp: 20010914124752Z modifiersName: cn=admin,dc=myorg,dc=be modifyTimestamp: 20010914124752Z dn: cn=staff, ou=groups, dc=myorg, dc=be objectClass: top objectClass: posixGroup cn: staff gidNumber: 50 creatorsName: cn=admin,dc=myorg,dc=be createTimestamp: 20010914124752Z modifiersName: cn=admin,dc=myorg,dc=be modifyTimestamp: 20010914124752Z dn: cn=Raphael Bauduin, ou=people, dc=myorg, dc=be cn: Raphael Bauduin sn: Bauduin objectClass: top objectClass: person objectClass: posixAccount objectClass: shadowAccount uid: rbauduin userPassword:: youwontgetmine_he_he uidNumber: 1037 gidNumber: 50 gecos: Raphael Bauduin loginShell: /bin/bash homeDirectory: /home/rbauduin shadowLastChange: 10877 shadowMin: 0 shadowMax: 999999 shadowWarning: 7 shadowInactive: -1 shadowExpire: -1 shadowFlag: 0 creatorsName: cn=admin,dc=myorg,dc=be createTimestamp: 20010914124752Z modifiersName: cn=admin,dc=myorg,dc=be modifyTimestamp: 20010914124752Z /////////////////////////////////////////////////////////////////////// At this time, you can access your ldap server without SSL. I tested it with Netscape and I could make a search for Bauduin and get the result. It should be possible now to use pam_ldap without ssl. that's what I do now. I get the latest pam_ldap.tgz from www.padl.com (126). Change the config file used by the module to /etc/pam_ldap.conf (in pam_ldap.c, line 672 for version 126): configFile = "/etc/pam_ldap.conf"; This is to avoid some possible problems with nss_ldap, which uses /etc/ldap.conf as config file. I had not added my /opt/openldap/lib to the /etc/ld.so.conf file, so I do it now and run ldconfig afterwards. ./configure --with-ldap-dir=/opt/openldap/ --with-ldap-lib=openldap --disable-ssl type make (you need the pam development files. On debian, apt-get install libpam-dev) You get a pam_ldap.so file you have to copy to /lib/security. To test this, I configure the ssh service in /etc/pam.d/ssh to use the ldap server for authentication: ******************************** #%PAM-1.0 auth required pam_ldap.so debug account required pam_ldap.so debug password required pam_ldap.so debug session required pam_ldap.so debug ******************************** and edit the /etc/pam_ldap.conf to my needs: ********************************* host IP.ADDR.OF.SRV port 389 base dc=myorg,dc=be ldap_version 3 ********************************* Now comes the SSL part. We need to create certificates used by theldap server. We need the CA certificate and the server certificate that is signed by this CA. We'll create this CA ourselves. mkdir /br/ldap-certs/ca cd /br/ldap-certs/ca openssl req -new -x509 -keyout ./ca.key -out ./ca.crt You now have your CA certificate and private key. I create a directory for the LDAP server certificate: mkdir /br/ldap-certs/server cd /br/ldap-certs/server openssl genrsa -out server.key We then generate a Certificate Signing Request: openssl req -new -key server.key -out server.csr !!!!As Common Name, enter the FQDN of the LDAP server!!!! ///////////////////////////////////// Using configuration from /opt/openssl/openssl.cnf You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:BE State or Province Name (full name) [Some-State]:Belgium Locality Name (eg, city) []: Organization Name (eg, company) [Internet Widgits Pty Ltd]: Organizational Unit Name (eg, section) []: Common Name (eg, YOUR name) []:ldap1.freegates.net Email Address []: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: ////////////////////////////////////// Now, we can sign this csr with the CA certificate we generated. I creates a openssl.cf file in my working directory with this content: *********************************************************************** #################################################################### [ ca ] default_ca = CA_default # The default ca section #################################################################### [ CA_default ] dir = /br/ldap-certs/ca # Where everything is kept certs = $dir/certs # Where the issued certs are kept crl_dir = $dir/crl # Where the issued crl are kept database = $dir/index.txt # database index file. new_certs_dir = $dir/newcerts # default place for new certs. certificate = $dir/ca.cert # The CA certificate serial = $dir/serial # The current serial number crl = $dir/crl.pem # The current CRL private_key = $dir/ca.key # The private key RANDFILE = $dir/private/.rand # private random number file # Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs # so this is commented out by default to leave a V1 CRL. # crl_extensions = crl_ext default_days = 365 # how long to certify for default_crl_days= 30 # how long before next CRL default_md = md5 # which md to use. preserve = no # keep passed DN ordering # A few difference way of specifying how similar the request should look # For type CA, the listed attributes must be the same, and the optional # and supplied fields are just that :-) policy = policy_anything # For the 'anything' policy # At this point in time, you must list all acceptable 'object' # types. [ policy_anything ] countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional *********************************************************************** At first, issue this command to initialise the serial number: echo 01 > /br/ldap-certs/ca/serial then, issue this command: openssl ca -config ./openssl.cf -out server.crt -infiles ./server.csr you get the files server.crt which is the certificate the LDAP server will use. You can check the content of the certificate by issuing this command: openssl x509 -text -in server.crt Check that the CN is set to the fqdn of your LDAP server! We no have generated all certificates needed, we just have to configure the server in slapd.conf. TLSCipherSuite HIGH:MEDIUM:+SSLv2:RSA TLSCertificateFile /br/ldap-certs/server/server.crt TLSCertificateKeyFile /br/ldap-certs/server/server.key and start le ldap server with ./slapd -d1 -h "ldaps://0.0.0.0/" You can test it with netscape, though I wouldn't advise it as I encountered problems that weren't due to the server. I have problems here checking my config, so I'll go on and configure pam_ldap. PAM_LDAP with ssl. ------------------ We just recompile pam_ldap with ssl support: ./configure --with-ldap-dir=/opt/openldap/ --with-ldap-lib=openldap --enable-ssl make and copy to /lib/security Also copy the ca.cert file to the client if you want to check the identity of the server. Add these lines to your pam_ldap.conf: ssl on tls_ciphers HIGH:MEDIUM:+SSLv2:RSA tls_checkpeer no set your pam configuration to use the ldap server as above, and you should be ok. ------------------------------------------------------ Tweaking the configuration and use ---------------------------------- If your entry has a objectClass = account, you can specify on which hosts the user can login thanks to the host attribute. Be care full to configure pam correctly, because having aacount set to sufficient will let you log in, as you have an account, even if you shouldn't be able to log in..... I set it to [success=ok auth_err=die service_err=ignore perm_denied=die] and it corrected the problems. Be carefull to look at your /etc/hosts file. I had problems when it didn't correspond.