{{table_of_contents}}
This article provides an example of how to set up LDAP authentication and authorization on Cumulus Linux using Active Directory. It applies to any Debian Wheezy-based server or switch.
The method described in the article applies ONLY to Windows Server 2008. This method does not work as well with Windows Server 2012.
Prerequisites
- Windows 2008 Active Directory
- Cumulus Linux 2.x
Active Directory Setup
Base DN: CN=Cumulus Admin, DC=RTP, DC=Example, DC=test
Base OU: OU=Support, DC=RTP, DC=Example, DC=Test
Users and Groups: This example has three users that are allowed to access a Cumulus Linux switch. Two are in the senior network engineer group, one in the junior engineering group. The last user, Mark Smith, does not have access to the switches because he is not a member of the cumuluslnxadm group.
AD group layout of users
Layout of users and groups in AD schema
Goals
- Configure LDAP authentication without changing the default AD schema. (There is no need to apply the UNIX identities in Active Directory Domain Services.)
- Support nested groups. The following should work:
- User directories are automatically created the first time an authorized user logs into the switch.
- Senior network admins via
sudo
can run any command on the switch. - Junior network admins can:
- Log in and access any non-privileged command.
- Run
sudo lldpctl
without prompting for a password.lldpctl
is an important network troubleshooting tool, but requires root access. - Use all
ip
commands (iproute2 commands). - Not access Quagga via
vtysh
or non-modal CLI likecl-ospf.
Configuring Cumulus Linux
1. Update PAM to support automatic creation of directories(optional)
This information is from the Debian wiki. The alternative is to set the "homeDirectory" attribute for users in AD to "/home/cumulus", and all users will map to the pre-defined user account.
Create the following file /usr/share/pam-configs/mkhomedir
:
Name: Create home directory during login
Default: yes
Priority: 900
Session-Type: Additional
Session:
required pam_mkhomedir.so umask=0022 skel=/etc/skel
2. Add Debian backports to apt sources list (optional).
libnss-ldapd
version 0.9 and higher is needed for nested group support. For Wheezy, and thus Cumulus Linux 2.x, include Debian Wheezy backports to the apt
sources list.
3. Seed debconf with appropriate values (recommended).
Seeding debconf
is helpful because it adds most of the important configuration values in the various applications and prevents the apps from asking questions during the installation.
While it is possible to execute apt-get
in non-interactive mode, you will need to change most of the necessary config later.
Note: For
libnss-ldapd
, there are CPU architecture-specific questions to answer.
root# apt-get install debconf-utils
root# debconf-set-selections <<'zzzEndOfFilezzz'
# LDAP database user. Leave blank will be populated later!
# This way of setting binddn and bindpw doesn't seem to work.
# So have to manually do it. But interactive apt-get mode works.
nslcd nslcd/ldap-binddn string
# LDAP user password. Leave blank!
nslcd nslcd/ldap-bindpw password
# LDAP server search base:
nslcd nslcd/ldap-base string ou=support,dc=rtp,dc=example,dc=test
# LDAP server URI. Using ldap over ssl.
nslcd nslcd/ldap-uris string ldaps://myadserver.rtp.example.test
# New to 0.9. restart cron, exim and others libraries without asking
nslcd libraries/restart-without-asking: boolean true
# LDAP authentication to use:
# Choices: none, simple, SASL
# Using simple because its easy to configure. Security comes by using LDAP over SSL
# keep /etc/nslcd.conf 'rw' to root for basic security of bindDN password
nslcd nslcd/ldap-auth-type select simple
# Don't set starttls to true
nslcd nslcd/ldap-starttls boolean false
# Check server's SSL certificate:
# Choices: never, allow, try, demand
nslcd nslcd/ldap-reqcert select never
# Choices: Ccreds credential caching - password saving, Unix authentication, LDAP Authentication , Create home directory on first time login, Ccreds credential caching - password checking
# This is where "mkhomedir" pam config is activated that allows automatic creation of home directory
libpam-runtime libpam-runtime/profiles multiselect ccreds-save, unix, ldap, mkhomedir , ccreds-check
# for internal use; can be preseeded
man-db man-db/auto-update boolean true
# Name services to configure:
# Choices: aliases, ethers, group, hosts, netgroup, networks, passwd, protocols, rpc, services, shadow
libnss-ldapd libnss-ldapd/nsswitch multiselect group, passwd, shadow
libnss-ldapd libnss-ldapd/clean_nsswitch boolean false
zzzEndOfFilezzz
Verify the debconf
configuration:
root# debconf-show nslcd
* nslcd/ldap-bindpw: (password omitted)
nslcd/restart-failed:
nslcd/ldap-sasl-authcid:
nslcd/restart-services:
nslcd/ldap-sasl-realm:
* nslcd/ldap-sasl-mech:
* nslcd/ldap-starttls: false
* nslcd/ldap-base: ou=support,dc=rtp,dc=example,dc=test
nslcd/ldap-sasl-krb5-ccname: /var/run/nslcd/nslcd.tkt
* nslcd/ldap-auth-type: none
nslcd/disable-screensaver:
* libraries/restart-without-asking: true
* nslcd/ldap-reqcert: never
nslcd/ldap-cacertfile: /etc/ssl/certs/ca-certificates.crt
nslcd/ldap-sasl-authzid:
* nslcd/ldap-uris: ldaps://myadserver.rtp.example.test
* libraries/restart-without-asking:: true
nslcd/ldap-sasl-secprops:
nslcd/xdm-needs-restart:
* nslcd/ldap-binddn:
root# debconf-show libpam-runtime
libpam-runtime/override: false
libpam-runtime/profiles: mkhomedir, unix, ldap, capability, auditd
libpam-runtime/title:
libpam-runtime/conflicts:
libpam-runtime/no_profiles_chosen:
root# debconf-show man-db
* man-db/auto-update: true
man-db/install-setuid: false
root# debconf-show libnss-ldapd
* libnss-ldapd/nsswitch: group, passwd, shadow
* libnss-ldapd/clean_nsswitch: false
4. Install LDAP apps.
libnss-ldapd
from the Wheezy main repo does not support nested groups. Load the libnss-ldapd
app from backports to get the latest available version.
Note: Do not install
libnss-ldap
. This is the wrong app, and this explains why.
root# apt-get -t wheezy-backports install libnss-ldapd ldap-utils
5. Get the Active Directory Domain SID.
Use the dsquery
command on the Windows server to get the domain SID. For more information, read this good reference on Object SIDs.
6. Configure nslcd.conf.
Update /etc/nslcd.conf
with the following:
- Specify the Bind DN path.
- Specify the Bind DN password.
- Configure LDAP search filter. The filter states that only users in the cumuluslnxadm group are allowed to log in. The search filter performs the nested group lookup.
- Configure Unix to AD mappings.
- Configure nested group support.
Here is the /etc/nslcd.conf
config with comments:
# /etc/nslcd.conf
# nslcd configuration file. See nslcd.conf(5)
# for details.
# The user and group nslcd should run as.
uid nslcd
gid nslcd
# The location at which the LDAP server(s) should be reachable.
# If planning to use secure LDAP, use fqdn that matches name
# in the server SSL cert sent during negotiation. Debugging
# nslcd will show this error if found
uri ldap://myadserver.rtp.example.test
# The search base that will be used for all queries.
base ou=support,dc=rtp,dc=example,dc=test
# The LDAP protocol version to use.
#ldap_version 3
# The DN to bind with for normal lookups.
# defconf-set-selections doesn't seem to set this. so have to manually set this.
binddn CN=cumulus admin,CN=Users,DC=rtp,DC=example,DC=test
bindpw 1Q2w3e4r!
# The DN used for password modifications by root.
#rootpwmoddn cn=admin,dc=example,dc=com
# SSL options
#ssl off (default)
# default tls setting of 'demand' requires CA public cert
# for AD server be defined in "tls_cacertfile"
# use PEM format for CA cert, not DER format.
tls_reqcert never
#tls_cacertfile /etc/ssl/certs/ca-certificates.crt
# The search scope.
#scope sub
# Add nested group support
# Supported in nslcd 0.9 and higher.
# default wheezy install of nslcd supports on 0.8. wheezy-backports has 0.9
nss_nested_groups yes
# Mappings for Active Directory
# (replace the SIDs in the objectSid mappings with the value for your domain)
# "dsquery * -filter (samaccountname=testuser1) -attr ObjectSID"
pagesize 1000
referrals off
idle_timelimit 1000
# Do not allow uids lower than 100 to login (aka Administrator)
# not needed as pam already has this support
# nss_min_uid 1000
# This filter says to get all users who are part of the cumuluslnxadm group. Supports nested groups search filter.
# Example, mary is part of the snrnetworkadm group which is part of cumuluslnxadm group
# Ref: http://msdn.microsoft.com/en-us/library/aa746475%28VS.85%29.aspx (LDAP_MATCHING_RULE_IN_CHAIN)
filter passwd (&(Objectclass=user)(!(objectClass=computer))(memberOf:1.2.840.113556.1.4.1941:=cn=cumuluslnxadm,ou=groups,ou=support,dc=rtp,dc=example,dc=test))
map passwd uid sAMAccountName
map passwd uidNumber objectSid:S-1-5-21-1391733952-3059161487-1245441232
map passwd gidNumber objectSid:S-1-5-21-1391733952-3059161487-1245441232
map passwd homeDirectory "/home/$sAMAccountName"
map passwd gecos displayName
map passwd loginShell "/bin/bash"
# Filter for any AD group or user in the baseDN. the reason for filtering for the
# user to make sure group listing for user files don't say '<user> <gid>'. instead will say '<user> <user>'
# So for cosmetic reasons..nothing more.
filter group (&(|(objectClass=group)(Objectclass=user))(!(objectClass=computer)))
map group gidNumber objectSid:S-1-5-21-1391733952-3059161487-1245441232
map group cn sAMAccountName
7. Enabling Secure LDAP (optional)
- Copy the LDAP CA certificate (in PEM format) to the directory, specified in the nslcd.conf
tls_cacertfile
option, on the client device. Ensure the file specified matches the filename copied. - Set the
tls_reqcert
option todemand
. - Change the URI to use ldaps://...
8. Confirm that LDAP authentication works.
- Restart the
nscd
service usingservice nscd restart
to clear the cache. This can cache a mistake and then you can spend hours troubleshooting a problem that doesn't exist. Alternatively, clear the nscd cache for passwd and group using the commands:
root# nscd --invalidate=group
root# nscd --invalidate=passwd
- Run
nslcd
in debug mode.
root# service nslcd stop
root# nslcd -d
-
When it works, it should output as follows:
user list: The UID and GIDs are the last 4 digits of the user's AD object SID. Notice that "Mark Smith" the support manager is not there. This is because the user is not part of thecumuluslnxadm
group.root# getent passwd root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/bin/sh ... .......... _lldpd:x:105:107::/var/run/lldpd:/bin/false joechen:*:1121:1121:Joe Chen:/home/joechen:/bin/bash marydiho:*:1124:1124:Mary Diho:/home/marydiho:/bin/bash obidia:*:1128:1128:Obi Dia:/home/obidia:/bin/bash
group list: GIDs of each user should be present. Because nested group support is enabled, all nested groups are mapped to the right users.
root# getent group .. ..... ssh:x:105: nslcd:x:106 _lldpd:x:107: joechen:*:1121: marydiho:*:1124: marksmith:*:1125: obidia:*:1128: jnrnetworkadm:*:1118:obidia cumuluslnxadm:*:1120:obidia,marydiho,joechen snrnetworkadm:*:1126:marydiho,joechen
9. Set up command authorization (optional).
To do authorization with nslcd, creating entries on the client device will match against the LDAP information cached. To accomplish this, it is required to install the sudo-ldap
package from the Wheezy repo.
In this example, we will create the following authorizations:
- Senior engineers can run any privileged and non-privileged command.
- Junior engineers can run
lldpctl
without a password. By default,lldpctl
requires root access.
Add two files to the /etc/sudoers.d
directory, one for senior engineers and the other for junior engineers. This can be configured in the /etc/sudoers file, but this keeps things modular.
/etc/sudoers.d/snrnetworkadm:
# allow any senior engineer root privilege after they type their password
%snrnetworkadm ALL=(ALL) ALL
/etc/sudoers.d/jnrnetworkadm:
Cmnd_Alias LLDP_CMDS = /usr/sbin/lldpctl
# allow any junior network engineer to run lldpctl without root permission
%jnrnetworkadm ALL=(ALL) NOPASSWD: LLDP_CMDS
Automate it: Ansible Playbook
Available on github.com and Ansible Galaxy is an Ansible Playbook that automates the configuration shown in this article.
Comments