To use OpenLDAP for authentication on FreeBSD, we're going to need to customize our cosine.schema, and install/configure a few additional ports.
First, we need to install the following ports:
Once the above ports are installed, we need to build our ldap.conf file. What's interesting is that Luke H over at PADL Software, Ltd has done, is made his pam_ldap module configuration compatible with OpenLDAP's configuration. The end result is both pieces of software will use /usr/local/etc/ldap.conf. nss_ldap also follows this pattern.
A good ldap.conf file to use is as follows:
# LDAP Configuration uri ldap://ldap.example.com base dc=example,dc=com ldap_version 3 ssl start_tls tls_checkpeer no tls_ciphers TLSv1 TLS_CACERT /usr/local/etc/ca.crt nss_base_netgroup cn=group,dc=example,dc=com nss_base_group ou=group,dc=example,dc=com
The config above has the following effect:
- use ldap server at ldap.example.com
- use dc=example,dc=com for the search base
- connects with ldap version 3 only
- issues a start_tls command to encrypt the connection
- instructs pam_ldap to accept the certificate
- set tls_ciphers to TLS version 1
- uses the ca certificate found in /usr/local/etc/openldap/ca.crt to verify the server's certificate
- gets group names from cn=group,dc=example,dc=com (finger,pw, directory listings, etc)
- gets group names from ou=group,dc=example,dc=com
uri ldap://ldap.example.com base ou=people,dc=example,dc=com ldap_version 3 ssl start_tls tls_checkpeer no tls_ciphers TLSv1
This config does the same things as above, specific to nss_ldap port.
## Define lookups for users and groups. passwd: files ldap group: files ldap ## Optimize the nss_ldap searches for these databases. #nss_base_passwd ou=staff,ou=people,dc=claimlynx,dc=com #nss_base_group ou=staff,ou=people,dc=claimlynx,dc=com group: compat group_compat: nis hosts: files dns networks: files shells: files
The part we're most concerned with is the first two non-comment lines. These tell the system to first look in files (/etc/master.passwd and /etc/group) for uid/gid and authentication, followed by ldap. The rest of the files is what was there by default.
The next task is to roll our changes into PAM so that it's using our LDAP installation for authentication. First, we're going to configure sshd:
Edit the /etc/pam.d/sshd file, and add the following lines in their respective places:
auth sufficient /usr/local/lib/pam_ldap.so no_warn try_first_pass account required /usr/local/lib/pam_ldap.so ignore_unknown_user ignore_authinfo_unavail session required /usr/local/lib/pam_mkhomedir.so
At this point, (no need to restart SSHd or anything), you should be able to log in via ssh to the newly configured host. In addition, you should be able to finger and pw to glean information out of LDAP regarding user accounts:
root@oliver:/etc/pam.d-> finger foobeans Login: foobeans Name: Eric F Crist Directory: /home/foobeans Shell: /bin/csh Office: x842, (411) 555-9000 Home Phone: (411) 555-1234 Last login Wed Apr 23 10:23 (CDT) on ttyp7 from nat.example.com No Mail. No Plan. root@oliver:/etc/pam.d-> pw usershow foobeans -P Login Name: foobeans #400 Group: (invalid) #400 Full Name: Eric F Crist Home: /home/foobeans Class: Shell: /bin/csh Office: x842 Work Phone: (411) 555-9000 Home Phone: (411) 555-1234 Acc Expire: [None] Pwd Expire: [None]
When you log in for the first time, pam_mkhomedir.so automatically creates the user's home directory. The last item to verify is that the home directory was created (/usr/home/<username>) and that it's owned by that user/group:
root@oliver:/etc/pam.d-> ls -lah /usr/home drwxr-xr-x 2 foobeans 400 512B Apr 23 10:23 foobeans
What you'll notice above is that the foobeans user ID is correctly mapped in LDAP, but I've yet to build the group subtree with user group names. As such, GID 400 doesn't map to a group name at this time.
Locking It Down
To further lock down your LDAP authentication scheme, I'd recommend you do host-based verification. This means that, if the user isn't listed as having access to a specific host, they'll be denied with the following error:
ecrist@redoct:~$ ssh foobeans@oliver Password: Access denied for this host Permission denied (publickey,keyboard-interactive).
Without this extra protection, ALL ldap users with a PosixAccount will be given shell access to ALL servers on your network using LDAP for authentication. The method described here lists hosts within a user's LDAP entry for hosts they have access to. An alternative, not covered here, is to enter hosts, with user entries for each user with access.
To get this host verification feature, we need to modify our OpenLDAP cosine.schema file on the OpenLDAP servers. This file can be found in /usr/local/etc/openldap/schema/cosine.schema.
Edit line 1113 (search for "objectclass ( 0.9.2342.19200300.100.4.5 NAME 'account'") and change "SUP top STRUCTURAL to SUP top AUXILIARY. Save the file and restart slapd (/usr/local/etc/rc.d/slapd restart).
Next, add the following line to /usr/local/etc/ldap.conf on all of your client systems:
No restart of anything needed for this change.
Lastly, we need to make certain the appropriate entry exists in the LDAP directory entry. You should now be able to add a host attribute (multiple host attributes are OK), with the FQDN for each host to give access to. From there you should be able to log into hosts you have access to, and be denied access to hosts that aren't explicitly allowed.