如何在RHEL6上配置PAM LDAP认证(How to setup LDAP Authentication for PAM on RHEL6 x86_64)

来源:互联网 发布:网络舆情监测员职责 编辑:程序博客网 时间:2024/03/29 02:13

PAM-LDAP 身份验证的原理

身份验证本身是由 需要身份验证服务的服务(例如:ssh,su,ftp等等)根据/etc/pam.d/目录下对应的配置信息选择相应的PAM模块逐一进行的。指定的认证模块从身份验证候选机制中获取用户名和用户的credential进行认证(用户的从credential可以是提示用户输入,也可以是上一个认证模块传过来)。pam-ldap.so就是使用LDAP进行认证的PAM模块。它先(从上一个认证模块)获取用户名(uid),使用/etc/pam_ldap.conf (对于非RHEL6 x84_64版本的Linux,对应的文件是/etc/ldap.conf或者/etc/pam.conf)文件中binddn字段指定DN及bindpw字段配置的密码(即利用binddn/bindpw指定的用户名和密码) 到  LDAP 服务器上去查询检索pam-ldap.so模块传入待验证的用户 uid 条目(注意不是binddn字段指定的用户名)相关的 DN。注意,因为我们是用binddn指定的DN作为查询身份标示来进行LDAP查询,所以在LDAP服务器一端的访问控制设置(Access Control)中要保证binddn指定的DN必须拥有对用户的条目(entry)进行读取的权限。当然,如果LDAP服务本身允许做匿名查询的话,就没必要在pam_ldap.conf文件中配置binddn/bindpw字段。在获取待验证用户在LDAP中的条目后,pam-ldap.so从身份验证候选机制中获取密码(一般说来是从上一个模块,通常都是pam_unix.so),然后使用这个用户(uid)查询到的对应DN和用户输入的密码做配对再次到LDAP服务器上尝试绑定(binding)操作特别要注意的是在/etc/pam_ldap.conf中不能配置rootbinddn字段的值。如果配置了,最后到LDAP服务器尝试绑定操作的DN就不是待认证用户查询到的DN,而是rootbinddn指定的DN,那肯定会导致失败。如果LDAP服务器返回绑定成功,PAM 会报告说这个用户已经成功通过了 pam_ldap.so 提供的身份验证测试根据 PAM 的配置不同(/etc/pam.d目录下配置文件,或者/etc/pam.conf),在用户看到命令行提示符之前可能会执行其它身份验证/测试。

Setup Procedure (within RHEL6)

0. Precondition

To use LDAP for authentication through PAM, it is required that an LDAP service has been properly provisioned with necessary user/group data.

It's better to provide two sub-trees in your LDAP database:

  • a user sub-tree to hold all users' information (eg, ou=people,dc=example,dc=com);
  • a group sub-tree to hold group information of all users (eg, ou=groups,dc=example,dc=com);

For each user entry, it must include a posixAccount and a shadowAccount objectClass(es). Since we usually use LDAP as a unique point for generic authentication and directory service, it's wise to define user's entry as inetOrgperson as well.

For each user's group entry, it must include a posixGroup objectClass.

dn: cn=lukeyang,ou=groups,dc=example,dc=comobjectClass: posixGroupcn: lukeyanggidNumber: 505memberUid: 505

You can manually create LDIF file for each user and then add the entry to LDAP database through ldapadd command. Or you can use PADL.com's migration tool (included in RHEL 6 already as part of openLDAP - actually it's part of  the University of Michigan LDAP distribution - the predecessor of openLDAP) to migrate the existing user/group's information (or the other information) from /etc/passwd, /etc/group to LDIF format. The detailed manual is available fromhttp://www.padl.com/OSS/MigrationTools.html.

Note before using MigrationTools
Modify the migrate_common.ph file per your LDAP model before you run any MigrationTools script.

An example to use MigrationTools to migrate one account "ldapuser" from /etc/passwd to LDAP database (by using ldapadd) :

# grep ldapuser /etc/passwd > passwd.in# ./migrate_passwd.pl passwd.in > passwd.ldif# cat passwd.ldifdn: uid=ldapuser,ou=People,dc=example,dc=comuid: ldapusercn: ldapuserobjectClass: accountobjectClass: posixAccountobjectClass: topobjectClass: shadowAccountuserPassword: {crypt$1$TeOlOcMc$cpQaa0WpLSFRC1HIHW5bt1shadowLastChange: 13048shadowMax: 99999shadowWarning: 7loginShell: /bin/bashuidNumber: 500gidNumber: 500homeDirectory: /home/ldapusergecos: ldapuser# ldapadd -x -D "cn=Manager,dc=example,dc=com" -W -f passwd.ldif

1. /etc/nsswitch.conf - NSS configuration

Modify /etc/nsswitch.conf to include ldap for at least the passwd, group and shadow maps. Whether you should also change the other maps depends on the information in your LDAP directory. You should include ldap after local lookups (files or in some cases compat). Your /etc/nsswitch.conf will contain something like:

passwd:   files ldapgroup:    files ldapshadow:   files ldap

2. /etc/pam.d - PAM configuration

To enable logins using both LDAP and local users (e.g. you want to keep root logins) you should edit files under /etc/pam.d (or /etc/pam.conf if your system uses that. For RHEL6, it use /etc/pam.d format). Everywhere that pam_unix is called you should also call pam_ldap.

Tips for RHEL6: In fact, we could only need to modify /etc/pam.d/system-auth and /etc/pam.d/password-auth since these two files are wildly "included" in each service's configuration file.

Here's an example for system-auth (the same thing to password-auth):

#%PAM-1.0# This file is auto-generated.# User changes will be destroyed the next time authconfig is run.auth        required      pam_env.soauth        sufficient    pam_fprintd.soauth        sufficient    pam_unix.so nullok try_first_passauth        requisite     pam_succeed_if.so uid >= 500 quietauth        sufficient    pam_ldap.so use_first_passauth        required      pam_deny.so account     required      pam_unix.soaccount     sufficient    pam_localuser.soaccount     sufficient    pam_succeed_if.so uid < 500 quietaccount     [default=bad success=ok user_unknown=ignore] pam_ldap.soaccount     required      pam_permit.so password    requisite     pam_cracklib.so try_first_pass retry=3 type=password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtokpassword    sufficient    pam_ldap.so use_authtokpassword    required      pam_deny.so session     optional      pam_keyinit.so revokesession     required      pam_limits.sosession     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uidsession     required      pam_unix.sosession     optional      pam_ldap.so

What's been changed:
For each category (auth, account, password and session), we added one new line with pam_ldap.

3. /etc/sysconfig/authconfig - system authentication resources configruation

Modify the file and change USELDAPAUTH=no to USELDAPAUTH=yesUSELDAP=no to USELDAP=yes and FORCELEGACY=no to FORCELEGACY=yes (this is because RHEL6 forces to use TLS for LDAP - if you don't want this, set FORCELEGACY to yes will disable it).

A full example of modified authconfig file:

USEMKHOMEDIR=yesUSEPAMACCESS=yesCACHECREDENTIALS=yesUSESSSDAUTH=noUSESHADOW=yesUSEWINBIND=noPASSWDALGORITHM=sha512FORCELEGACY=yesUSEFPRINTD=yesUSEHESIOD=noFORCESMARTCARD=noUSEDB=noUSELDAPAUTH=yesUSELDAP=yesUSECRACKLIB=yesUSEWINBINDAUTH=noUSESMARTCARD=noUSELOCAUTHORIZE=yesUSENIS=noUSEKERBEROS=noUSESYSNETAUTH=noUSESSSD=noUSEPASSWDQC=no

Or you can use system-config-authentication GUI application (RHEL Desktop GUI: System->Administration->Authentication or /usr/bin/authconfig-gtk) or the command line options of /usr/sbin/authconfig instead. Note: even you use these tools, you still need to modify the /etc/sysconfig/authconfig manually to enable non-TLS support (RHEL 6 only). Also please be aware that these tools will modify the other configuration files needed for LDAP authentication (eg, the /etc/nslcd.conf in step 4 below).

Here's an example of using /usr/sbin/authconfig command.

authconfig --enableldap --enableldapauth --enablemkhomedir --enableforcelegacy --disablesssd --disablesssdauth --ldapserver=ldap1.example.com,ldap2.example.com --ldapbasedn="dc=example,dc=com" --update

4. /etc/nslcd.conf - local LDAP name service daemon configuration

nslcd is a daemon that will do LDAP queries for local processes that want to do user, group and other naming lookups (NSS) or do user authentication, authorization or password modification through PAM. It's a mandatory component for LDAP authentication on RHEL6. 注:在RHEL6之前,是没有这个模块的。It's installed within nss-pam-ldapd RPM package. 建议将nslcd设置为系统服务。具体方法参见本文最后章节。

ATTENTION!
注意:虽然我们可以将nscld设置成为系统服务,但在某些情况下RHEL系统重启后,nslcd服务有可能不会正常运行,这样就会导致PAM-LDAP验证失败 -- 具体故障显示为ssh, ftp, telnet等登陆失败,而其它的通过LDAP验证的服务没有问题。解决办法就是按正常方式启动nslcd即可(service nslcd start).

nslcd所需的配置信息存放在/etc/nslcd.conf目录中。作为一个LDAP查询代理,它必须需要知道这几点:1. LDAP服务器的地址(包括端口);2. 查询时的指定LDAP base (到LDAP服务器目录里哪个分支去查询);3. 如果LDAP服务器不支持匿名查询的话,用什么身份去查询。 所有这些都是nslcd.conf配置文件需要给明的。

Configuration Format
Configuration file options consist of a keyword followed by a space and any arguments.
另:你会发现nslcd.conf的格式和内容和/etc/pam_ldap.conf非常之像。我认为RH是将原来pam_ldap.so中的LDAP查询模块部分独立出来成为nslcd,所以基本上重用了原来的pam_ldap.conf格式。但大部分的字段我们是没必要配置的。

Key fields to update in nslcd.conf:

  1. uri: well known address for your LDAP service. Multiple entries may be specified. For example, ldap://127.0.0.1/
  2. base: the base (root) of the Directory Information Tree defined in your LDAP database. For example: dc=example,dc=com
  3. binddn and bindpw: the binddn specifies the distinguished name with which to bind to the directory server for lookups. The bindpw specifies the clear text credentials with which to bind - it is only applicable when used with binddn. If you set the bindpw option you should consider changing the permissions of the nslcd.conf file to only grant access to the root user. If your LDAP service support anonymous query, these two fields are not necessary.
  4. rootpwmoddn: the rootpwmoddn specifies the distinguished name to perform password modifications by root by (for example: cn=Manager,dc=example,dc=com).
  5. rootpwmodpw: the rootpwmodpw specifies the clear text credentials with which to bind if the root user tries to change a user's password - it is only applicable when used with rootpwmoddn. If the rootpwmodpw option is not specified, the PAM module prompts the user for this password. If you set the rootpwmodpw option, you should consider changing the permissions of the nslcd.conf file to only grant access to the root user. ATTENTION: this new option was introduced in nss-pam-ldap 0.8.0 (2010/12/30) - so it is not supported in the 0.7.5-7 version used by RHEL 6.
# chown nslcd:ldap /etc/nslcd.conf# chmod 660 /etc/nslcd.conf# ls -l /etc/nslcd.conf-rw-rw----. 1 nslcd ldap 4173 Sep  1 11:51 nslcd.conf#

个人体会:

通过近期的学习和尝试,个人感觉nslcd的作用就像一个LDAP查询的本地代理 - 所有的系统模块(例如前面提到的pam-ldap.so)在进行用户认证、NSS查询等需要LDAP查询的操作时,都是将LDAP请求发送给nslcd daemon,再由nslcd统一向配置(/etc/nslcd.conf中uri字段)好的LDAP服务器发送查询请求。查询结果返回后再分发给最初的请求模块。

5. /etc/pam_ldap.conf

The pam_ldap module is a Pluggable Authentication Module (PAM), which provides for authentication, authorization and password changing against LDAP servers.

When authenticating or authorizing a user, pam_ldap first maps the user’s login name to a distinguished name by searching the directory server.  This must be possible using the local system’s identity, specified in pam_ldap.conf (Note that presently only simple authentication is supported for authenticating in this initial step).

To  authenticate a user, pam_ldap attempts to bind to the directory server using the distinguished name of the user (retrieved previously). Both simple and SASL authentication mechanisms are supported; in the former case, one  should take care to use transport security to prevent the user’s password being transmitted in the clear.

Finally, pam_ldap supports a number of password change protocols used by directory servers from various vendors. (Some directory servers support more than one password change protocol.)

Whilst pam_ldap is generally configured in the system LDAP naming configuration file (pam_ldap.conf), some options can be configured in the PAM configuration file, to allow for per-service granularity. These options include the path to the LDAP naming configuration file to use, so in effect all options can be configured on a per-service basis. Options are listed below under PAM Configuration.

Configuration Format
Configuration file options consist of a keyword followed by a space and any arguments.

Key fields to update in pam_ldap.conf:

  1. uri: well known address for your LDAP service. Multiple entries may be specified. For example, ldap://127.0.0.1/
  2. base: the base (root) of the Directory Information Tree defined in your LDAP database. For example: dc=example,dc=com
  3. binddn and bindpw: the binddn specifies the distinguished name with which to bind to the directory server (for example: cn=Manager,dc=example,dc=com). The bindpw specifies the clear text credentials with which to bind - it is only applicable when used with binddn. If you set the bindpw option you should consider changing the permissions of the nslcd.conf file to only grant access to the root user. If your LDAP service support anonymous query, these two fields are not necessary.
  4. nss_base_passwd, nss_base_shadow and nss_base_group: adjust the value to match your DIT definition in LDAP database.
nss_base_passwd         ou=people,dc=example,dc=com?onenss_base_shadow         ou=people,dc=example,dc=com?onenss_base_group          ou=groups,dc=example,dc=com?one

ATTENTION!
=============== DO NOT provide value to rootbinddn field===============
Since the DN of the user who is being be authenticated s DN will be used to try binding operation with the password provided by the user against the LDAP server. If the binding is sucessuful, it means that the authentication against the user is passed. Provide the rootbinddn will overwrite the user's DN value during the last bind attempt and cause the authentication failure.

If you want to debug problem, you can enable pam-ldap log by adding following lines to pam_ldap.conf:

logdir /tmp/ldap/debug 3

Appendix 1. /etc/pam_ldap.secret - configuration of password for root DN used by PAM

Normally, we should not provide value for rootbinddn (mentioned above) field, thus no need to provide value to rootbinddnpw. If you have to, follow the procedure below.

Firstly, you need to use /usr/sbin/slappasswd to generate the ciphered password for root DN from clear text. Here's an example of using slappasswd: -s will pass the password in clear text (it's "secret" in our example). By default, slappasswd use SSHA as cipher schema. You can specify -h to use different schema per your needs (eg, {MD5}, {CRYPT} or {SHA}).

# slappasswd -s secret{SSHA}PDBi+xt5VwftrbQvVfQUuwhG6kWkBS7L#

Create or modify /etc/pam_ldap.secret file to include the root DN's password value as: rootbinddnpw <the ciphered password value from slappasswd>

# cat /etc/pam_ldap.secretrootbinddnpw {SSHA}PDBi+xt5VwftrbQvVfQUuwhG6kWkBS7L#

Once the file is ready, make sure it's owned by root and read/write only by owner:

# chown root:root /etc/pam_ldap.secret# chmod 600 /etc/pam_ldap.secret# ls -l /etc/pam_ldap.secret-rw-------. 1 root root 53 Aug 29 21:56 /etc/pam_ldap.secret#

Appendix 2. Enable and start nslcd - local LDAP name service daemon

Restart or run the nslcd based on the status of nslcd:

  • service nslcd status will return the status of nslcd
  • service nslcd start will start nslcd
  • service nslcd stop will stop nslcd
  • service nslcd restart will stop and then start nslcd (a combination of stop and start). It's strongly suggested to restart nslcd everytime you modify the /etc/nslcd.conf configuration file.

It's also a good idea to enable the nslcd as a service which starts up automatically through reboot. Three methods to do this:

  1. ntsysv (/usr/sbin/ntsysv - simple interface for configuring runlevels) - a GUI tool to configure runlevel services;
  2. An replacement: chkconfig
    1. check status of an service: chkconfig --list nslcd
    2. update status of an service: chkconfig --level 235 nslcd on
  3. Use GUI: System -> Administration -> Services

Reference

  • 使用 OpenLDAP 集中管理用户帐号 - 非常棒!
  • Tony's LDAP page
  • http://www.saas.nsw.edu.au/solutions/ldap.html
  • SSL Certificates HOWTO
  • http://www.kernel.org/pub/linux/libs/pam/index.html
  • Gentoo LDAP authentication howto
  • http://www.linuxdoc.org/HOWTO/LDAP-Implementation-HOWTO/ uses Netscape LDAP libs
  • http://www.padl.com/OSS/pam_ldap.html
  • http://www.redhat.com/docs/manuals/linux/RHL-6.2-Manual/ref-guide/s1-ldap-redhattips.html\
  • http://www.kernel.org/pub/linux/libs/pam/
  • http://www.rudedog.org/auth_ldap/1.4/auth_ldap.html (apache)
  • http://www.raphinou.com/ldaps/LDAP-SSL.HOWTO
  • http://www.openldap.org/faq/data/cache/185.html http://asg.web.cmu.edu/sasl/
  • http://hints.linuxfromscratch.org/hints/ldap_auth.txt http://www.spack.org/index.cgi/UnixAndActiveDirectory/
  • http://staff.pisoftware.com/bmarshal/publications/system_auth/sage-au/system_auth.html http://www.cosc.canterbury.ac.nz/~mpj17/ldap/
  • LDAP Authentication at Mandrake site
  • PADL Documentation
原创粉丝点击