1. Create dirs
ssh 10.41.0.2 sudo mkdir -p /srv/data/computer/docker/ldap/database sudo mkdir -p /srv/data/computer/docker/ldap/config sudo mkdir -p /srv/data/computer/docker/ldap/ssl
2. Create container
docker run --name ldap \ -v /srv/data/computer/docker/ldap/database:/var/lib/ldap \ -v /srv/data/computer/docker/ldap/config:/etc/ldap/slapd.d \ -v /srv/data/computer/docker/ldap/ssl:/osixia/slapd/assets/ssl \ -e LDAP_ORGANISATION="Kedu SCCL" \ -e LDAP_DOMAIN="kedu.cat" \ -e LDAP_ADMIN_PASSWORD=secret \ -e SSL_CRT_FILENAME=ldap01_slapd_cert.pem \ -e SSL_KEY_FILENAME=ldap01_slapd_key.pem \ -e SSL_CA_CRT_FILENAME=cacert.pem \ -d osixia/openldap
IMPORTANT: LDAP_ADMIN_PASSWORD variable will hold the administrative password of “cn=admin,dc=example,dc=com” account, and it will be used later on
2.1. Test it:
Note: this step can be performed from phpldapadmin or similar with “cn=admin,dc=example,dc=com” account
docker exec -ti ldap bash ldapsearch -x -H ldap://localhost -b dc=example,dc=com -D "cn=admin,dc=example,dc=com" -w secret
Expected output:
# extended LDIF # # LDAPv3 # base <dc=example,dc=com> with scope subtree # filter: (objectclass=*) # requesting: ALL # # kedu.cat dn: dc=example,dc=com objectClass: top objectClass: dcObject objectClass: organization o: Kedu SCCL dc: kedu # admin, example.com dn: cn=admin,dc=example,dc=com objectClass: simpleSecurityObject objectClass: organizationalRole cn: admin description: LDAP administrator userPassword:: e1NTSEF9RzJ2d0w2N05GOUhsdlplbXJpajZNaWdvU0Rub3Urelk= # search result search: 2 result: 0 Success # numResponses: 3 # numEntries: 2
3. Fix permisions to allow a readonly user.
With this step:
3.1. Fix permisions:
ldapmodify -Q -Y EXTERNAL -H ldapi:/// -W <<EOF
dn: olcDatabase={1}mdb,cn=config
changetype: modify
delete: olcAccess
-
add: olcAccess
olcAccess: {0}to attrs=userPassword,shadowLastChange by self write by dn="cn=admin,dc=example,dc=com" write by anonymous auth by * none
olcAccess: {1}to * by self write by dn="cn=admin,dc=example,dc=com" write by * read
-
EOF
Enter LDAP Password:
secret
Output:
modifying entry "olcDatabase={1}hdb,cn=config"
3.2. Create “readonly” user:
Note: this step can be performed from phpldapadmin or similar with “cn=admin,dc=example,dc=com” account
ldapadd -x -D 'cn=admin,dc=example,dc=com' -w secret -H ldapi:/// <<EOF
dn: cn=readonly,dc=example,dc=com
cn: readonly
description: LDAP readonly to be used by 3rd party applications
objectclass: simpleSecurityObject
objectclass: organizationalRole
objectclass: top
userpassword: {SSHA}hHJACqn9+rMO3a6Vvc+fjwfr7WKzOkKN
EOF
Expected output:
adding new entry "cn=readonly,dc=example,dc=com"
3.3. Test it:
| “Username” | cn=readonly,dc=example,dc=com |
| Password | secret |
Now you should be able to:
4. Add groupOfNames module/overlay
This module/overlay is needed in order to use LDAP groups in 3rd party applications, such as redmine
4.1. Add module
ldapadd -Q -Y EXTERNAL -H ldapi:/// -W <<EOF
dn: cn=module,cn=config
cn: module
objectClass: olcModuleList
olcModuleLoad: memberof.la
olcModulePath: /usr/lib/ldap
dn: olcOverlay={0}memberof,olcDatabase={1}mdb,cn=config
objectClass: olcConfig
objectClass: olcMemberOf
objectClass: olcOverlayConfig
objectClass: top
olcOverlay: memberof
olcMemberOfDangling: ignore
olcMemberOfRefInt: TRUE
olcMemberOfGroupOC: groupOfNames
olcMemberOfMemberAD: member
olcMemberOfMemberOfAD: memberOf
EOF
Enter LDAP Password:
secret
Expected output:
adding new entry "cn=module,cn=config"
adding new entry "olcOverlay={0}memberof,olcDatabase={1}mdb,cn=config"
4.2. Configure it
ldapmodify -Q -Y EXTERNAL -H ldapi:/// -W <<EOF
dn: cn=module{1},cn=config
add: olcmoduleload
olcmoduleload: refint.la
EOF
Enter LDAP Password:
secret
Expected output:
modifying entry "cn=module{1},cn=config"
4.3. Add overlay:
ldapadd -Q -Y EXTERNAL -H ldapi:/// -W <<EOF
dn: olcOverlay={1}refint,olcDatabase={1}mdb,cn=config
objectClass: olcConfig
objectClass: olcOverlayConfig
objectClass: olcRefintConfig
objectClass: top
olcOverlay: {1}refint
olcRefintAttribute: memberof member manager owner
EOF
Enter LDAP Password:
secret
Expected output:
adding new entry "olcOverlay={1}refint,olcDatabase={1}mdb,cn=config"
5. Load test data:
Note: this step can be performed from phpldapadmin or similar with “cn=admin,dc=example,dc=com” account
ldapadd -x -D 'cn=admin,dc=example,dc=com' -w secret -H ldapi:/// <<EOF
dn: ou=groups,dc=example,dc=com
objectclass: organizationalUnit
objectclass: top
ou: groups
dn: cn=testgroup,ou=groups,dc=example,dc=com
cn: testgroup
member: cn=user1,ou=people,dc=example,dc=com
member: cn=user2,ou=people,dc=example,dc=com
objectclass: groupOfNames
objectclass: top
dn: ou=people,dc=example,dc=com
objectclass: organizationalUnit
objectclass: top
ou: people
dn: cn=user1,ou=people,dc=example,dc=com
cn: user1
gidnumber: 10001
givenname: User
homedirectory: /home/user1
loginshell: /bin/bash
mail: user1@example.com
objectclass: inetOrgPerson
objectclass: posixAccount
objectclass: top
sn: One
uid: user1
uidnumber: 10001
userpassword: {MD5}Xr4ilOzQ4PCOq3aQ0qbuaQ==
dn: cn=user2,ou=people,dc=example,dc=com
cn: user2
gidnumber: 10001
givenname: User
homedirectory: /home/user2
loginshell: /bin/bash
mail: user2@example.com
objectclass: inetOrgPerson
objectclass: posixAccount
objectclass: top
sn: Two
uid: user2
uidnumber: 10002
userpassword: {MD5}Xr4ilOzQ4PCOq3aQ0qbuaQ==
EOF
Expected output:
adding new entry "ou=groups,dc=example,dc=com" adding new entry "cn=testgroup,ou=groups,dc=example,dc=com" adding new entry "ou=people,dc=example,dc=com" adding new entry "cn=user1,ou=people,dc=example,dc=com" adding new entry "cn=user2,ou=people,dc=example,dc=com"
5.1. Test it:
ldapsearch -LL -Y EXTERNAL -H ldapi:/// "(uid=user1)" -b dc=example,dc=com memberOf
Expected output:
SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 version: 1 dn: uid=test1,ou=people,dc=example,dc=com
This has FAILED. The reason is that we need to perform a write operation in memberof object “testgroup” in order to trigger the overlay and then see the appropiate information:
5.2. Trigger a write operation in memberof object
TODO: document how to do it via CLI
5.2.1. Create a phpldapadmin container in the same docker host that is running LDAP container:
docker run --name phpldapadmin \ --link ldap:ldap \ -e PHPLDAPADMIN_LDAP_HOSTS=ldap \ -d osixia/phpldapadmim
5.2.2. Login to phpldapadmin:
| URL | it will depend on your infraestructure, the simplest way is https://private_ip_phpldapadmin_container |
| login | cn=admin,dc=example,dc=com |
| password | secret |
5.2.3. Click on “+” to expand the tree
5.2.4. Click on “+” at the left of “groups” to expand the tree
5.2.5. Click on “testgroup”
5.2.6. Click on “modify group members”
5.2.7. Click on “test2”, click on “Remove selected” and click on “Save changes”
5.2.8. Click on “Update Object”
TODO: this command will remove the object “uid=test2,ou=people,dc=example,dc=com” and will not trigger memberof overlay, so pending write a command
ldapmodify -x -D "cn=admin,dc=example,dc=com" -W <<EOF dn: cn=testgroup,ou=groups,dc=example,dc=com changetype: modify delete: member member: cn=user2,ou=people,dc=example,dc=com EOF
Enter LDAP Password:
secret
Expected output:
modifying entry "cn=testgroup,ou=groups,dc=example,dc=com"
5.3. Let's repeat step 5.1. again:
ldapsearch -LL -Y EXTERNAL -H ldapi:/// "(uid=user1)" -b dc=example,dc=com memberOf
Expected output:
SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 version: 1 dn: cn=user1,ou=people,dc=example,dc=com memberOf: cn=testgroup,ou=groups,dc=example,dc=com
5.4. Test it using a filter re-usable later on by 3rd party applications, such as redmine:
ldapsearch -D "cn=admin,dc=example,dc=com" -x -W -b 'dc=example,dc=com' -H 'ldap://127.0.0.1:389/' "(&(objectClass=posixAccount)(memberOf=cn=testgroup,ou=groups,dc=example,dc=com)(uid=user1))"
Enter LDAP Password:
secret
Expected output:
# extended LDIF # # LDAPv3 # base <dc=example,dc=com> with scope subtree # filter: (&(objectClass=posixAccount)(memberOf=cn=testgroup,ou=groups,dc=example,dc=com)(uid=user1)) # requesting: ALL # # user1, people, kedu.cat dn: cn=user1,ou=people,dc=example,dc=com cn: user1 gidNumber: 10001 givenName: User homeDirectory: /home/user1 loginShell: /bin/bash mail: user1@example.com objectClass: inetOrgPerson objectClass: posixAccount objectClass: top sn: One uid: user1 uidNumber: 10001 userPassword:: e01ENX1YcjRpbE96UTRQQ09xM2FRMHFidWFRPT0= # search result search: 2 result: 0 Success # numResponses: 2 # numEntries: 1
5.5. Test it with a 3rd party application, such as redmine. Filter:
(&(objectClass=posixAccount)(memberOf=cn=testgroup,ou=groups,dc=example,dc=com))
open-ldap slapd ldap
Variables:
| Distro | Ubuntu Server 12.10 |
| Domain Component | example.com |
https://help.ubuntu.com/12.10/serverguide/openldap-server.html
0.1 (Opcional) Eliminar por completo una instalacion anterior:
sudo aptitude purge ldap-utils slapd
0.2 (Opcional) Al instalar el paquete slapd nos crea un DIT por defecto basado en el hostname de la maquina donde se instale. Si queremos en este ejemplo usar el dominio de prueba 'example.com':
sudo vim /etc/hosts
Y dejar la linea tal que asi, asumiendo que nuestro hostname es “ldap-1.dev.local.example.com”:
127.0.0.1 localhost 127.0.1.1 ldap.example.com ldap-1.dev.local.example.com
1. Instalar paquetes:
sudo aptitude install ldap-utils slapd
Nos pedira una contrasenya.
IMPORTANTE: esa contrasenya sera la del usuario “cn=admin,dc=example,dc=com”
https://help.ubuntu.com/12.10/serverguide/openldap-server.html#openldap-server-populate
Asumimos que la BD ha sido creada al instalar los paquetes, y que tenemos el DIT “dc=example,dc=com”.
1. Crear:
vim ~/ingesta.ldif
Con el siguiente contenido:
# Creado al instalar
#dn: dc=example,dc=com
#dc: example
#o: example.com
#objectclass: top
#objectclass: dcObject
#objectclass: organization
# Creado al instalar. Superusuario. Permisos de escritura
#dn: cn=admin,dc=example,dc=com
#cn: admin
#description: LDAP administrator
#objectclass: simpleSecurityObject
#objectclass: organizationalRole
#userpassword: {SSHA}JXmAPflthZNZZKv2GR5CAoP4WkFCzJf1
# Usuario de solo lectura para uso de las aplicaciones que se conecten a LDAP
dn: cn=readonly,dc=example,dc=com
cn: readonly
description: LDAP readonly to be used by 3rd party applications
objectclass: simpleSecurityObject
objectclass: organizationalRole
objectclass: top
userpassword: {SSHA}Ij157dTx0/kapcSa2AT7DfJIksc4MYV2
# People. Los usuarios cuelgan de esta OU
dn: ou=people,dc=example,dc=com
objectclass: organizationalUnit
ou: people
# Usuario #1
dn: uid=user1,ou=people,dc=example,dc=com
cn: User One
objectclass: inetOrgPerson
objectclass: top
sn: User One
uid: user1
userpassword: {MD5}kod69wpF/Wou1/6B4SNreA==
# Usuario #2
dn: uid=user2,ou=people,dc=example,dc=com
cn: User Two
objectclass: inetOrgPerson
objectclass: top
sn: User Two
uid: user2
userpassword: {MD5}kod69wpF/Wou1/6B4SNreA==
# Grupos
dn: ou=groups,dc=example,dc=com
objectclass: organizationalUnit
objectclass: top
ou: groups
# Grupo chat. Metemos al usuario #1
dn: cn=chat,ou=groups,dc=example,dc=com
cn: chat
gidnumber: 10001
memberuid: user1
objectclass: posixGroup
# Grupo redmine. Metemos a los usuarios #1 y #2
dn: cn=redmine,ou=groups,dc=example,dc=com
cn: redmine
gidnumber: 10002
memberuid: user1
objectclass: posixGroup
objectclass: top
NOTA: la contrasenya de los usuarios luego la cambiamos con phpldapadmin
2. Ejecutar:
sudo ldapadd -x -D cn=admin,dc=example,dc=com -W -f ingesta.ldif
Teclear contrasenya de admin:
Enter LDAP Password:
Salida:
adding new entry "dc=example,dc=com" adding new entry "cn=admin,dc=example,dc=com" adding new entry "ou=people,dc=example,dc=com" adding new entry "ou=groups,dc=example,dc=com" etc...
3. Comprobar:
ldapsearch -x -LLL -b dc=example,dc=com 'uid=user1' cn
Salida:
dn: uid=john,ou=People,dc=example,dc=com cn: User One
Puede servir si queremos crear un segundo DIT.
1. Crear:
vim ~/backend.ldif
Con el siguiente contenido:
# Load dynamic backend modules
#dn: cn=module,cn=config
#objectClass: olcModuleList
#cn: module
#olcModulepath: /usr/lib/ldap
#olcModuleload: back_hdb
# Database settings
dn: olcDatabase=hdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcHdbConfig
olcDatabase: {1}hdb
olcSuffix: dc=example,dc=com
olcDbDirectory: /var/lib/ldap
olcRootDN: cn=admin,dc=example,dc=com
olcRootPW: password
olcDbConfig: set_cachesize 0 2097152 0
olcDbConfig: set_lk_max_objects 1500
olcDbConfig: set_lk_max_locks 1500
olcDbConfig: set_lk_max_lockers 1500
olcDbIndex: objectClass eq
olcDbIndex: uid eq
olcDbIndex: uidNumber eq
olcDbIndex: uniqueMember eq
olcDbIndex: gidNumber eq
olcLastMod: TRUE
olcDbCheckpoint: 512 30
olcAccess: to attrs=userPassword by dn="cn=admin,dc=example,dc=com" write by anonymous auth by self write by * none
olcAccess: to attrs=shadowLastChange by self write by * read
olcAccess: to dn.base="" by * read
olcAccess: to * by dn="cn=admin,dc=example,dc=com" write by * read
Variables
| dc=example,dc=com | Domain Component. Todos los objetos colgaran de ahi |
| cn=admin,dc=example,dc=com | Usuario admin |
| password | contrasenya usuario admin |
2. Ejecutar:
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f backend.ldif
Salida:
SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 adding new entry "olcDatabase=hdb,cn=config"
3. Crear:
vim ~/frontend.ldif
Con el siguiente contenido:
# Create top-level object in domain dn: dc=example,dc=com objectClass: top objectClass: dcObject objectclass: organization o: Example Organization dc: example description: LDAP Example # Admin user. dn: cn=admin,dc=example,dc=com objectClass: simpleSecurityObject objectClass: organizationalRole cn: admin description: LDAP administrator userPassword: password dn: ou=people,dc=example,dc=com objectClass: organizationalUnit ou: people dn: ou=groups,dc=example,dc=com objectClass: organizationalUnit ou: groups dn: uid=perico,ou=people,dc=example,dc=com objectClass: inetOrgPerson objectClass: posixAccount objectClass: shadowAccount uid: perico sn: Os Palotes givenName: Perico cn: Perico Os Palotes displayName: Perico Os Palotes uidNumber: 10001 gidNumber: 10001 userPassword: pericopassword gecos: Perico Os Palotes loginShell: /bin/bash homeDirectory: /home/perico shadowExpire: -1 shadowFlag: 0 shadowWarning: 7 shadowMin: 8 shadowMax: 999999 shadowLastChange: 10877 mail: perico.ospalotes@example.com postalCode: 31000 l: Barcelona o: Example mobile: +33 (0)6 xx xx xx xx homePhone: +33 (0)5 xx xx xx xx title: System Administrator postalAddress: initials: PO dn: cn=example,ou=groups,dc=example,dc=com objectClass: posixGroup cn: example gidNumber: 10001
Variables
| dc=example,dc=com | - |
| cn=admin,dc=example,dc=com | Usuario admin |
| password | contrasenya usuario admin |
| uid=perico | - |
| pericopassword | - |
4. Ejecutar:
sudo ldapadd -x -D cn=admin,dc=example,dc=com -W -f frontend.ldif
Teclear contrasenya de admin:
Enter LDAP Password:
Salida:
adding new entry "dc=example,dc=com" adding new entry "cn=admin,dc=example,dc=com" adding new entry "ou=people,dc=example,dc=com" adding new entry "ou=groups,dc=example,dc=com" adding new entry "uid=perico,ou=people,dc=example,dc=com" adding new entry "cn=example,ou=groups,dc=example,dc=com"
5. Verificar:
ldapsearch -x -LLL -b "dc=example,dc=com" uid=perico
Salida:
dn: uid=perico,ou=people,dc=example,dc=com objectClass: inetOrgPerson objectClass: posixAccount objectClass: shadowAccount uid: perico sn: Os Palotes givenName: Perico cn: Perico Os Palotes displayName: Perico Os Palotes uidNumber: 10001 gidNumber: 10001 gecos: Perico Os Palotes loginShell: /bin/bash homeDirectory: /home/perico shadowExpire: -1 shadowFlag: 0 shadowWarning: 7 shadowMin: 8 shadowMax: 999999 shadowLastChange: 10877 mail: perico.ospalotes@example.com postalCode: 31000 l: Barcelona o: Example mobile: +33 (0)6 xx xx xx xx homePhone: +33 (0)5 xx xx xx xx title: System Administrator postalAddress: initials: PO
6. A partir de aqui ya podriamos probar con phpldapadmin:
Login DN: cn=admin,dc=example,dc=com Password: password
Asumimos que tenemos un servidor Apache (httpd) y otro con OpenLDAP (ldap.example.com). En este ejemplo tenemos el siguiente objeto en nuestro LDAP:
dn: uid=perico,ou=people,dc=example,dc=com ... cn: Perico Os Palotes objectclass: inetOrgPerson objectclass: posixAccount objectclass: shadowAccount ... uid: perico userpassword: pericopassword ...
1. (Apache) Habilitar el modulo ldap
sudo a2enmod authnz_ldap
1. (Apache) Ejemplo de virtualhost:
<VirtualHost *:80>
ServerName testldap.example.com
ServerAdmin webmaster@localhost
DocumentRoot /srv/www/testldap
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /srv/www/testldap>
Options Indexes ExecCGI FollowSymLinks
order allow,deny
allow from all
AuthName "AuthRequired"
AuthType Basic
AuthBasicProvider ldap
AuthLDAPBindDN cn=readonly,dc=example,dc=com
AuthLDAPBindPassword clearpassword
AuthLDAPURL "ldap://ldap.example.com:389/ou=people,dc=example,dc=com" STARTTLS
require valid-user
</Directory>
ErrorLog ${APACHE_LOG_DIR}/testldap.error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/testldap.access.log combined
</VirtualHost>
Variables:
ldap://ldap.example.com:389/ou=people,dc=example,dc=com
Ver authldapurl
1. Configuracion del virtual host:
<VirtualHost *:443>
ServerName testldap.example.com
ServerAdmin webmaster@localhost
DocumentRoot /srv/www/testldap
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /srv/www/testldap>
Options Indexes ExecCGI FollowSymLinks
order allow,deny
allow from all
AuthName "AuthRequired"
AuthType Basic
AuthBasicProvider ldap
AuthLDAPBindDN cn=readonly,dc=example,dc=com
AuthLDAPBindPassword clearpassword
AuthLDAPURL "ldaps://ldap.local.jamgo.org:636/ou=people,dc=jamgo,dc=org"
require valid-user
</Directory>
ErrorLog ${APACHE_LOG_DIR}/testldap.error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/testldap.access.log combined
</VirtualHost>
2. Crear el siguiente archivo:
sudo vim /etc/apache2/conf.d/ldap-tls
Con el siguiente contenido:
LDAPVerifyServerCert Off
3. (TODO) Comprobar si es necesario reiniciar apache o con el reload de mas adelante es suficiente
1. (Apache) Reiniciar Apache:
sudo service apache2 reload
2. En un navegador teclear:
http://testldap.example.com Usuario: perico Contrasenya: pericopassword
https://help.ubuntu.com/12.10/serverguide/openldap-server.html#openldap-server-logging
1. Crear:
vim ~/logging.ldif
Con el siguiente contenido:
dn: cn=config changetype: modify add: olcLogLevel olcLogLevel: stats
2. Implementar el cambio:
sudo ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f logging.ldif
3. Ver los logs (ahora mas descriptivos):
sudo tail -F /var/log/syslog
Si tras teclear:
ldapsearch -x -W -b 'dc=example,dc=com' -H 'ldap://127.0.0.1:389/' 'objectclass=*'
Y pulsar 'Enter' te aparecen resultados, el usuario anonimo puede acceder a tu servidor LDAP
TODO: hacerlo en un solo archivo
1. Crear dos archivos:
vim ~/disable_anonymous_part_1.ldif
Con el siguiente contenido:
dn: cn=config changetype: modify add: olcDisallows olcDisallows: bind_anon
vim ~/disable_anonymous_part_2.ldif
Con el siguiente contenido:
dn: olcDatabase={-1}frontend,cn=config
changetype: modify
add: olcRequires
olcRequires: authc
2. Aplicar los dos cambios:
sudo ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f disable_anonymous_part_1.ldif
modifying entry "cn=config"
sudo ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f disable_anonymous_part_2.ldif
modifying entry "olcDatabase={-1}frontend,cn=config"
3. Volver a probar:
ldapsearch -x -W -b 'dc=example,dc=com' -H 'ldap://127.0.0.1:389/' 'objectclass=*' Enter LDAP Password: ldap_bind: Inappropriate authentication (48) additional info: anonymous bind disallowed
NOTA: si se utiliza 'cn=config' en lugar de 'slapd.conf' NO hace falta reiniciar el servicio. Esto vale para todos los cambios a no ser que se indique lo contrario
https://help.ubuntu.com/12.10/serverguide/openldap-server.html#openldap-tls
When authenticating to an OpenLDAP server it is best to do so using an encrypted session. This can be accomplished using Transport Layer Security (TLS).
Here, we will be our own Certificate Authority and then create and sign our LDAP server certificate as that CA. Since slapd is compiled using the gnutls library, we will use the certtool utility to complete these tasks.
1. Install the gnutls-bin and ssl-cert packages:
sudo apt-get install gnutls-bin ssl-cert
2. Create a private key for the Certificate Authority:
sudo sh -c "certtool --generate-privkey > /etc/ssl/private/cakey.pem"
3. Create the template/file /etc/ssl/ca.info to define the CA:
cn = Example Company ca cert_signing_key
4. Create the self-signed CA certificate:
sudo certtool --generate-self-signed --load-privkey /etc/ssl/private/cakey.pem --template /etc/ssl/ca.info --outfile /etc/ssl/certs/cacert.pem
5. Make a private key for the server:
sudo certtool --generate-privkey --bits 1024 --outfile /etc/ssl/private/ldap01_slapd_key.pem
6. Create the /etc/ssl/ldap01.info info file containing:
organization = Example Company cn = ldap01.example.com tls_www_server encryption_key signing_key expiration_days = 3650
The above certificate is good for 10 years. Adjust accordingly.
7. Create the server's certificate:
sudo certtool --generate-certificate --load-privkey /etc/ssl/private/ldap01_slapd_key.pem --load-ca-certificate /etc/ssl/certs/cacert.pem --load-ca-privkey /etc/ssl/private/cakey.pem --template /etc/ssl/ldap01.info --outfile /etc/ssl/certs/ldap01_slapd_cert.pem
8. Create the file /etc/ssl/certinfo.ldif with the following contents (adjust accordingly, our example assumes we created certs using https://www.cacert.org):
dn: cn=config add: olcTLSCACertificateFile olcTLSCACertificateFile: /etc/ssl/certs/cacert.pem - add: olcTLSCertificateFile olcTLSCertificateFile: /etc/ssl/certs/ldap01_slapd_cert.pem - add: olcTLSCertificateKeyFile olcTLSCertificateKeyFile: /etc/ssl/private/ldap01_slapd_key.pem
Use the ldapmodify command to tell slapd about our TLS work via the slapd-config database:
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f /etc/ssl/certinfo.ldif
9. IMPORTANTE es recomendable habilitar ldaps, por lo tanto SI es necesario:
Editar:
sudo vim /etc/default/slapd
Y dejar la linea tal que asi:
SLAPD_SERVICES="ldap:/// ldapi:/// ldaps:///"
Mas info:
LDAP over TLS/SSL (ldaps: / / ) is deprecated in favour of StartTLS. The latter refers to an existing LDAP session (listening on TCP port 389) becoming protected by TLS/SSL whereas LDAPS, like HTTPS, is a distinct encrypted-from-the-start protocol that operates over TCP port 636.
10. Tighten up ownership and permissions:
sudo adduser openldap ssl-cert sudo chgrp ssl-cert /etc/ssl/private/ldap01_slapd_key.pem sudo chmod g+r /etc/ssl/private/ldap01_slapd_key.pem sudo chmod o-r /etc/ssl/private/ldap01_slapd_key.pem
11. Restart OpenLDAP:
sudo service slapd restart
12. Comprobar:
sudo netstat -nlp | egrep "636|389" | grep -v "tcp6"
Salida esperada:
tcp 0 0 0.0.0.0:636 0.0.0.0:* LISTEN 15275/slapd tcp 0 0 0.0.0.0:389 0.0.0.0:* LISTEN 15275/slapd
Para añadir un campo, por ejemplo loginshell al usuario jur. Creeamos el fichero anyadir.ldif:
dn: cn=jur,dc=lobo99,dc=info add: loginshell loginshell: /bin/bash
Lo añadimos con el comando:
ldapmodify -x -w ******** -D "cn=admin,dc=lobo99,dc=info" -f anyadir.ldif
Para modificarlo, creamos el fichero modificar.ldif
dn: cn=jur,dc=lobo99,dc=info changetype: modify replace: loginshell loginshell: /bin/sh
ldapmodify -x -w ******** -D "cn=admin,dc=lobo99,dc=info" -f modificar.ldif
ldapsearch -D "cn=admin,dc=nodomain" -h 172.17.0.2 -p 389 -w **** -s base -b "CN=Subschema" objectclasses -v -o ldif-wrap=no
Con linux si tienes perl:
ldapsearch -D "cn=admin,dc=nodomain" -h 172.17.0.2 -p 389 -w **** -s base -b "CN=Subschema" objectclasses -v | perl -p00e 's/\r?\n //g'
ldapsearch -D "cn=admin,dc=nodomain" -h 172.17.0.2 -p 389 -w **** -s base -b "CN=Subschema" objectclasses -v -o ldif-wrap=no
objectClasses: ( 2.5.6.0 NAME 'top' DESC 'top of the superclass chain' ABSTRACT MUST objectClass ) objectClasses: ( 1.3.6.1.4.1.1466.101.120.111 NAME 'extensibleObject' DESC 'RFC4512: extensible object' SUP top AUXILIARY ) objectClasses: ( 2.5.6.1 NAME 'alias' DESC 'RFC4512: an alias' SUP top STRUCTURAL MUST aliasedObjectName ) objectClasses: ( 2.16.840.1.113730.3.2.6 NAME 'referral' DESC 'namedref: named subordinate referral' SUP top STRUCTURAL MUST ref ) objectClasses: ( 1.3.6.1.4.1.4203.1.4.1 NAME ( 'OpenLDAProotDSE' 'LDAProotDSE' ) DESC 'OpenLDAP Root DSE object' SUP top STRUCTURAL MAY cn ) objectClasses: ( 2.5.17.0 NAME 'subentry' DESC 'RFC3672: subentry' SUP top STRUCTURAL MUST ( cn $ subtreeSpecification ) )