- Openldap Tutorial – Practical Realtime Implementation and Integration
- Installation and configuration of openldap in Ubuntu
- Installing phpLDAPadmin – Web based LDAP Client
- Planning of LDAP DIT Structure and Config of Overlays ( access, ppolicy )
- OpenLDAP – Graylog LDAP Integration
- openLDAP – Linux Client LDAP Integration
- openLDAP – Basic Authentication using LDAP
- openLDAP – Self Service Password and Adhoc LDAP utilities
In the previous article we saw how to integrate Graylog with LDAP. In this section we will discuss about Linux client LDAP Integration.
What we will do ?
Based on our scenario, we will implement key based authentication to a linux client connected to LDAP. Like previous examples, two users will have access to the server. One of the user is an admin and will have sudo privileges. The other will be considered a Dev user, who has sudo access only to a specific application id ( appid )
We first need to create a separate group for managing access to servers. Let’s get our hands dirty and start doing it.
We have already got few containers and entries created in the previous section when we integrated Graylog with LDAP. We need to create the ones marked in dotted red boundaries in the diagram above.
Create a container ( ou=server ) for managing servers
Create a file named serverou.ldif with the below content,
dn: ou=server,ou=group,dc=devopsideas,dc=com objectClass: organizationalUnit ou: server description: Group for managing servers
Run the below command to implement the change,
ldapadd -Z -W -D cn=admin,dc=devopsideas,dc=com -f serverou.ldif
Overcoming posixGroup and groupOfNames caveat
We will be creating server group objects of type posixGroup under ou=server container. The posixgroup is required to provide the translation between group id numbers and their name. We’ll be providing access to servers based on membership of the groups. posixGroup’s member attribute is called memberUID and simply lists the uid of the member. Using this alone, there’s really no solid way to identify the specific distinguished name of the group member.
The problem we have is, memberOf attribute is part of groupOfNames objectClass. We cannot use both posixGroup and groupOfNames together since both are STRUCTURAL objectClasses ( An entry can have only one STRUCTURAL object class ).
To overcome this, we need to create a custom objectClass that will be a clone of posixGroup but of type AUXILIARY instead of STRUCTURAL. Hence we will be able to use groupOfNames along with the custom posixGroup which is almost identical to posixGroup except the class type.
The posixGroup exists in nis schema and hence we’ll make the change there.
Create a file named schema_update.ldif with the below content
dn: cn={2}nis,cn=schema,cn=config
changetype: modify
add: olcObjectClasses
olcObjectClasses: {13}( 1.3.6.1.1.1.2.13 NAME 'customposixGroup' DESC 'Abstraction of a group of accounts' AUXILIARY MUST ( cn $ gidNumber ) MAY ( userPassword $ memberUid $ description $ member ) )
{2} denotes the order. You can refer ‘/etc/ldap/slapd.d/cn\=config/cn\=schema’ to get this.
We have named the custom group as customposixGroup. This contains all the attributes that are part of posixGroup except the class type marked as ‘AUXILIARY’.
Run the below command to make the changes,
ldapmodify -W -D cn=admin,cn=config -f schema_update.ldif
Create the server group entries within ou=server container
Create a file named server_group.ldif and copy the below content.
dn: cn=server_admin,ou=server,ou=group,dc=devopsideas,dc=com objectclass: customposixGroup objectclass: groupOfNames cn: server_admin gidNumber: 5000 description: Server Admin Group member: cn=chris.sam,ou=people,dc=devopsideas,dc=com dn: cn=server_dev,ou=server,ou=group,dc=devopsideas,dc=com objectclass: customposixGroup objectclass: groupOfNames cn: server_dev gidNumber: 6000 description: Server Dev Group member: cn=aron.francis,ou=people,dc=devopsideas,dc=com
We are using customposixGroup and groupOfNames as objectClass. As part of creating this entry we are adding members to it. chris.sam is added as part of server_admin and aron.francis is added as part of server_dev group.
The gidNumber represents the Group id in the server. We are giving higher numbers for this to be safe from conflicting with the local gid’s in the server.
Implement the change by running the below command,
ldapadd -W -Z -D cn=admin,dc=devopsideas,dc=com -f server_group.ldif
We have now completed adding group entries inside ou=server container.
Service id for Linux Client binding
Create a service id cn=serverid,ou=service_ids,dc=devopsideas,dc=com, for binding LDAP clients. Since we need to specify password for this, we’ll create password hash first,
$ slappasswd -h {SHA} -s <password> {SHA}qUqP5cyxm6YcTAhz05Hph5gvu9M=
Create a file named serverid.ldif with the below content.
dn: cn=serverid,ou=service_ids,dc=devopsideas,dc=com cn: serverid givenName: Server ID sn: id uid: serverid objectClass: top objectClass: inetOrgPerson objectClass: person userPassword: {SHA}qUqP5cyxm6YcTAhz05Hph5gvu9M=
Run the below command to import the change,
ldapadd -W -Z -D cn=admin,dc=devopsideas,dc=com -f serverid.ldif
If you recollect, we have set a separate password policy for service id’s and we need to apply that for this id. Create a file named serverid_ppolicy.ldif with the below content.
dn: cn=serverid,ou=service_ids,dc=devopsideas,dc=com changetype: modify add: pwdPolicySubentry pwdPolicySubentry: cn=servicePasswordPolicy,ou=pwpolicies,dc=devopsideas,dc=com
Run the below command,
ldapmodify -W -Z -D cn=admin,dc=devopsideas,dc=com -f serverid_ppolicy.ldif
The serverid DN will now have ‘cn=servicePasswordPolicy,ou=pwpolicies,dc=devopsideas,dc=com’ as its password policy definition
Update schema to enable sshPublicKey attribute
Since we will implement key based authentication, we need an attribute that can store public key of the user. There is no attribute available by default to store the public key. Hence we need to define a schema for the same and create an attribute to store the key.
Create a file named publickey.ldif with the below content,
dn: cn=openssh-lpk,cn=schema,cn=config objectClass: olcSchemaConfig cn: openssh-lpk olcAttributeTypes: ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey' DESC 'MANDATORY: OpenSSH Public key' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) olcObjectClasses: ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY DESC 'MANDATORY: OpenSSH LPK objectclass' MAY ( sshPublicKey $ uid ) )
Run the below command to implement the change,
ldapadd -W -D cn=admin,cn=config -f publickey.ldif
We have created an attributed named ‘ldapPublicKey’ to store the ssh public key of the users.
Update user entry with posixGroup and ldapPublicKey
We already have user entries created with inetOrgPerson objectClass. We further need posixGroup & ldapPublicKey added as part of the entries to get attributes that will be used for working with Linux clients.
Create a file named usermod.ldif and copy the below content
dn: cn=chris.sam,ou=people,dc=devopsideas,dc=com changetype: modify add: objectClass objectclass: posixAccount - add: homeDirectory homeDirectory: /home/chris.sam - add: loginShell loginShell: /bin/bash - add: uidNumber uidNumber: 5000 - add: gidNumber gidNumber: 5000 - add: uid uid: chris.sam - add: objectClass objectclass: ldapPublicKey - add: sshPublicKey sshPublicKey: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMhJyIJ66E4uEU6N309afcc2RrF3n+38AQaf4e4IItuotD7b0K/JM4XdpnbNfOUmXSqOpOaCKnBdP6d7TBQVq5ChxMOtAvvNwmOtgzIJNCIPLD7aVHekO3MNgLwqlkDGXEoO3HjcJpoZhWLpHNOopiPp2yJcfFXA6twhKf9Dqbl+1XT4mDeyF7Fg0/y1JIkBQEraCFywHzsWTuQTc5u7Ve6kQMlEOP5np13e+hQJ7lQUxsFvnO59W4Th/4Uyimp2G32nfuy3p6pF6iwZD6QuD/iIFvmaYDh1MsXGcMPrP1M8ewhknEWn4mgxJVvb/zq2R74FSB5azg5yO1VyI9lN6R dn: cn=aron.francis,ou=people,dc=devopsideas,dc=com changetype: modify add: objectClass objectclass: posixAccount - add: homeDirectory homeDirectory: /home/aron.francis - add: loginShell loginShell: /bin/bash - add: uidNumber uidNumber: 6000 - add: gidNumber gidNumber: 6000 - add: uid uid: aron.francis - add: objectClass objectclass: ldapPublicKey - add: sshPublicKey sshPublicKey: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDD2A/ApDfwnlHDmzJ1SefYSgd3x/BPqltQ3kO4EmpUDpE6CZJL+RVaTq19lOzpqnLOAx7qM5qS6rsfPzE2UxfTmMM4PWeBe+M5ypCMp7yQgXoJkxX90sTM5KRv5Bj9WauF56ZK+PiFqQzuE1cWnt7Owwnki4aTEvwY+vtWFcHy4KLrVzML0Y5ldsshp1l0o3Qj69smsAbCto76lEG5fXCfZ0XELXSKKQdiBqdQqz+dhi1slZDSt8n0azyQSTqWR1nXNuLd5HfveT+VGq9/HuNkriKUV94RzYjrkGJXlqsaa24vRY21tKqKgw3rGHrWml1g6yNVqg24kGrezlxVO3Hd
We have included new objectClasses to our user entries. We have also specified the required attributes of those entries. In short,
- We have specified the homeDirectory , loginShell, uid and gid of the user
- We have also added the user ssh keys as part of sshPublicKey attribute.
We have everything configured at LDAP server end and we are good to configure our Linux client now.
Configure Linux Client
Run the below commands to install the necessary packages in Linux Client.
apt-get -y install libpam-ldap nscd ldap-utils libnss-ldapd
You’ll be asked series of questions similar to those installed during LDAP server.
1) First prompt relates to nlscd configuration. Provide the LDAP server domain name or IP address.
2) Next, enter the distinguished name of the LDAP server. dc=devopsideas,dc=com in this case.
3) Next configuration is for libnss-ldapd. Select the services for which LDAP lookups should be enabled. We are enabling for passwd, group and shadow service in this example.
4) Next, enter the LDAP URI. ( ldap://ldap.devopsideas.com)
5) The next configuration is for ldap-auth-config. Enter the DN of the LDAP search again ( dc=devopsideas,dc=com)
6) Select the LDAP version – v3
7) Select ‘No’ for the next option to store password locally.
8) Select ‘Yes’ for the next option
9) Provide the DN of the serverid which we created earlier,
10) Enter the password of the serverid
Install the other required packages,
apt-get -y install python-pip python-ldap apt-get install libsasl2-dev python-dev libldap2-dev libssl-dev pip install ssh-ldap-pubkey
We must configure OpenSSH to fetch the keys from OpenLDAP. Add the following lines to /etc/ssh/sshd_config:
AuthorizedKeysCommand /usr/local/bin/ssh-ldap-pubkey-wrapper AuthorizedKeysCommandUser nobody
Restart ssh service,
service ssh restart
Configure PAM
1) Edit /etc/pam.d/common-auth and add the following line:
account required pam_access.so
2) Edit /etc/pam.d/common-password and remove use_authtok parameter
3) To automatically create home directories when users log in, edit /etc/pam.d/common-session and add the following line:
session required pam_mkhomedir.so skel=/etc/skel umask=0022
Configure ldap client to use startTLS
1) Copy the cacert.pem generated in the LDAP server. ( Refer Enabling and Enforcing TLS section in this article ).
mkdir /etc/ldap/certs # Assuming you have copied the cert from LDAP server to the client in /tmp cp /tmp/cacert.pem /etc/ldap/certs/
2) Edit /etc/ldap.conf file and make the following changes,
# Uncomment start_tls ssl start_tls # uncomment tls_checkpeer tls_checkpeer yes tls_cacertfile /etc/ldap/certs/cacert.pem
3) Edit /etc/ldap/ldap.conf and change the value of TLS_CACERT to point to cacert.pem
TLS_CACERT /etc/ldap/certs/cacert.pem
Configure nslcd
nslcd is a daemon that will do LDAP queries for local processes based on a simple configuration file. nslcd is configured through a configuration file nslcd.conf. We will using filter to implement access control.
Edit the nslcd configuration file /etc/nslcd.conf and it should contain the below content.
uid nslcd gid nslcd uri ldap://ldap.devopsideas.com/ base ou=people,dc=devopsideas,dc=com binddn cn=serverid,ou=service_ids,dc=devopsideas,dc=com bindpw <serverid-password> ssl start_tls tls_reqcert demand tls_cacertfile /etc/ldap/certs/cacert.pem tls_cacertdir /etc/ldap/certs filter passwd (&(objectClass=posixAccount)(|(memberOf=cn=server_dev,ou=server,ou=group,dc=devopsideas,dc=com)(memberOf=cn=server_admin,ou=server,ou=group,dc=devopsideas,dc=com))) base group ou=server,ou=group,dc=devopsideas,dc=com filter group (&(objectClass=posixGroup)(cn=server*))
Take a look at the filter section. We are filtering users based on objectClass of type posixAccoung and they should be member of either server_dev or server_admin group
We are also filtering and importing group in order to use it locally to provide sudo access.
Do a restart of the nslcd service for the changes to take effect
service nslcd restart
Test your access
We have completed the Linux client and LDAP integration. Try accessing the linux client from your local where you have the keys. You should be able to access the server now.
ssh [email protected] chris.sam@web:~$ chris.sam@web:~$ id uid=5000(chris.sam) gid=5000(server_admin) groups=5000(server_admin)
If you are not able to login, check the syslog of LDAP server and see if you get any errors. Try troubleshooting based on the error code.
The id command reveals that the user is part of server_admin which we created in LDAP. This gets fetched from the group filter specified in the nslcd.conf file
Configure sudo access
We can’t do anything much with the present configuration. The user can only login with their id’s but they cannot perform any operations like deploying new code, make configuration changes, restarting service etc.
For this example, we will consider the application is owned by an application id (appid). The Dev user should have access to switch only to this id. On the other hand the Admin user should have complete sudo access. We will achieving this by editing sudoers file and adding relevant permission to the groups that we got through the group filter in nslcd configuration
Run visudo to edit the sudoers file and add the below content
Defaults env_reset Defaults mail_badpass Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" # User privilege specification root ALL=(ALL:ALL) ALL # Access for appid for server_dev users %server_dev ALL=(appid) ALL # Sudo access ofr server_admin users %server_admin ALL=(ALL:ALL) ALL # Members of the admin group may gain root privileges %admin ALL=(ALL) ALL # Allow members of group sudo to execute any command %sudo ALL=(ALL:ALL) ALL
The content highlighted in blue are the ones we have added additionally. We have specified that users belonging to server_admin will have sudo access and user part of server_dev will have access to switch only to appid
For eg, the aron.francis belongs to server_dev group. Hence in order to switch to appid, he has to run
sudo -u appid -i
Well Done!! We have successfully integrated Linux client with LDAP.