Does anyone use nscd?
Lawrence Stewart
lstewart at freebsd.org
Thu Oct 6 13:11:39 UTC 2011
On 10/05/11 19:43, Dag-Erling Smørgrav wrote:
[snip]
>
> While we're at it, I'd be very grateful if someone could email me a
> quick and dirty guide to setting up an LDAP server for testing. I have
> too much on my plate right now to start reading documentation...
A bit dated, but this build guide is reasonably complete and should
pretty much all still be relevant. It has some bits you won't need if
you're just setting something up for quick and dirty testing - I think
they'll be obvious as you're working through it.
Cheers,
Lawrence
-------------- next part --------------
- Based mostly on information from these places (among many others!):
- http://www.freebsd.org/doc/en/articles/ldap-auth/index.html
- http://www.openldap.org/doc/admin24/
## USEFUL RANDOM TIDBITS ##
- These pearls of wisdom are useful during set up and debugging
- Use the "slapcat" tool on the server command line to show you the contents
- of the ldap database in ldif format. This is useful for rolling backups.
- Have a cron job call slapcat every 30 mins and write the output over the top
- of a file which is incrementally backed up
- Example of updating the "test" user's password as the DB admin
ldappasswd -x -S -H ldap://127.0.0.1 -D 'cn=root,dc=example,dc=com' -W 'uid=test,ou=people,dc=example,dc=com'
- LDAP data is often stored base64 encoded (e.g. userPassword field). Use this to decode:
echo "e0NSWVBUfSQxJEt5T3FxYmdlJDQec3VTLnZUY21rTzRGWENBVVBTMjE=" | perl -MMIME::Base64 -ne 'print decode_base64($_) . "\n";'
-To manually update an existing entry's attribute
ldapmodify -x -H ldap://127.0.0.1 -D 'cn=root,dc=example,dc=com' -W -f testuser.ldif
- With testuser.ldif contents:
dn: uid=test,ou=people,dc=example,dc=com
changetype: modify
replace: userPassword
userPassword: {crypt}$1$pUXysTUZ$97r27L6FE21NDtZdNUYRc1
-To delete an existing entry
ldapmodify -x -H ldap://127.0.0.1 -D 'cn=root,dc=example,dc=com' -W -f testuser.ldif
- With testuser.ldif contents:
dn: uid=test,ou=people,dc=example,dc=com
changetype: delete
- Enable the monitor backend in slapd.conf and run the following query to get operational info about slapd
ldapsearch -x -H ldap://127.0.0.1 -b 'cn=Monitor' +
- Change the "loglevel" directive in slapd.conf to "conns filter stats" to get useful debugging info in /var/log/debug.log
- Setting "debug 1" in pam_ldap.conf and/or nss_ldap.conf will give you some useful debugging info on the client side in /var/log/debug.log
-
## END USEFUL RANDOM TIDBITS ##
## SERVER CONFIG ##
- Add the following lines to /etc/make.conf to make the FreeBSD ports system
- use LDAP 2.4.x for ports that require LDAP (default uses 2.3.x)
# Use OpenLDAP 2.4.x
WANT_OPENLDAP_VER=24
- Install openldap server
cd /usr/ports/net/openldap24-server
make install clean
- Select options: SASL, PASSWD, PERL, ODBC, TCP_WRAPPERS, BDB, SEQMOD, SYNCPROV, DYNAMIC_BACKENDS
- Create a certificate/key for encrypted comms with the LDAP server
mkdir /usr/local/certs
openssl req -new -x509 -days 1825 -nodes -out /usr/local/certs/ldapserver.pem -keyout /usr/local/certs/ldapserver.pem
- The dialog with openssl should go something like this:
Country Name (2 letter code) [AU]:AU
State or Province Name (full name) [Some-State]:Victoria
Locality Name (eg, city) []:Melbourne
Organization Name (eg, company) [Internet Widgits Pty Ltd]: Org
Organizational Unit Name (eg, section) []: Org Unit
Common Name (eg, YOUR name) []:ldapserver.blah.com.au
Email Address []:youruser at blah.com.au
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
#- Check that the basic details are all good
openssl x509 -subject -dates -fingerprint -noout -in /usr/local/certs/ldapserver.pem
#- Set perms on sensitive files
#create 'certs' group and add ldap and www users:
pw groupadd certs
pw groupmod certs -M www ldap
chmod 0440 /usr/local/certs/ldapserver.pem
chgrp certs /usr/local/certs/ldapserver.pem
#- Configure slapd, the ldap server
mkdir /var/db/slapd
chown ldap:ldap /var/db/slapd
cp /usr/local/etc/openldap/DB_CONFIG.example /var/db/slapd/DB_CONFIG
cd /usr/local/etc/openldap
edit slapd.conf
- Make the file look like this
#######################################################
include /usr/local/etc/openldap/schema/core.schema
include /usr/local/etc/openldap/schema/cosine.schema
include /usr/local/etc/openldap/schema/inetorgperson.schema
include /usr/local/etc/openldap/schema/nis.schema
include /usr/local/share/examples/samba/LDAP/samba.schema
loglevel conns filter stats
#loglevel none
pidfile /var/run/openldap/slapd.pid
argsfile /var/run/openldap/slapd.args
modulepath /usr/local/libexec/openldap
moduleload back_bdb
defaultsearchbase "dc=blah,dc=com,dc=au"
password-hash {CRYPT}
password-crypt-salt-format "$1$%.8s"
security ssf=128
TLSCertificateFile /usr/local/certs/ldapserver.pem
TLSCertificateKeyFile /usr/local/certs/ldapserver.pem
TLSCACertificateFile /usr/local/certs/ldapserver.pem
database bdb
directory /var/db/slapd
suffix "dc=blah,dc=com,dc=au"
rootdn "cn=root,dc=blah,dc=com,dc=au"
rootpw <password from next step>
checkpoint 0 5
index objectClass eq
index uid eq
index uidNumber eq
index gidNumber eq
access to dn.base="sambaDomainName=LDAPSERVER,ou=samba,dc=blah,dc=com,dc=au"
by dn.base="uid=samba,ou=admins,dc=blah,dc=com,dc=au" write
access to attrs=userPassword,sambaNTPassword,sambaLMPassword,sambaPasswordHistory,sambaPwdLastSet,sambaAcctFlags
by self =xw
by dn.base="uid=samba,ou=admins,dc=blah,dc=com,dc=au" write
by * auth
access to *
by self write
by * read
#######################################################
#- Create a slapd root password, replacing "test" with real password
slappasswd -s "test"
- This will spit a string out to the console that looks like "{SSHA}L4kq3C1TWCpVnWKq8oeHtZV883ljiViM"
- Copy the entire string and paste it into the slapd config file at the "rootpw" line
# - edit /usr/local/etc/openldap/ldap.conf - add folowing line:
echo "TLS_REQCERT allow" >> /usr/local/etc/openldap/ldap.conf
#- Make ldap server start on boot
#edit /etc/rc.conf
#- Add the following line
echo 'slapd_enable=\"YES\"' >> /etc/rc.conf
- Start the server now
/usr/local/etc/rc.d/slapd start
## BEGIN OPTIONAL SERVER CONFIG ##
- Install PHP LDAP admin (phpldapadmin-1.1.0.5_2,1)
cd /usr/ports/www/apache22
make install clean
- select default options
cd /usr/ports/net/phpldapadmin
make install clean
- select options: CLI, CGI, APACHE, SUHOSIN, MULTIBYTE, IPV6, FASTCGI, PATHINFO for php5-5.2.6
- Make apache handle .php files via the php interpreter
edit /usr/local/etc/apache22/httpd.conf
- Add the following lines under the existing line "AddType application/x-gzip .gz .tgz"
#######################################################
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps
#######################################################
- Uncomment the following line
#Include etc/apache22/extra/httpd-ssl.conf
- Configure SSL/TLS
edit /usr/local/etc/apache22/extra/httpd-ssl.conf
- Comment out the following lines
#ServerName www.example.com:443
#ServerAdmin you at example.com
- Change the following lines appropriately
SSLCertificateFile "/usr/local/certs/ldapserver.pem"
SSLCertificateKeyFile "/usr/local/certs/ldapserver.pem"
- Make apache serve phpldapadmin via HTTPS
edit /usr/local/etc/apache22/Includes/phpldapadmin.conf
- Add the following lines:
#######################################################
RewriteEngine on
RewriteCond %{SERVER_PORT} !443$
RewriteRule ^/?(phpldapadmin/.*) https://%{SERVER_NAME}/$1 [R=301,L]
Alias /phpldapadmin /usr/local/www/phpldapadmin/htdocs
<Directory /usr/local/www/phpldapadmin>
Order allow,deny
Allow from all
DirectoryIndex index.php
</Directory>
#######################################################
- Configure phpldapadmin
edit /usr/local/www/phpldapadmin/config/config.php
- Make the file look like this:
#######################################################
<?php
$i=0;
$ldapservers = new LDAPServers;
$ldapservers->SetValue($i,'server','name','LDAP Server');
$ldapservers->SetValue($i,'server','host','127.0.0.1');
$ldapservers->SetValue($i,'server','auth_type','session');
$ldapservers->SetValue($i,'server','tls',true);
$ldapservers->SetValue($i,'server','sasl_auth',false);
$friendly_attrs = array();
$friendly_attrs['facsimileTelephoneNumber'] = 'Fax';
$friendly_attrs['telephoneNumber'] = 'Phone';
$friendly_attrs['uid'] = 'User Name';
$q=0;
$queries = array();
$queries[$q]['name'] = 'User List';
$queries[$q]['base'] = 'dc=blah,dc=com,dc=au';
$queries[$q]['scope'] = 'sub';
$queries[$q]['filter'] = '(&(objectClass=posixAccount)(uid=*))';
$queries[$q]['attributes'] = 'cn, uid, homeDirectory, telephonenumber, jpegphoto';
?>
#######################################################
- Make apache start on boot
edit /etc/rc.conf
- Add the following line
apache22_enable="YES"
- Start apache
apachectl start
- You should now be able to access http://<hostname>/phpldapadmin and login with your
- LDAP server's rootdn credentials
- e.g. username "cn=root,dc=blah,dc=com,dc=au" and password is the clear text version
- you typed into the slappasswd command previously to generate the rootpw option
- "Import" action in phpldapadmin can be used to run an ldif file against the server
## END OPTIONAL SERVER CONFIG ##
- Create an ldif file to seed the LDAP db with our required structure
- We'll use "people" as the OU for user accounts and "groups" as the OU for groups
edit /usr/local/etc/openldap/initldap.ldif
- seed ldif file contents:
#######################################################
#org
dn: dc=blah,dc=com,dc=au
objectClass: dcObject
objectClass: organization
dc: org
o: ORG NAME
description: Blah
# Create an OU for people
dn: ou=people,dc=blah,dc=com,dc=au
ou: people
objectClass: top
objectClass: organizationalUnit
# Create an OU for groups
dn: ou=groups,dc=blah,dc=com,dc=au
objectClass: top
objectClass: organizationalUnit
ou: groups
#######################################################
- Apply the contents of the ldif file against the DB (or use web interface)
ldapadd -c -x -f /usr/local/etc/openldap/initldap.ldif -H ldap://127.0.0.1 -D 'cn=root,dc=blah,dc=com,dc=au' -W -ZZ
## END SERVER CONFIG ##
## CLIENT CONFIG ##
- Add the following lines to /etc/make.conf to make the FreeBSD ports system
- use LDAP 2.4.x for ports that require LDAP (default uses 2.3.x)
# Use OpenLDAP 2.4.x
WANT_OPENLDAP_VER=24
- Install required ports
Paste the following patch into the file shown below:
/usr/ports/security/pam_ldap/files/patch-groupdnfix
################################################################
--- pam_ldap.c.orig 2008-06-27 17:51:37.000000000 +1000
+++ pam_ldap.c 2008-06-27 17:45:11.000000000 +1000
@@ -4020,7 +4020,7 @@
{
rc = ldap_compare_s (session->ld,
session->conf->groupdn,
- session->conf->groupattr, session->info->userdn);
+ session->conf->groupattr, session->info->username);
if (rc != LDAP_COMPARE_TRUE)
{
snprintf (buf, sizeof buf, "You must be a %s of %s to login.",
################################################################
cd /usr/ports/security/pam_ldap
make install clean
cd /usr/ports/net/nss_ldap
make install clean
cd /usr/ports/security/pam_mkhomedir
make WITH_PROFILE=yes install clean
- Configure pam to attempt ldap auth before falling back on local file auth
edit /etc/pam.d/sshd
- Add the following line before "auth required pam_unix.so no_warn try_first_pass"
auth sufficient /usr/local/lib/pam_ldap.so no_warn config=/usr/local/etc/pam_ldap.conf try_first_pass
- Add the following line before "account required pam_unix.so"
account sufficient /usr/local/lib/pam_ldap.so no_warn ignore_authinfo_unavail ignore_unknown_user
- Add the following line before "session required pam_permit.so"
session required /usr/local/lib/pam_mkhomedir.so
- Make sure /home exists either as a symlink to a directory or an actual directory
edit /usr/local/etc/pam_ldap.conf
- Make the file contents this:
#######################################################
uri ldap://ldapserver.blah.com.au
base dc=blah,dc=com,dc=au
ssl start_tls
tls_checkpeer no
#debug 1
#######################################################
- Configure nss to use ldap to resolve uid/gid info
edit /etc/nsswitch.conf
- Change the following lines accordingly
group: files ldap
passwd: files ldap
- nss_ldap is written by the authors of pam_ldap and they can share config files
ln -s /usr/local/etc/pam_ldap.conf /usr/local/etc/nss_ldap.conf
- If nss is working, "touch test.file ; chown ldapuid:ldapgid test.file" where "ldapuid" is a uid of a user in ldap that isn't
- in the local system's /etc/passwd file and "ldapgid" is a gid of a group in ldap that isn't
- in the local system's /etc/group file
- Then run "ls -l test.file" and you should see the user name and group name details from ldap next to the file
### Local logins
The original config only sets up ldap auth for SSH logins
Add support for local LDAP logins if required:
edit /etc/pam.d/login with the same options as you did for /etc/pam.d/sshd to allow local ldap logins
### Adding nsswitch caching with nscd
Without caching, an offline LDAP server renders the workstation almost useless, as each time a username is required, eg "ls -al" the system will try and connect o the LDAP server to resolve the name.
The solution is the Name Service Caching Daemon. This basic configuration will mean that once logged into a machine (auth is done) uid/username pairs will be cached locally.
confirm /etc/nscd.conf contains the following
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
enable-cache passwd yes
enable-cache group yes
enable-cache hosts yes
enable-cache services yes
enable-cache protocols yes
enable-cache rpc yes
enable-cache networks yes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This will configure nscd to cache everything it can.
By default, caches are kept for 1 hour.
This can be changed by adding an entry as below.
A line is needed for each chache type you would like to alter.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
positive-time-to-live passwd 7200
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
edit /etc/rc.conf
add:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
nscd_enable="YES"
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
edit /etc/nssswitch.conf
add 'cache' as the first source for group, hosts, passwd, services, protocaols, rpc and networks.
This will enable caching of users and passwords from ldap as well as DNS host lookups
### LDAP Password changes with 'passwd'
edit /usr/local/etc/pam_ldap.conf
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
add "pam_passwd exop"
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: With the 'exop' option, the password is sent in clear text (BUT it is over TLS so will still be secure) and upon receiving the password, the server encrypts it into the proper format. 'crypt' also works, and sends an encrypted password to ldap, but it is ideal to keep passwords in exactly the same format in ldap as is kept in a locat master.passwd file.
The system password command is very old and isn't aware that passwords can be changed for LDAP users.
We therefore have to add a hack to bypass this limitation. (There is no feasable alternate solution at this stage).
edit /usr/src/usr.bin/passwd/passwd.c
Replace:
errx(1, "Sorry, `passwd' can only change passwords for local or NIS users.");
With:
fprintf(stderr, "Now you can change LDAP password via PAM\n");
make install in that directory.
edit /etc/pam.d/passwd
add the following line before the pam_unix.so entry
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
password sufficient /usr/local/lib/pam_ldap.so no_warn try_first_pass config=/usr/local/etc/pam_ldap.conf
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
### Restricting Logins to a particular group
http://lists.freebsd.org/pipermail/freebsd-questions/2005-October/100816.html
edit /usr/local/etc/pam_ldap.conf
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pam_groupdn cn=login_group,ou=groups,dc=blah,dc=com,dc=au
pam_member_attribute memberUid
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
WARNING: For this to work the FULL DN of the user must be listed in the memberUid attribute of the posix group specified in pam_groupdn config.
Suggestion, use a separate OU for hosts, which contain groups with machine names -> full dn of allowed users on those machines should be stored in memberUid
OR
add a separate attribute 'loginDN' to relavant groups that will be used for login restrictions. change pam_member_atrribute from memberUid to loginDN
### Preventing long delays during Auth when LDAP server isn't available
By default, when the LDAP server isn't available, the client will not give up trying to connect to the LDAP server.
Changing the bind policy to 'soft' will cause the client to give up immediately if the server is not available.
# Reconnect policy:
# hard_open: reconnect to DSA with exponential backoff if
# opening connection failed
# hard_init: reconnect to DSA with exponential backoff if
# initializing connection failed
# hard: alias for hard_open
# soft: return immediately on server failure
edit /usr/local/etc/pam_ldap.conf
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
bind_policy soft
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
### Allowing machine logins to be restricted by groups
Paste the following patch into the file shown below:
/usr/ports/security/pam_ldap/files/patch-groupdnfix
--- pam_ldap.c.orig 2008-06-27 17:51:37.000000000 +1000
+++ pam_ldap.c 2008-06-27 17:45:11.000000000 +1000
@@ -4020,7 +4020,7 @@
{
rc = ldap_compare_s (session->ld,
session->conf->groupdn,
- session->conf->groupattr, session->info->userdn);
+ session->conf->groupattr, session->info->username);
if (rc != LDAP_COMPARE_TRUE)
{
snprintf (buf, sizeof buf, "You must be a %s of %s to login.",
cd /usr/ports/
make clean
## END CLIENT CONFIG ##
## BEGIN SAMBA SERVER CONFIG ##
passdb backend = ldapsam:ldap://ldapserver.blah.com.au
ldap admin dn = uid=samba,ou=admins,dc=blah,dc=com,dc=au
ldap ssl = no
ldap delete dn = no
ldap user suffix = ou=people
ldap group suffix = ou=groups
ldap machine suffix = ou=computers
ldap suffix = dc=blah,dc=com,dc=au
## END SAMBA SERVER CONFIG ##
More information about the freebsd-hackers
mailing list