Difference between revisions of "LDAP server"
(28 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
+ | [[Category:Linux]] | ||
+ | |||
LDAP server | LDAP server | ||
Line 10: | Line 12: | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
apt-get install slapd ldap-utils | apt-get install slapd ldap-utils | ||
+ | |||
+ | # For SSL - TLS access | ||
+ | apt-get install gnutls-bin | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 41: | Line 46: | ||
* Select NO to the first question = it will '''create a new database''' | * Select NO to the first question = it will '''create a new database''' | ||
* Current LDAP server: "'''dev.daxiongmao.eu'''". This must match your (DC=...,DC=....,DC=....) | * Current LDAP server: "'''dev.daxiongmao.eu'''". This must match your (DC=...,DC=....,DC=....) | ||
+ | * Name of your organization: '''daxiongmao.eu''' | ||
* Root LDAP server: put your root or the same value as before. | * Root LDAP server: put your root or the same value as before. | ||
* Put your '''administrator password - the same as earlier''' | * Put your '''administrator password - the same as earlier''' | ||
Line 58: | Line 64: | ||
$IPTABLES -A INPUT -p tcp -m state --state NEW --dport 636 -j ACCEPT # LDAP over SSL | $IPTABLES -A INPUT -p tcp -m state --state NEW --dport 636 -j ACCEPT # LDAP over SSL | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | =Add overlays= | ||
+ | |||
+ | By default OpenLDAP does NOT support all the LDAP features. | ||
+ | |||
+ | You should enable: | ||
+ | * the group membership: an user has some group membership (''memberOf'') ; each group has a set of members (''member'' attribute). | ||
+ | * the Referential Integrity: to apply all changes on Cascade | ||
+ | |||
+ | |||
+ | |||
+ | ==MemberOf overlay== | ||
+ | |||
+ | This will enable the group memberships attribute "memberOf" for each user | ||
+ | |||
+ | => This attribute "memberOf" will have the complete DN of all user's groups | ||
+ | |||
+ | |||
+ | ===Module setup=== | ||
+ | |||
+ | Create the module configuration's file: | ||
+ | |||
+ | <syntaxhighlight lang="bash"> | ||
+ | cd /etc/ldap | ||
+ | vim memberof.ldif | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | Put the following content: | ||
+ | |||
+ | <syntaxhighlight lang="scheme"> | ||
+ | dn: cn=module{1},cn=config | ||
+ | cn: module{1} | ||
+ | objectClass: olcModuleList | ||
+ | objectClass: top | ||
+ | olcModuleLoad: memberof.la | ||
+ | olcModulePath: /usr/lib/ldap | ||
+ | |||
+ | |||
+ | dn: olcOverlay={0}memberof,olcDatabase={1}hdb,cn=config | ||
+ | objectClass: olcConfig | ||
+ | objectClass: olcOverlayConfig | ||
+ | objectClass: olcMemberOf | ||
+ | objectClass: top | ||
+ | olcOverlay: memberof | ||
+ | olcMemberOfDangling: ignore | ||
+ | olcMemberOfRefInt: TRUE | ||
+ | olcMemberOfGroupOC: groupOfNames | ||
+ | olcMemberOfMemberAD: member | ||
+ | olcMemberOfMemberOfAD: memberOf | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | [!] The overlay must be apply on "cn=module{1}" for declaration + automatic appliance. | ||
+ | |||
+ | otherwise, if "cn=module{0}", the attribute will be supported but not automaticaly used. | ||
+ | |||
+ | |||
+ | [!] Don't forget the empty line at the end | ||
+ | |||
+ | |||
+ | ===Apply configuration=== | ||
+ | |||
+ | <syntaxhighlight lang="bash"> | ||
+ | ldapadd -Q -Y EXTERNAL -H ldapi:/// -f memberof.ldif | ||
+ | service slapd restart | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | ===Check results=== | ||
+ | |||
+ | <syntaxhighlight lang="bash"> | ||
+ | cat /etc/ldap/slapd.d/cn=config/cn=module{1}.ldif | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | =="Referential integrity" overlay== | ||
+ | |||
+ | When enabled, Referential integrity plug-in performs integrity updates on specified attributes immediately after a delete, rename, or move operation. | ||
+ | |||
+ | => It will apply the "memberOf" on user + "member" on group automaticaly | ||
+ | |||
+ | |||
+ | |||
+ | ===Module setup=== | ||
+ | |||
+ | Create the module configuration's file: | ||
+ | |||
+ | <syntaxhighlight lang="bash"> | ||
+ | cd /etc/ldap | ||
+ | vim referential_integrity.ldif | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | Put the following content: | ||
+ | |||
+ | <syntaxhighlight lang="scheme"> | ||
+ | dn: cn=module,cn=config | ||
+ | cn: module | ||
+ | objectClass: olcModuleList | ||
+ | objectClass: top | ||
+ | olcModuleLoad: refint.la | ||
+ | olcModulePath: /usr/lib/ldap | ||
+ | |||
+ | dn: olcOverlay={1}refint,olcDatabase={1}hdb,cn=config | ||
+ | objectClass: olcConfig | ||
+ | objectClass: olcOverlayConfig | ||
+ | objectClass: olcRefintConfig | ||
+ | objectClass: top | ||
+ | olcOverlay: {1}refint | ||
+ | olcRefintAttribute: memberof member manager owner | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | [!] Don't forget the empty line at the end | ||
+ | |||
+ | |||
+ | [!] Unlike "memberOf" you don't need to specify the "cn=module{x}" you can let OpenLDAP decides it for you (== it should be module{2} then !) | ||
+ | |||
+ | |||
+ | |||
+ | ===Apply configuration=== | ||
+ | |||
+ | <syntaxhighlight lang="bash"> | ||
+ | ldapadd -Q -Y EXTERNAL -H ldapi:/// -f referential_integrity.ldif | ||
+ | service slapd restart | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | |||
+ | ===Check results=== | ||
+ | |||
+ | <syntaxhighlight lang="bash"> | ||
+ | cat /etc/ldap/slapd.d/cn=config/cn=module{2}.ldif | ||
+ | </syntaxhighlight> | ||
+ | |||
=Maintenance operations= | =Maintenance operations= | ||
+ | |||
+ | ==Know your configuration== | ||
+ | |||
+ | Display LDAP configuration's structure | ||
+ | |||
+ | <syntaxhighlight lang="bash"> | ||
+ | find /etc/ldap/slapd.d/ | sed 's/[^/]*\//| /g;s/| *\([^| ]\)/+--- \1/' | ||
+ | </syntaxhighlight> | ||
Line 82: | Line 239: | ||
==Test== | ==Test== | ||
− | Install a LDAP client and test to access the server. It should be OK | + | Install a LDAP client and test to access the server. It should be OK ! ^-^ |
+ | |||
+ | See the following page to get more information: [[LDAP client]] | ||
+ | |||
Line 101: | Line 261: | ||
* Do not encrypt your private key | * Do not encrypt your private key | ||
* You cannot generate 2 certificates with the same server name. | * You cannot generate 2 certificates with the same server name. | ||
+ | |||
If you already have a server certificate for the current FQDN, please use it! | If you already have a server certificate for the current FQDN, please use it! | ||
− | Make files accessible for OpenLDAP | + | ==Make files accessible for OpenLDAP== |
− | You have to copy | + | |
− | + | You have to copy your server private key + server certificate and CA certificate. | |
− | + | ||
− | + | <syntaxhighlight lang="bash"> | |
− | + | mkdir /etc/ldap/ssl | |
− | + | cd /etc/ldap/ssl | |
− | + | cp /srv/ssl/private/ldapServer.nopass.key ldapServer.key | |
− | + | cp /srv/ssl/certs/ldapServer.cert.pem ldapServer.pem | |
− | + | cp /srv/ssl/cacerts.pem . | |
− | + | chown -R root:openldap /etc/ldap/ssl | |
− | + | </syntaxhighlight> | |
− | + | ||
− | + | ||
− | + | ... Symlink might work but you can have some rights issues. It's just simpler - in my case - to copy the data. | |
− | + | ||
− | + | ||
− | + | ||
− | + | ==Register certificates== | |
− | + | ||
− | + | ||
− | + | ===SLAPD service=== | |
− | + | ||
− | + | Since OpenLDAP 2.4 there is no more "slapd.conf" file. | |
− | + | ||
− | + | All the configuration is now dynamic and set in database. | |
− | + | ||
− | + | ||
− | + | ||
− | + | '''Create the .ldif file''' | |
− | + | ||
− | + | <syntaxhighlight lang="bash"> | |
− | + | vim /etc/ldap/slapd.d/tls.ldif | |
− | + | </syntaxhighlight> | |
− | + | ||
− | + | Add the following params: | |
− | + | ||
− | + | <syntaxhighlight lang="bash"> | |
− | + | dn: cn=config | |
− | + | add: olcTLSCACertificateFile | |
− | + | olcTLSCACertificateFile: /etc/ldap/ssl/cacerts.pem | |
− | + | - | |
− | + | add: olcTLSCertificateFile | |
− | + | olcTLSCertificateFile: /etc/ldap/ssl/ldapServer.pem | |
− | + | - | |
− | + | add: olcTLSCertificateKeyFile | |
− | + | olcTLSCertificateKeyFile: /etc/ldap/ssl/ldapServer.key | |
− | + | </syntaxhighlight> | |
− | + | ||
− | + | ||
− | + | ||
− | + | '''Adjust rights''' | |
− | + | ||
− | + | <syntaxhighlight lang="bash"> | |
− | + | chown openldap:openldap /etc/ldap/slapd.d/tls.ldif | |
− | + | </syntaxhighlight> | |
− | + | ||
− | + | ||
− | + | ||
− | + | '''Apply the configuration''' | |
− | + | ||
− | + | <syntaxhighlight lang="bash"> | |
− | + | ldapmodify -Y EXTERNAL -H ldapi:/// -f /etc/ldap/slapd.d/tls.ldif | |
− | + | </syntaxhighlight> | |
− | + | ||
− | + | ||
− | + | ||
− | + | '''Allow TLS protocol''' | |
− | + | ||
− | + | <syntaxhighlight lang="bash"> | |
− | + | vim /etc/default/slapd | |
− | + | </syntaxhighlight> | |
− | + | ||
− | + | ||
− | + | Add the "ldaps" protocol (line 24): | |
− | + | ||
− | + | <syntaxhighlight lang="bash"> | |
− | + | SLAPD_SERVICES="ldap:/// ldapi:/// ldaps:///" | |
− | + | ||
− | + | # For more security you can now restrict the LDAP to localhost | |
− | + | SLAPD_SERVICES="ldap://127.0.0.1:389/ ldaps:/// ldapi:///" | |
− | + | </syntaxhighlight> | |
− | + | ||
− | + | ||
− | + | ||
− | + | '''Restart the service''' | |
− | + | ||
− | + | <syntaxhighlight lang="bash"> | |
− | + | /etc/init.d/slapd restart | |
− | + | </syntaxhighlight> | |
− | + | ||
− | + | ||
− | + | ||
− | + | ===OpenLDAP configuration=== | |
− | + | ||
− | + | '''Edit the LDAP configuration''' | |
− | + | ||
− | + | <syntaxhighlight lang="bash"> | |
− | + | vim /etc/ldap/ldap.conf | |
− | + | </syntaxhighlight> | |
− | + | ||
− | + | ||
− | + | Adjust the TLS certificate path | |
− | + | ||
− | + | <syntaxhighlight lang="bash"> | |
− | + | TLS_CACERT /etc/ldap/ssl/cacerts.pem | |
− | + | </syntaxhighlight> | |
− | + | ||
− | + | You have to use the same as before in the "slapd" configuration. | |
− | + | ||
− | + | ||
− | + | '''Restart service''' | |
− | + | ||
− | + | <syntaxhighlight lang="bash"> | |
− | + | service slapd restart | |
− | + | </syntaxhighlight> | |
− | + | ||
− | + | ||
− | + | Now you can connect to the server on port 686 and test your LDAP server over TLS! | |
− | + | ||
− | + | ||
− | + | '''Bonus''' | |
− | + | ||
− | + | Now you can edit your firewall and close the port 389 | |
− | + | ||
− | + | ||
− | + | ||
− | # | + | =Populate the LDAP db (manual)= |
− | + | ||
− | + | ==Create root schema== | |
− | + | ||
− | + | <syntaxhighlight lang="bash"> | |
− | + | cd /etc/ldap | |
− | + | vim daxiongmao.eu_core.ldif | |
− | + | </syntaxhighlight> | |
− | cn | + | |
− | + | ||
− | + | Put the following and adjust: | |
− | + | * Domain name (here it's ''daxiongmao.eu'') | |
− | + | * Admin password (here it's ''PASSWORD_ADMIN'') | |
− | + | ||
− | + | ||
− | + | <syntaxhighlight lang="scheme"> | |
− | + | ##### LDAP domain declaration | |
− | + | dn: dc=daxiongmao,dc=eu | |
− | + | objectClass: top | |
− | + | objectClass: dcObject | |
− | + | objectclass: organization | |
− | + | o: Server Organization | |
− | + | dc: Daxiongmao | |
− | + | description: Daxiongmao.eu root LDAP | |
− | + | ||
− | + | #### Admin user | |
− | + | dn: cn=admin,dc=daxiongmao,dc=eu | |
− | + | objectClass: simpleSecurityObject | |
− | + | objectClass: organizationalRole | |
− | + | cn: admin | |
− | + | description: LDAP administrator | |
− | + | userPassword: PASSWORD_ADMIN | |
− | + | ||
− | + | #### People | |
− | + | # List of LDAP users. An user can be a human or a service account | |
− | + | dn: ou=people,dc=daxiongmao,dc=eu | |
− | + | objectClass: organizationalUnit | |
− | + | ou: people | |
− | + | ||
− | + | #### Groups | |
− | + | dn: ou=groups,dc=daxiongmao,dc=eu | |
− | + | objectClass: organizationalUnit | |
− | + | ou: groups | |
− | + | ||
− | + | #### Locations | |
− | + | dn: ou=locations,dc=daxiongmao,dc=eu | |
− | + | objectClass: organizationalUnit | |
− | + | ou: locations | |
− | + | ||
− | + | #### hosts | |
− | + | dn: ou=hosts,dc=daxiongmao,dc=eu | |
− | + | objectClass: organizationalUnit | |
− | + | ou: hosts | |
− | + | ||
− | + | </syntaxhighlight> | |
− | + | ||
− | + | ||
− | + | [!] Don't forget the empty line at the end of the file | |
− | + | ||
− | + | ||
− | + | ||
− | + | Apply schema | |
− | + | ||
− | + | <syntaxhighlight lang="bash"> | |
− | + | ldapadd -x -D cn=admin,dc=daxiongmao,dc=eu -W -f daxiongmao.eu_core.ldif | |
− | + | </syntaxhighlight> | |
− | + | ||
− | + | ||
− | + | ||
− | + | ==Create users== | |
− | + | ||
− | + | <syntaxhighlight lang="bash"> | |
− | + | cd /etc/ldap | |
− | + | vim daxiongmao.eu_users.ldif | |
− | + | </syntaxhighlight> | |
− | + | ||
− | + | ||
− | + | Put and adjust the following: | |
− | + | * user name | |
− | + | * User password | |
− | + | * UID number (it must be unique) | |
− | + | * UID must match the beginning of the dn (uid=) | |
− | + | ||
− | + | <syntaxhighlight lang="scheme"> | |
− | + | #### Users list | |
− | + | dn: uid=guillaume.diaz,ou=people,dc=daxiongmao,dc=eu | |
− | + | objectClass: inetOrgPerson | |
+ | objectClass: posixAccount | ||
+ | objectClass: shadowAccount | ||
+ | uid: guillaume.diaz | ||
+ | sn: Diaz | ||
+ | givenName: Guillaume | ||
+ | cn: Guillaume Diaz | ||
+ | displayName: Guillaume Diaz | ||
+ | initials: GD | ||
+ | mail: guillaume@qin-diaz.com | ||
+ | title: System Administrator | ||
+ | uidNumber: 1000 | ||
+ | gidNumber: 10000 | ||
+ | userPassword: PASSWORD_GUILLAUME | ||
+ | loginShell: /bin/bash | ||
+ | homeDirectory: /home/guillaume.diaz | ||
+ | shadowExpire: -1 | ||
+ | shadowFlag: 0 | ||
+ | |||
+ | |||
+ | dn: uid=jenkins,ou=people,dc=daxiongmao,dc=eu | ||
+ | objectClass: inetOrgPerson | ||
+ | objectClass: posixAccount | ||
+ | objectClass: shadowAccount | ||
+ | uid: jenkins | ||
+ | sn: Jenkins | ||
+ | cn: Jenkins | ||
+ | displayName: Jenkins | ||
+ | initials: CI | ||
+ | uidNumber: 1001 | ||
+ | gidNumber: 10000 | ||
+ | userPassword: PASSWORD_JENKINS | ||
+ | shadowExpire: -1 | ||
+ | shadowFlag: 0 | ||
+ | shadowWarning: 7 | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | [!] Note that the GID 10000 is not important. This group doesn't even exists !! You can adjust it later on. | ||
+ | |||
+ | |||
+ | |||
+ | Apply changes | ||
+ | |||
+ | <syntaxhighlight lang="bash"> | ||
+ | ldapadd -x -D cn=admin,dc=daxiongmao,dc=eu -W -f daxiongmao.eu_users.ldif | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | |||
+ | ==Create a group== | ||
+ | |||
+ | By default OpenLDAP will create ''posixGroup'' (~ Unix like). | ||
+ | |||
+ | Those are nice but they do NOT support the membership relations. That's a very big limitation !! :( | ||
+ | |||
+ | |||
+ | |||
+ | You should always create '''groupOfNames''' instead of ''posixGroup'' !! | ||
+ | |||
+ | |||
+ | <syntaxhighlight lang="bash"> | ||
+ | cd /etc/ldap | ||
+ | vim daxiongmao.eu_groups.ldif | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | Put and adjust the following: | ||
+ | * group name | ||
+ | |||
+ | <syntaxhighlight lang="scheme"> | ||
+ | dn: cn=users,ou=groups,dc=vehco,dc=com | ||
+ | objectClass: groupofnames | ||
+ | cn: users | ||
+ | description: Domain users (humans). This is the list of all the users that are allowed on the domain | ||
+ | member: uid=guillaume.diaz,ou=people,dc=vehco,dc=com | ||
+ | |||
+ | |||
+ | dn: cn=services,ou=groups,dc=vehco,dc=com | ||
+ | objectClass: groupofnames | ||
+ | cn: services | ||
+ | description: Group for application's users | ||
+ | member: uid=jenkins,ou=people,dc=daxiongmao,dc=eu | ||
+ | |||
+ | |||
+ | dn: cn=ssh-users,ou=groups,dc=vehco,dc=com | ||
+ | objectClass: groupofnames | ||
+ | cn: ssh-users | ||
+ | description: SSH users | ||
+ | member: uid=guillaume.diaz,ou=people,dc=vehco,dc=com | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | Apply changes | ||
+ | |||
+ | <syntaxhighlight lang="bash"> | ||
+ | ldapadd -x -D cn=admin,dc=daxiongmao,dc=eu -W -f daxiongmao.eu_groups.ldif | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | =Populate LDAP db (graphical)= | ||
+ | |||
+ | Use your favorite LDAP client (see [[LDAP client]]) to populate the LDAP registry. | ||
+ | |||
+ | |||
+ | ==Create Organizational Units== | ||
+ | |||
+ | I advised you to create the following OU= | ||
+ | |||
+ | {| class="wikitable" | ||
+ | |- | ||
+ | ! Organization !! Description | ||
+ | |- | ||
+ | | OU=people|| for users | ||
+ | |- | ||
+ | | OU=groups|| for groups such as: application | IT | company | project groups | ||
+ | |- | ||
+ | | OU=locations|| specific area | ||
+ | |- | ||
+ | | OU=applications|| for applications' virtual users | ||
+ | |} | ||
+ | |||
+ | |||
+ | |||
+ | ==Create Groups== | ||
+ | |||
+ | In the "OU=groups" create: | ||
+ | |||
+ | {| class="wikitable" | ||
+ | |- | ||
+ | ! Group !! Description | ||
+ | |- | ||
+ | | CN=users|| domain users | ||
+ | |- | ||
+ | | CN=administrators|| for system administrators | ||
+ | |- | ||
+ | | CN=services|| System and services accounts | ||
+ | |} | ||
+ | |||
+ | |||
+ | |||
+ | ==Create locations== | ||
+ | |||
+ | Under 'locations' create a location for each office | home | place that you'll have in your registry. | ||
+ | |||
+ | |||
+ | In the "OU=location" create: | ||
+ | |||
+ | {| class="wikitable" | ||
+ | |- | ||
+ | ! Location !! Description | ||
+ | |- | ||
+ | | l=France|| French users | ||
+ | |- | ||
+ | | l=Sweden|| Swedish users | ||
+ | |} | ||
+ | |||
+ | |||
+ | |||
+ | ==Create Users== | ||
+ | |||
+ | * Inside '''ou=people''' create a new '''UID''' for each user + make that user a member of ''OU=groups,CN=users'' | ||
+ | |||
+ | |||
+ | |||
+ | * Inside '''ou=applications''' create a new UID for each application or service that will use the LDAP + make that a member of ''OU=groups,CN=services'' | ||
+ | |||
+ | |||
+ | |||
+ | Example of minimal structure: | ||
+ | [[File:LDAP_min_structure.png|none|LDAP minimal structure]] | ||
+ | |||
+ | |||
+ | |||
+ | =Apache 2= | ||
+ | |||
+ | See Apache 2 documentation to get more info: [[Apache 2 - LDAP access]] | ||
+ | |||
+ | |||
+ | |||
+ | =References= | ||
+ | |||
+ | LDAP explanations (French): | ||
+ | * http://www-sop.inria.fr/members/Laurent.Mirtain/ldap-livre.html | ||
+ | * http://www-sop.inria.fr/members/Laurent.Mirtain/ldap-slide.pdf | ||
+ | |||
+ | |||
+ | Overlays "memberOf" + "refint" : | ||
+ | * http://www.schenkels.nl/2013/03/how-to-setup-openldap-with-memberof-overlay-ubuntu-12-04/ | ||
+ | * http://technicalnotes.wordpress.com/2014/04/19/openldap-setup-with-memberof-overlay/ | ||
+ | |||
+ | |||
+ | LDAP howTo (french) | ||
+ | * http://www.jouvinio.net/wiki/index.php/OpenLDAP_Installation | ||
+ | * http://www.jouvinio.net/wiki/index.php/Accueil |
Latest revision as of 13:49, 28 August 2014
LDAP server
Contents
Installation
Packages
apt-get install slapd ldap-utils
# For SSL - TLS access
apt-get install gnutls-bin
You'll have to choose a LDAP admin password. Choose a strong password!!
Set domain
Edit configuration file:
vim /etc/ldap/ldap.conf
Uncomment and adjust:
BASE dc=dev,dc=daxiongmao,dc=eu
URI ldap://dev.daxiongmao.eu
Launch LDAP configuration
Launch configuration:
dpkg-reconfigure slapd
- Select NO to the first question = it will create a new database
- Current LDAP server: "dev.daxiongmao.eu". This must match your (DC=...,DC=....,DC=....)
- Name of your organization: daxiongmao.eu
- Root LDAP server: put your root or the same value as before.
- Put your administrator password - the same as earlier
- Select HDB (Berkley database)
- Do NOT remove database on package removal
- Move old database
- Do NOT allow LDAP v2
Open firewall
Add the following rules to your firewall
# LDAP
$IPTABLES -A INPUT -p tcp -m state --state NEW --dport 389 -j ACCEPT # LDAP
$IPTABLES -A INPUT -p tcp -m state --state NEW --dport 636 -j ACCEPT # LDAP over SSL
Add overlays
By default OpenLDAP does NOT support all the LDAP features.
You should enable:
- the group membership: an user has some group membership (memberOf) ; each group has a set of members (member attribute).
- the Referential Integrity: to apply all changes on Cascade
MemberOf overlay
This will enable the group memberships attribute "memberOf" for each user
=> This attribute "memberOf" will have the complete DN of all user's groups
Module setup
Create the module configuration's file:
cd /etc/ldap
vim memberof.ldif
Put the following content:
dn: cn=module{1},cn=config
cn: module{1}
objectClass: olcModuleList
objectClass: top
olcModuleLoad: memberof.la
olcModulePath: /usr/lib/ldap
dn: olcOverlay={0}memberof,olcDatabase={1}hdb,cn=config
objectClass: olcConfig
objectClass: olcOverlayConfig
objectClass: olcMemberOf
objectClass: top
olcOverlay: memberof
olcMemberOfDangling: ignore
olcMemberOfRefInt: TRUE
olcMemberOfGroupOC: groupOfNames
olcMemberOfMemberAD: member
olcMemberOfMemberOfAD: memberOf
[!] The overlay must be apply on "cn=module{1}" for declaration + automatic appliance.
otherwise, if "cn=module{0}", the attribute will be supported but not automaticaly used.
[!] Don't forget the empty line at the end
Apply configuration
ldapadd -Q -Y EXTERNAL -H ldapi:/// -f memberof.ldif
service slapd restart
Check results
cat /etc/ldap/slapd.d/cn=config/cn=module{1}.ldif
"Referential integrity" overlay
When enabled, Referential integrity plug-in performs integrity updates on specified attributes immediately after a delete, rename, or move operation.
=> It will apply the "memberOf" on user + "member" on group automaticaly
Module setup
Create the module configuration's file:
cd /etc/ldap
vim referential_integrity.ldif
Put the following content:
dn: cn=module,cn=config
cn: module
objectClass: olcModuleList
objectClass: top
olcModuleLoad: refint.la
olcModulePath: /usr/lib/ldap
dn: olcOverlay={1}refint,olcDatabase={1}hdb,cn=config
objectClass: olcConfig
objectClass: olcOverlayConfig
objectClass: olcRefintConfig
objectClass: top
olcOverlay: {1}refint
olcRefintAttribute: memberof member manager owner
[!] Don't forget the empty line at the end
[!] Unlike "memberOf" you don't need to specify the "cn=module{x}" you can let OpenLDAP decides it for you (== it should be module{2} then !)
Apply configuration
ldapadd -Q -Y EXTERNAL -H ldapi:/// -f referential_integrity.ldif
service slapd restart
Check results
cat /etc/ldap/slapd.d/cn=config/cn=module{2}.ldif
Maintenance operations
Know your configuration
Display LDAP configuration's structure
find /etc/ldap/slapd.d/ | sed 's/[^/]*\//| /g;s/| *\([^| ]\)/+--- \1/'
Export database
The whole database may be exported as ldif file using this command:
slapcat
Get current configuration:
slapcat –b cn=config
Test
Install a LDAP client and test to access the server. It should be OK ! ^-^
See the following page to get more information: LDAP client
Installation # Encryption – SSL
By default OpenLDAP communication is not encrypted. Therefore, if some user have clear password anyone can used them.
Generate server certificates
See SSL server documentation to generate a certificate for the current server.
-- Hints --
- Do not encrypt your private key
- You cannot generate 2 certificates with the same server name.
If you already have a server certificate for the current FQDN, please use it!
Make files accessible for OpenLDAP
You have to copy your server private key + server certificate and CA certificate.
mkdir /etc/ldap/ssl
cd /etc/ldap/ssl
cp /srv/ssl/private/ldapServer.nopass.key ldapServer.key
cp /srv/ssl/certs/ldapServer.cert.pem ldapServer.pem
cp /srv/ssl/cacerts.pem .
chown -R root:openldap /etc/ldap/ssl
... Symlink might work but you can have some rights issues. It's just simpler - in my case - to copy the data.
Register certificates
SLAPD service
Since OpenLDAP 2.4 there is no more "slapd.conf" file.
All the configuration is now dynamic and set in database.
Create the .ldif file
vim /etc/ldap/slapd.d/tls.ldif
Add the following params:
dn: cn=config
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/ldap/ssl/cacerts.pem
-
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ldap/ssl/ldapServer.pem
-
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ldap/ssl/ldapServer.key
Adjust rights
chown openldap:openldap /etc/ldap/slapd.d/tls.ldif
Apply the configuration
ldapmodify -Y EXTERNAL -H ldapi:/// -f /etc/ldap/slapd.d/tls.ldif
Allow TLS protocol
vim /etc/default/slapd
Add the "ldaps" protocol (line 24):
SLAPD_SERVICES="ldap:/// ldapi:/// ldaps:///"
# For more security you can now restrict the LDAP to localhost
SLAPD_SERVICES="ldap://127.0.0.1:389/ ldaps:/// ldapi:///"
Restart the service
/etc/init.d/slapd restart
OpenLDAP configuration
Edit the LDAP configuration
vim /etc/ldap/ldap.conf
Adjust the TLS certificate path
TLS_CACERT /etc/ldap/ssl/cacerts.pem
You have to use the same as before in the "slapd" configuration.
Restart service
service slapd restart
Now you can connect to the server on port 686 and test your LDAP server over TLS!
Bonus
Now you can edit your firewall and close the port 389
Populate the LDAP db (manual)
Create root schema
cd /etc/ldap
vim daxiongmao.eu_core.ldif
Put the following and adjust:
- Domain name (here it's daxiongmao.eu)
- Admin password (here it's PASSWORD_ADMIN)
##### LDAP domain declaration
dn: dc=daxiongmao,dc=eu
objectClass: top
objectClass: dcObject
objectclass: organization
o: Server Organization
dc: Daxiongmao
description: Daxiongmao.eu root LDAP
#### Admin user
dn: cn=admin,dc=daxiongmao,dc=eu
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
userPassword: PASSWORD_ADMIN
#### People
# List of LDAP users. An user can be a human or a service account
dn: ou=people,dc=daxiongmao,dc=eu
objectClass: organizationalUnit
ou: people
#### Groups
dn: ou=groups,dc=daxiongmao,dc=eu
objectClass: organizationalUnit
ou: groups
#### Locations
dn: ou=locations,dc=daxiongmao,dc=eu
objectClass: organizationalUnit
ou: locations
#### hosts
dn: ou=hosts,dc=daxiongmao,dc=eu
objectClass: organizationalUnit
ou: hosts
[!] Don't forget the empty line at the end of the file
Apply schema
ldapadd -x -D cn=admin,dc=daxiongmao,dc=eu -W -f daxiongmao.eu_core.ldif
Create users
cd /etc/ldap
vim daxiongmao.eu_users.ldif
Put and adjust the following:
- user name
- User password
- UID number (it must be unique)
- UID must match the beginning of the dn (uid=)
#### Users list
dn: uid=guillaume.diaz,ou=people,dc=daxiongmao,dc=eu
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: guillaume.diaz
sn: Diaz
givenName: Guillaume
cn: Guillaume Diaz
displayName: Guillaume Diaz
initials: GD
mail: guillaume@qin-diaz.com
title: System Administrator
uidNumber: 1000
gidNumber: 10000
userPassword: PASSWORD_GUILLAUME
loginShell: /bin/bash
homeDirectory: /home/guillaume.diaz
shadowExpire: -1
shadowFlag: 0
dn: uid=jenkins,ou=people,dc=daxiongmao,dc=eu
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: jenkins
sn: Jenkins
cn: Jenkins
displayName: Jenkins
initials: CI
uidNumber: 1001
gidNumber: 10000
userPassword: PASSWORD_JENKINS
shadowExpire: -1
shadowFlag: 0
shadowWarning: 7
[!] Note that the GID 10000 is not important. This group doesn't even exists !! You can adjust it later on.
Apply changes
ldapadd -x -D cn=admin,dc=daxiongmao,dc=eu -W -f daxiongmao.eu_users.ldif
Create a group
By default OpenLDAP will create posixGroup (~ Unix like).
Those are nice but they do NOT support the membership relations. That's a very big limitation !! :(
You should always create groupOfNames instead of posixGroup !!
cd /etc/ldap
vim daxiongmao.eu_groups.ldif
Put and adjust the following:
- group name
dn: cn=users,ou=groups,dc=vehco,dc=com
objectClass: groupofnames
cn: users
description: Domain users (humans). This is the list of all the users that are allowed on the domain
member: uid=guillaume.diaz,ou=people,dc=vehco,dc=com
dn: cn=services,ou=groups,dc=vehco,dc=com
objectClass: groupofnames
cn: services
description: Group for application's users
member: uid=jenkins,ou=people,dc=daxiongmao,dc=eu
dn: cn=ssh-users,ou=groups,dc=vehco,dc=com
objectClass: groupofnames
cn: ssh-users
description: SSH users
member: uid=guillaume.diaz,ou=people,dc=vehco,dc=com
Apply changes
ldapadd -x -D cn=admin,dc=daxiongmao,dc=eu -W -f daxiongmao.eu_groups.ldif
Populate LDAP db (graphical)
Use your favorite LDAP client (see LDAP client) to populate the LDAP registry.
Create Organizational Units
I advised you to create the following OU=
Organization | Description |
---|---|
OU=people | for users |
OU=groups | IT | company | project groups |
OU=locations | specific area |
OU=applications | for applications' virtual users |
Create Groups
In the "OU=groups" create:
Group | Description |
---|---|
CN=users | domain users |
CN=administrators | for system administrators |
CN=services | System and services accounts |
Create locations
Under 'locations' create a location for each office | home | place that you'll have in your registry.
In the "OU=location" create:
Location | Description |
---|---|
l=France | French users |
l=Sweden | Swedish users |
Create Users
- Inside ou=people create a new UID for each user + make that user a member of OU=groups,CN=users
- Inside ou=applications create a new UID for each application or service that will use the LDAP + make that a member of OU=groups,CN=services
Example of minimal structure:
Apache 2
See Apache 2 documentation to get more info: Apache 2 - LDAP access
References
LDAP explanations (French):
- http://www-sop.inria.fr/members/Laurent.Mirtain/ldap-livre.html
- http://www-sop.inria.fr/members/Laurent.Mirtain/ldap-slide.pdf
Overlays "memberOf" + "refint" :
- http://www.schenkels.nl/2013/03/how-to-setup-openldap-with-memberof-overlay-ubuntu-12-04/
- http://technicalnotes.wordpress.com/2014/04/19/openldap-setup-with-memberof-overlay/
LDAP howTo (french)