pam_ldap详细配置

来源:互联网 发布:三菱plc模拟软件 编辑:程序博客网 时间:2024/05/01 13:36

本文转自《pam_ldap详细配置》

 

Fedora 6下配置nss_ldap,pam_ldap,openldap以及加入ssl/tls安全认证
nss_ldap-253-1 包含两个模块:nss_ldap和pam_ldap
nss_ldap: 其中nss是name service switch.nss_ldap模块用以连接ldap服务器,可以让系统识别ldap中的用户和群组。
pam_ldap: pam是Pluggable Authentication Module,即插件式认证模块。它集成了很多种认证方法,pam_ldap是其中的一种,调用ldap验证用户的身份。这里的ldap我用的是openldap。

配置各个文件的时候注意备份,以便出错以后进行恢复。

首先设置 /etc/sysconfig/authconfig,这个文件用来跟踪特定身份验证机制是否已经启用。我们可以希望以下条目的值都是 “yes”:

USELDAP=yes
USELDAPAUTH=yes
USEMD5=yes
USESHADOW=yes
USELOCAUTHORIZE=yes

配置/etc/nsswitch.conf文件:

passwd: files
shadow: files
group: files
改为:
passwd: files ldap
shadow: files ldap
group: files ldap
让系统能够识别ldap中的用户和群组。

配置/etc/ldap.conf:
(注意:linux中还有一个/etc/openldap/ldap.conf文件,这个是openldap的客户端配置文件。
/etc/ldap.conf是nss_ldap,pam_ldap需要调用的配置文件)
先不考虑加入ssl
添加:
base dc=myserver,dc=com
uri ldap://myserver.com  (ldap服务器的uri,myserver.com必须能被解析,nss_ldap调用它连接ldap服务器。这个设置和 "host myserver.com"是等价的,设置其中的一个就可以了。但是这个比较灵活,当开启ssl时,就可以设为"ldaps://myserver.com",host就不行)
binddn cn=Manager,dc=myserver,dc=com (可选,默认为匿名绑定)
bindpw secret

配置/etc/pam.d/system.auth:
system.auth是系统认证的配置文件,pam.d文件夹中还有很多文件,如sshd,login等等,打开以后会发现有这些语句:auth include system-auth
这句话的意思是ssh的认证(auth)模块是调用system-auth文件中的(auth)认证模块的设置。所以我们设置system-auth文件的同时,实际上就把很多其它文件如ssh,login也设置了。

配置的语句格式:service-name module-type control-flag module-path arguments

service-name 服务的名字,比如telnet、login、ftp等,服务名字“OTHER”代表所有没有在该文件中明确配置的其它服务。

module-type 模块类型有四种:auth、account、session、password,即对应PAM所支持的四种管理方式。同一个服务可以调用多个 PAM模块进行认证,这些模块构成一个stack。四种模块如下:
1 auth:认证管理(authentication management)主要是接受用户名和密码,进而对该用户的密码进行认证,并负责设置用户的一些秘密信息。

2 account:帐户管理(account management)主要是检查帐户是否被允许登录系统,帐号是否已经过期,帐号的登录是否有时间段的限制等等。

3 password:密码管理(password management)主要是用来修改用户的密码。

4 session:会话管理(session management)主要是提供对会话的管理和记账(accounting)。

control-flag 用来告诉PAM库该如何处理与该服务相关的PAM模块的成功或失败情况。它有四种可能的 值:required,requisite,sufficient,optional。

1 required 表示本模块必须返回成功才能通过认证,但是如果该模块返回失败的话,失败结果也不会立即通知用户,而是要等到同一stack 中的所有模块全部执行完毕再将失败结果返回给应用程序。可以认为是一个必要条件。

2 requisite 与required类似,该模块必须返回成功才能通过认证,但是一旦该模块返回失败,将不再执行同一stack内的任何模块,而是直 接将控制权返回给应用程序。是一个必要条件。注:这种只有RedHat支持,Solaris不支持。

3 sufficient 表明本模块返回成功已经足以通过身份认证的要求,不必再执行同一stack内的其它模块,但是如果本模块返回失败的话可以 忽略。可以认为是一个充分条件。

4 optional表明本模块是可选的,它的成功与否一般不会对身份认证起关键作用,其返回值一般被忽略。

对于control-flag,从Linux-PAM-0.63版本起,支持一种新的语法,具体可参看LinuxPAM文档。

module-path 用来指明本模块对应的程序文件的路径名,一般采用绝对路径,如果没有给出绝对路径,默认该文件在目录/usr/lib/security下 面。

arguments 是用来传递给该模块的参数。一般来说每个模块的参数都不相同,可以由该模块的开发者自己定义,但是也有以下几个共同 的参数:

debug 该模块应当用syslog( )将调试信息写入到系统日志文件中。

no_warn 表明该模块不应把警告信息发送给应用程序。

use_first_pass 表明该模块不能提示用户输入密码,而应使用前一个模块从用户那里得到的密码。

try_first_pass 表明该模块首先应当使用前一个模块从用户那里得到的密码,如果该密码验证不通过,再提示用户输入新的密码。

use_mapped_pass 该模块不能提示用户输入密码,而是使用映射过的密码。

expose_account 允许该模块显示用户的帐号名等信息,一般只能在安全的环境下使用,因为泄漏用户名会对安全造成一定程度的威 胁。

配置后如下:
auth        required      pam_env.so
auth        sufficient    pam_unix.so nullok try_first_pass (pam_unix.so验证本地系统的用户)
auth        requisite     pam_succeed_if.so uid >= 500 quiet(uid<500的用户,即系统用户不会进行ldap验证。uid>=500的用户不管是不是ldap中的用户都要进行ldap验证)
auth        sufficient    pam_ldap.so use_first_pass        (pam_ldap.so验证ldap中的用户)
auth        required      pam_deny.so

account     required      pam_unix.so broken_shadow
account     sufficient    pam_succeed_if.so uid < 500 quiet  (如果uid<500则不会进行ldap验证,在ldap服务器未开启的时候root可以运行ssh,login命令,其它uid>=500的用户则不行,因为这些用户会进行下面的ldap验证,ldap未开启时是不能进行验证的,所以会fail)
account [default=bad success=ok user_unknown=ignore] pam_ldap.so
account     required      pam_permit.so

password    requisite     pam_cracklib.so try_first_pass retry=3  (更改密码)
password    sufficient    pam_unix.so md5 shadow nullok try_first_pass use_authtok(use_authtok强制使用上个语句的密码,适用于密码被更改的情况)
password    sufficient    pam_ldap.so use_authtok
password    required      pam_deny.so

session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
session    [success=ok default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required      pam_unix.so
session     required      pam_mkhomedir.so skel=/etc/skel/ umask=0022 (为用户创建根目录)
session     optional      pam_ldap.so

要用ldap中的用户进行login,ssh登录,需要为ldap用户添加uidNumber和gidNumber,可以用以下脚本建立用户和组:
users.ldif:

dn: uid=test,dc=myserver,dc=com
uid: test
cn: test
sn: test
mail: test@163.com
userPassword:yourpassword
uidNumber: 1104
gidNumber: 1104
homeDirectory: /home/test
loginShell: /bin/bash
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: top

group.ldif:

dn: cn=test,dc=myserver,dc=com
cn: test
gidNumber: 1104
objectClass: posixGroup

ldapadd -x -D "cn=Manager,dc=myserver,dc=com" -W -f users.ldif
ldapadd -x -D "cn=Manager,dc=myserver,dc=com" -W -f group.ldif

启动openldap服务器:
/usr/local/libexec/slapd
然后运行 id test
会出现结果uid=1104(test) gid=1104(test) groups=1104(test)
说明test这个用户已经可以被用户识别了。
这样test用户可以登录系统了。PAM 身份验证服务就会从用户那里获取用户名test。PAM先从本地系统中寻找test用户,
会执行语句auth        sufficient    pam_unix.so nullok try_first_pass
这时肯定会失败,因为test在ldap中。接下来会进行ldap验证,从 LDAP 服务器中检索识别名(DN)条目 .dn: uid=test,dc=myserver,dc=com.。PAM 然后会从用户那里获取密码。然后 PAM 试图使用这个 DN 和密码与 LDAP 服务器进行绑定。DN 和密码都以明文文本的格式发送给 LDAP 服务器。在对密码进行散列操作之后,如果服务器可以让用户登录,就会向 PAM 报告说已经成功进行了绑定。成功绑定可以完全满足 PAM 对 pam_ldap 模块汇报成功的标准,如果所有其他 PAM 标准都已经满足了,那么就允许用户登录到系统中。

当前的用户密码是以明文文本格式传输的,不能满足安全身份验证的需求,需要设置ssl/tls,保证安全传输。
需要安装openssl。
用openssl提供的CA脚本,自己签发证书:
第一步:
执行/usr/share/ssl/misc/CA.sh -newca
显示:
CA certificate filename (or enter to create)

Making CA certificate ...
Using configuration from /etc/ssl/openssl.cnf
Generating a 1024 bit RSA private key
..........................++++++
.........................++++++
writing new private key to './demoCA/private/./cakey.pem'
Enter PEM pass phrase:
Verifying password - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:Texas
Locality Name (eg, city) []:Austin
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example Org
Organizational Unit Name (eg, section) []:Example Unit
Common Name (eg, YOUR name) []:example.com
Email Address []:.
%
会生成 demoCA/cacert.pem和demoCA/private/cakey.pem(即CA证书和私钥)

第二步:服务器签署请求(CSR)
执行openssl req -newkey rsa:1024 -nodes -keyout newreq.pem -out newreq.pem

Using configuration from /etc/ssl/openssl.cnf
Generating a 1024 bit RSA private key
..............++++++
..........................++++++
writing new private key to 'newreq.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:Texas
Locality Name (eg, city) []:Austin
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example Org
Organizational Unit Name (eg, section) []:Example Org Unit
Common Name (eg, YOUR name) []:myserver.com
Email Address []:ldap@myserver.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:.
%
注意Common Name必须是ldap服务器的域名,如myserver.com,这个很重要,如果输错的话,ssl认证将会失败。
生成newreq.pem

第三步:签署(CSR)
执行usr/share/ssl/misc/CA.sh -sign

Using configuration from /etc/ssl/openssl.cnf
Enter PEM pass phrase:
Check that the request matches the signature
Signature ok
The Subjects Distinguished Name is as follows
countryName :PRINTABLE:'US'
stateOrProvinceName :PRINTABLE:'Texas'
localityName :PRINTABLE:'Austin'
organizationName :PRINTABLE:'Example Org'
organizationalUnitName:PRINTABLE:'Example Org Unit'
commonName :PRINTABLE:'myserver.com'
emailAddress :IA5STRING:'ldap@myserver.com'
Certificate is to be certified until Apr 10 18:58:58 2004 GMT (365 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1 (0x1)
Signature Algorithm: md5WithRSAEncryption
Issuer: C=US, ST=Texas, L=Austin, O=Example Org, OU=Example Unit, CN=example.com
Validity
Not Before: Apr 11 18:58:58 2003 GMT
Not After : Apr 10 18:58:58 2004 GMT
Subject: C=US, ST=Texas, L=Austin, O=Example Org, OU=Example Org Unit, CN=myserver.com/Email=ldap@myserver.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (1024 bit)
Modulus (1024 bit):
< ... >
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
D0:C0:9D:46:30:65:2A:9C:63:63:6A:E6:FE:E4:AC:F7:21:F8:33:61
X509v3 Authority Key Identifier:
keyid:31:2E:0D:FB:A0:74:5A:0B:4B:C5:C4:E0:69:7F:32:6D:AF:46:82:F1
DirName:/C=US/ST=Texas/L=Austin/O=Example Org/OU=Example Unit/CN=example.com
serial:00

Signature Algorithm: md5WithRSAEncryption
< ... >
-----BEGIN CERTIFICATE-----
< ... >
-----END CERTIFICATE-----
Signed certificate is in newcert.pem
%
生成newcert.pem

第四步:
% cp demoCA/cacert.pem /usr/var/openldap-data/cacert.pem
% mv newcert.pem /usr/var/openldap-data/servercrt.pem
% mv newreq.pem /usr/var/openldap-data/serverkey.pem
% chmod 400 /usr/var/openldap-data/serverkey.pem  (将私钥设为只读)

设置openldap

服务器端设置(slapd.conf):
需要加入
TLSCipherSuite HIGH:MEDIUM:+SSLv2
TLSCACertificateFile /usr/var/openldap-data/cacert.pem
TLSCertificateFile /usr/var/openldap-data/servercrt.pem
TLSCertificateKeyFile /usr/var/openldap-data/serverkey.pem
完整slapd.conf如下:
#######################################################################
# $OpenLDAP: www/pages/pub/ksoper/OpenLDAP_TLS.html,v 1.1 2007/10/09 21:28:09 kurt Exp $
#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#
include /usr/etc/openldap/schema/core.schema
include /usr/etc/openldap/schema/cosine.schema
include /usr/etc/openldap/schema/inetorgperson.schema
include /usr/etc/openldap/schema/misc.schema
include /usr/etc/openldap/schema/openldap.schema

# Define global ACLs to disable default read access.

# Do not enable referrals until AFTER you have a working directory
# service AND an understanding of referrals.
#referral ldap://root.openldap.org

pidfile /usr/var/slapd.pid
argsfile /usr/var/slapd.args

# Load dynamic backend modules:
# modulepath /usr/libexec/openldap
# moduleload back_bdb.la
# moduleload back_ldap.la
# moduleload back_ldbm.la
# moduleload back_passwd.la
# moduleload back_shell.la

# Sample security restrictions
#
# Disallow clear text exchange of passwords
# disallow bind_simple_unprotected
#
# Require integrity protection (prevent hijacking)
# Require 112-bit (3DES or better) encryption for updates
# Require 63-bit encryption for simple bind
# security ssf=1 update_ssf=112 simple_bind=64

# Sample access control policy:
# Root DSE: allow anyone to read it
# Subschema (sub)entry DSE: allow anyone to read it
# Other DSEs:
# Allow self write access
# Allow authenticated users read access
# Allow anonymous users to authenticate
# Directives needed to implement policy:
# access to dn.base="" by * read
# access to dn.base="cn=Subschema" by * read
access to attr=userPassword
        by anonymous auth
        by self write
        by * none
access to *
        by self write
        by * read

# if no access controls are present, the default policy is:
# Allow read by all
#
# rootdn can always write!

# CA signed certificate and server cert entries:

TLSCipherSuite HIGH:MEDIUM:+SSLv2
TLSCACertificateFile /usr/var/openldap-data/cacert.pem
TLSCertificateFile /usr/var/openldap-data/servercrt.pem
TLSCertificateKeyFile /usr/var/openldap-data/serverkey.pem

# Use the following if client authentication is required
TLSVerifyClient demand
# ... or not desired at all
#TLSVerifyClient never

#######################################################################
# ldbm database definitions
#######################################################################

database ldbm
#suffix "dc=my-domain,dc=com"
#rootdn "cn=Manager,dc=my-domain,dc=com"
suffix "dc=myserver,dc=com"
rootdn "cn=Manager,dc=myserver,dc=com"

# Cleartext passwords, especially for the rootdn, should
# be avoided. See slappasswd(8) and slapd.conf(5) for details.
# Use of strong authentication encouraged.
#rootpw secret
rootpw {SSHA}/nM76XvHqgByMF/mplwZ4EuP6EjSPCFc

# The database directory MUST exist prior to running slapd AND
# should only be accessible by the slapd and slap tools.
# Mode 700 recommended.
directory /usr/var/openldap-data

# Indices to maintain
index objectClass eq

客户端设置:
/etc/openldap/ldap.conf中加入
HOST myserver.com
PORT 636

TLS_CACERT /usr/var/openldap-data/cacert.pem
TLS_REQCERT demand
如果客户端和服务器不在同一台机器上 ,需要将cacert.pem文件拷贝一份到客户端的机器上。

另外还须在/etc/ldap.conf中添加和修改:
将uri ldap://myserver.com 改为 uri ldaps://myserver.com
添加:
# OpenLDAP SSL mechanism, start_tls mechanism uses the normal LDAP port 389
ssl on  (如果是start_tls的话用默认端口389,ssl on使用端口636)
#Require and verify server certificate
tls_checkpeer yes
# CA certificates for server certificate verification
tls_cacertfile /usr/var/openldap-data/cacert.pem
pam_password md5

完整/etc/ldap.conf如下:
base dc=myserver,dc=com
uri ldaps://myserver.com 
binddn cn=Manager,dc=myserver,dc=com
bindpw secret
# OpenLDAP SSL mechanism, start_tls mechanism uses the normal LDAP port 389
ssl on 
#Require and verify server certificate
tls_checkpeer yes
# CA certificates for server certificate verification
tls_cacertfile /usr/var/openldap-data/cacert.pem
pam_password md5

最后重新启动ldap服务器:
/usr/local/libexec/slapd -h "ldaps:///"

在客户端可以用
openssl s_client -connect myserver.com:636 -showcerts -state -CAfile /usr/var/openldap-data/cacert.pem
测试ssl连接是否能用。

用ldapsearch -x -b 'dc=myserver,dc=com' -D "cn=Manager,dc=myserver,dc=com" '(objectclass=*)' -H ldaps://myserver.com -W
测试能不能连上ldap服务器

这时再用test用户登录一下,看一下能不能成功。

还有个问题需要说明一下,如果客户端和服务器为同一台机器,机器启动时会在启动系统消息总线时停顿很久,这好像是nss_ldap在连接ldapserver,由于ldap服务器还没有启动,系统会用上好几分钟的时间反复连接,直至最后连接失败。
客户端和服务器不在同一台机器上的话就没有这个问题。

 

参考资料:


用LDAP管理用户和组
http://gnawux.bokee.com/4721705.html
使用openldap集中管理用户帐号
http://linux.chinaitlab.com/administer/519684.html
OpenLDAP Sever with server-side ssl/tls and client authentication
http://www.openldap.org/pub/ksoper/OpenLDAP_TLS.html#4.0

原创粉丝点击