HOWTO setup ldap authentication

From Chaos

Jump to: navigation, search
This article is part of the HOWTO series.

Contents

Summary

This is an article designed to quickly and efficiently list what changes need to be made on a Linux server to allow pam_ldap, nss_ldap, Apache, Samba, and Sudo authentication via an OpenLDAP server, as well as enable password management (passwords are valid for 365 days, then they must be reset), and secure everything with SSL.

Caveats

This article assumes the following:

  • You already have a working LDAP server with users and groups pre-populated.
  • You have a good understanding of how Linux is laid out.
  • Any software that you want to authenticate via LDAP is compiled with LDAP support. This includes, but is not limited to:
    • Apache
    • phpldapadmin
    • Samba
    • smbldap-tools
    • nss_ldap
    • pam_ldap
    • sudo
    • easy-rsa (for certificate management)
  • All of the steps below are Gentoo-centric. They will work for just about any Linux distro (even BSD's), as long as you find the same files and make the same modifications. YMMV.

Easy RSA

You'll have to generate a SSL server certificate and key (ending in .crt and .key) for the OpenLDAP server, as well as the root CA authority file (ca.crt). This isn't an easy-rsa HOWTO, so you're on your own. The files I will be referencing are throughout this article are:

  • /etc/openldap/ssl/ca.crt -- Certificate Authority File
  • /etc/openldap/ssl/ldap.mycompany.net.crt -- Server Certificate File
  • /etc/openldap/ssl/ldap.mycompany.net.key -- Server Private Key File

OpenLDAP

You will need to initially setup OpenLDAP with both port 389 (unencrypted) and 636 (encrypted). This will ensure you can do debugging on port 389, and see if there's anything wrong (when you do tcpdump, all LDAP traffic will be unencryted, making it much easier to debug). When the time comes though, you'll need to disable unencrypted communication on port 389 (it will still use TLS only), and use SSL on 636.

If you want to easily check and see if your LDAP server has the right certificate configured for SSL, run this command:

SSL on port 636: openssl s_client -connect ldap.mycompany.net:636

slapd.conf

Of course, you are going to store Samba and Sudoers in your LDAP directory, as well as standard PAM users. Ensure your config looks like this:

#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#
# These includes are a part of the base OpenLDAP distribution.
include         /etc/openldap/schema/core.schema
include         /etc/openldap/schema/cosine.schema
include         /etc/openldap/schema/inetorgperson.schema
include         /etc/openldap/schema/nis.schema
include         /etc/openldap/schema/ldapns.schema
include         /etc/openldap/schema/samba.schema
include         /etc/openldap/schema/sudo.schema

# Load dynamic backend modules:
modulepath      /usr/lib/openldap/openldap
# moduleload    back_shell.so
# moduleload    back_relay.so
# moduleload    back_perl.so
# moduleload    back_passwd.so
# moduleload    back_null.so
# moduleload    back_monitor.so
# moduleload    back_meta.so
moduleload      back_hdb.so
# moduleload    back_dnssrv.so

# Sample security restrictions -- Require port 389 to be TLS encrypted
# WARNING: DISABLE THIS INITIALLY FOR TESTING, THEN ENABLE
#       Require integrity protection (prevent hijacking)
#       Require 112-bit (3DES or better) encryption for updates
#       Require 63-bit encryption for simple bind
security ssf=127 update_ssf=127 simple_bind=127

# Logging configuration. Enable this for debugging.
loglevel none

# SSL configuration. See the section on easy-rsa to generate the certificates and keys.
TLSCipherSuite HIGH:MEDIUM:-SSLv2
TLSCACertificateFile /etc/openldap/ssl/ca.crt
TLSCertificateFile /etc/openldap/ssl/ldap.mycompany.net.crt
TLSCertificateKeyFile /etc/openldap/ssl/ldap.mycompany.net.key

#######################################################################
# BDB database definitions
#######################################################################
database        hdb
suffix          "dc=mycompany,dc=net"
rootdn          "cn=root,dc=mycompany,dc=net"
checkpoint      32      30 # <kbyte> <min>
ldap_version    3

# Cleartext passwords, especially for the rootdn, should
# be avoid.  See slappasswd(8) and slapd.conf(5) for details.
# Use of strong authentication encouraged.
rootpw          {run slappasswd -s <password> to get this value}

# The database directory MUST exist prior to running slapd AND 
# should only be accessible by the slapd and slap tools.
# Mode 700 recommended, may be different for your Linux distribution.
directory       /var/lib/openldap-data

# ACLs
defaultaccess none

# ACL For password changing on command-line via smbldap-passwd for non-root users
access to attrs=userPassword,sambaLMPassword,sambaNTPassword,sambaPwdLastSet,sambaPwdMustChange
   by self write
   by anonymous auth
   by * none

# ACL for LDAP Manager Access
access to *
   by self write
   by users read
   by anonymous auth
   by * none

# Indices to maintain
index    sambaSID    eq
index    sambaPrimaryGroupSID    eq
index    sambaDomainName    eq
index objectClass,uid,uidNumber,gidNumber,memberUid eq
index cn,mail,surname,givenname   eq,subinitial

ldap.conf

This is in reference to /etc/openldap/ldap.conf, the client-side LDAP library configuration. This file sets options for any client software that uses the OpenLDAP library to connect from this machine. The key settings are URI, BASE, and TLS_{CACERTDIR,CACERT,CACERTFILE,REQCERT}.

#
# LDAP Defaults
#
#
# See ldap.conf(5) for details
# This file should be world readable but not world writable.
#
#BASE	dc=example, dc=com
#URI	ldap://ldap.example.com ldap://ldap-master.example.com:666

#SIZELIMIT	12
#TIMELIMIT	15
#DEREF		never
URI ldaps://ldap.mycompany.net:636
BASE dc=mycompany,dc=net

TLS_CACERTDIR /etc/openldap/ssl
TLS_CACERT /etc/openldap/ssl/ca.crt
TLS_CACERTFILE /etc/openldap/ssl/ca.crt
TLS_REQCERT  never

slapd Startup

In Gentoo, you have to tell slapd to use SSL when starting up. Modify the file /etc/conf.d/slapd, and add the following entries:

OPTS="-h 'ldap://ldap.mycompany.net ldaps://ldap.mycompany.net'"

System Authentication

ldap.conf

We need to modify /etc/ldap.conf. There are many options in ldap.conf, yours may vary. I have only included the ones I modified below.

# Your LDAP server. Must be resolvable without using LDAP.
# Multiple hosts may be specified, each separated by a 
# space. How long nss_ldap takes to failover depends on
# whether your LDAP client library supports configurable
# network or connect timeouts (see bind_timelimit).
host ldap.mycompany.net

# The distinguished name of the search base.
base dc=mycompany,dc=net

# The distinguished name to bind to the server with.
# Optional: default is to bind anonymously.
binddn cn=root,dc=mycompany,dc=net

# The credentials to bind with. 
# Optional: default is no credential.
bindpw s3cr3t

# The port.
# Optional: default is 389, 636 for SSL
port 636

# NOTE: Putting a short search/bind timelimit helps when OpenLDAP is restarted (or the system is rebooted).
#       I've put mine as low as 1, with no ill affects.
# Search timelimit
timelimit 3

# Bind/connect timelimit
bind_timelimit 3

# Reconnect policy: hard (default) will retry connecting to
# the software with exponential backoff, soft will fail
# immediately.
bind_policy soft

# Check the 'host' attribute for access control
# Default is no; if set to yes, and user has no
# value for the host attribute, and pam_ldap is
# configured for account management (authorization)
# then the user will not be allowed to login.
# WARNING: IF YOU ENABLE THIS OPTION, NOBODY WILL BE ABLE
# TO LOG ON TO THIS SYSTEM UNTIL YOU ADD A NEW 'host'
# ENTRY (AND ASSOCIATED OBJECTCLASS) TO THEIR USER
# ACCOUNT. BE CAREFUL!
pam_check_host_attr yes

# Use paged rseults
nss_paged_results yes

# Pagesize: when paged results enable, used to set the
# pagesize to a custom value
pagesize 1000

# RFC2307bis naming contexts
# Syntax:
# nss_base_XXX          base?scope?filter
# where scope is {base,one,sub}
# and filter is a filter to be &'d with the
# default filter.
# You can omit the suffix eg:
# nss_base_passwd       ou=People,
# to append the default base DN but this
# may incur a small performance impact.
nss_base_passwd         ou=Computers,dc=mycompany,dc=net?sub
nss_base_passwd         ou=Users,dc=mycompany,dc=net?sub
nss_base_shadow         ou=Users,dc=mycompany,dc=net?sub
nss_base_group          ou=Groups,dc=mycompany,dc=net?one

# How passwords are stored in OpenLDAP
pam_password ssha

# Logging config. Note that debug 255 is commented out initially, this will create *A LOT* of log messages when enabled!!
logdir /var/log/nss_ldap
#debug 255

# Enable SSL communications.
ssl on

# OpenLDAP SSL options
# Require and verify server certificate (yes/no)
# Default is to use libldap's default behavior, which can be configured in
# /etc/openldap/ldap.conf using the TLS_REQCERT setting.  The default for
# OpenLDAP 2.0 and earlier is "no", for 2.1 and later is "yes".
tls_checkpeer no

# For Gentoo's distribution of nss_ldap, as of 250-r1, we use these values
# (The hardwired constants in the code are changed to them as well):
nss_reconnect_tries 4                   # number of times to double the sleep time
nss_reconnect_sleeptime 1               # initial sleep value
nss_reconnect_maxsleeptime 16   # max sleep value to cap at
nss_reconnect_maxconntries 2    # how many tries before sleeping

ldap.conf.sudo

On Gentoo, the sudo ldap.conf is located in a separate file, /etc/ldap.conf.sudo. Here's what it needs to contain:

# supported directives: host, port, ssl, ldap_version
# uri, binddn, bindpw, sudoers_base, sudoers_debug
# tls_{checkpeer,cacertfile,cacertdir,randfile,ciphers,cert,key}
host ldap.mycompany.net
port 636
ssl yes
base dc=lifepointfamily,dc=org
binddn cn=root,dc=mycompany,dc=net
bindpw s3cr3t
sudoers_base ou=Sudoers,dc=mycompany,dc=net
#sudoers_debug 2

pam_ldap

First things first, setup System and SSH authentication to use LDAP. Go in to the directory /etc/pam.d, and edit the file system-auth. Add in each line as it is below that has pam_ldap.so as an entry:

auth            required        pam_env.so
auth            sufficient      pam_unix.so try_first_pass likeauth nullok
auth            required        pam_ldap.so use_first_pass

account         required        pam_ldap.so
account         required        pam_unix.so

password        required        pam_cracklib.so difok=2 minlen=8 dcredit=2 ocredit=2 try_first_pass retry=3
password        sufficient      pam_unix.so try_first_pass use_authtok nullok md5 shadow
password        sufficient      pam_ldap.so use_authtok use_first_pass

session         required        pam_limits.so
session         required        pam_env.so
session         required        pam_unix.so
session         optional        pam_ldap.so

Save the file and exit.

nsswitch.conf

Modify the file /etc/nsswitch.conf. This contains the settings for obtaining user and group information, and where it should be looked up. Mine looks something like this (all I do is modify the base nsswitch.conf to point to LDAP). Note the 'sudoers' entry, which is required:

passwd:      files ldap
shadow:      files ldap
group:       files ldap
sudoers:     files ldap
#passwd:      files
#shadow:      files
#group:       files

# passwd:    db files nis
# shadow:    db files nis
# group:     db files nis

hosts:       files dns
networks:    files dns

services:    db files
protocols:   db files
rpc:         db files
ethers:      db files
netmasks:    files
netgroup:    files
bootparams:  files

automount:   files
aliases:     files

Test

Using one of your new LDAP user accounts, SSH to your system in a new session, and see if you can login. If you cannot, turn up logging and start debugging. Remember, do not log out of your current SSH session, especially if things are not working yet! You may lock yourself out!

You can also run 'getent passwd' which will show you a list of all users/computers in the LDAP directory, if everything is configured correctly.

Samba

On to Samba. Ensure Samba is compiled with LDAP support. Edit /etc/samba/smb.conf, and add settings for LDAP auth that look something like the following. Note that these are only LDAP-specific settings. There are many other options that go in to smb.conf, yours will vary. Note that these settings are for a Samba server that IS NOT a domain controller.

If you would like to use VASC, see the main VASC page for instructions. VASC is already SSL-ready.

passdb backend = ldapsam:ldaps://ldap.mycompany.net/
ldap delete dn = Yes
ldap ssl = yes
ldap suffix = dc=mycompany,dc=net
ldap admin dn = uid=root,dc=mycompany,dc=net
ldap group suffix = ou=Groups
ldap user suffix = ou=Users
ldap machine suffix = ou=Computers
ldap idmap suffix = ou=Idmap

To set the password for the Admin DN in Samba, run 'smbpasswd -w mysecret'. It will save the encrypted password to secrets.tdb.

root@localhost:/etc/samba# smbpasswd -w mysecret

Restart Samba, you should be able to connect to the system using a user from LDAP.

Apache

httpd.conf

In Gentoo, the mod_ldap configuration is stored in /etc/apache2/modules.d/46_mod_ldap.conf. By default, you shouldn't need to modify anything, other than enabling the LDAP startup option in /etc/conf.d/apache2.

.htaccess

As long as your Apache is configured with LDAP support, enabling .htaccess files to auth against LDAP is easy. I have included the text below from one of mine that I use as a template (from Apache 2.2.11). This should be all the config you need to do.

AuthLDAPEnabled On
AuthLDAPAuthoritative On
AuthLDAPDereferenceAliases never
AuthLDAPGroupAttributeIsDN On
AuthLDAPGroupAttribute memberUid
AuthLDAPBindDN uid=manager,ou=users,dc=mycompany,dc=net
AuthLDAPBindPassword s3cr3t
AuthName "Restricted Files"
AuthType Basic
AuthLDAPURL ldaps://ldap.mycompany.net/dc=mycompany,dc=net?uid?sub?(objectClass=posixAccount)

# Let any valid user in
require valid-user

# Let only joe in
#require user joe

# Let anyone from group Administrators in
#require group cn=Administrators,ou=groups,dc=mycompany,dc=net

PHPLDAPAdmin

PHPLDAPAdmin needs TLS in order to operate correctly with our LDAP server. Your config should have an entry like this:

$servers = new Datastore();
$servers->newServer('ldap_pla');
$servers->setValue('server','name','MyCompany LDAP');
$servers->setValue('server','host','ldap.mycompany.net');
$servers->setValue('server','port',389);
$servers->setValue('server','base',array('dc=mycompany,dc=net'));
$servers->setValue('login','auth_type','session');
$servers->setValue('login','bind_id','cn=root,dc=mycompany,dc=net');
$servers->setValue('login','bind_pass','');
$servers->setValue('server','tls',true);

Samba LDAP Tools

smbldap-tools is a set of utilities that's meant to help administer Samba and Unix accounts. After you have setup Samba, you can configure this tool to help you populate your users (and manage other things, passwords, group membership, etc.). Read the file closely for setting it up. There is one peculiar thing I wanted to mention, when setting up encrypted communication, you have to use TLS on port 389. I also simplified it by not requiring certificate verification, YMMV.

# Put your own SID. To obtain this number do: "net getlocalsid".
# If not defined, parameter is taking from "net getlocalsid" return
SID="{SID_VALUE}"

# Domain name the Samba server is in charged.
# If not defined, parameter is taking from smb.conf configuration file
# Ex: sambaDomain="IDEALX-NT"
sambaDomain="MYCOMPANY"

# Slave LDAP server
# Ex: slaveLDAP=127.0.0.1
# If not defined, parameter is set to "127.0.0.1"
slaveLDAP="ldap.mycompany.net"

# Slave LDAP port
# If not defined, parameter is set to "389"
slavePort="389"

# Master LDAP server: needed for write operations
# Ex: masterLDAP=127.0.0.1
# If not defined, parameter is set to "127.0.0.1"
masterLDAP="ldap.mycompany.net"

# Master LDAP port
# If not defined, parameter is set to "389"
masterPort="389"

# Use TLS for LDAP
# If set to 1, this option will use start_tls for connection
# (you should also used the port 389)
# If not defined, parameter is set to "1"
ldapTLS="1"

# How to verify the server's certificate (none, optional or require)
# see "man Net::LDAP" in start_tls section for more details
verify="none"

The rest of the settings should be pretty self explanatory.

Password Management

I found it very difficult at first to get password changes and expiration working with Samba and Windows clients, using OpenLDAP. Here's what I found:

  • The "passwd chat" dialogue setting in smb.conf must be exact! This is easily achieved by running 'smbldap-passwd' for a random user, and then converting each line into something that looks like this (note how the text is wrapped in double-quotes):
    • "*Changing UNIX and samba passwords for %u*""*New password*" %n"*Retype new password*" %n
  • Remove all 'sambaPwd*' attributes on the individual accounts except for sambaPwdLastSet.
  • On the main domain policy, set sambaMinPwdAge to 1 week (604800).
  • On the main domain policy, set sambaMaxPwdAge to 1 year (31556926).
  • In smbldap.conf, change defaultMaxPasswordAge to 365 (this is for Shadow Password expiration).
  • If you have accounts that must have Shadow Passwords that do not expire, remove the attribute shadowMax from their LDAP entry.
  • If you have accounts that must have Samba Passwords that do not expire, modify the attribute sambaAcctFlags to be [UX]. [1]

References

Personal tools
Sponsored Links