在CentOS6上使用OpenLDAP统一管理服务器账户

安装OpenLDAP

  1. 创建管理OpenLDAP的用户和组

     groupadd ldap
     useradd -g ldap ldap
     passwd ldap
    
  2. 通过yum安装

     yum -y install openldap openldap-devel openldap-clients openldap-servers openssl nss_ldap
    
  3. 创建复制BDB数据库配置文件

     cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
     chown ldap:ldap /var/lib/ldap
     chmod -R 600 /var/lib/ldap
    
  1. 服务器配置

    • slapd.conf设置:

        vim /etc/openldap/slapd.conf
        suffix "dc=target2,dc=com"
        rootdn "cn=root,dc=target2,dc=com"
      
    • 设置管理员密码:

        slappasswd
        New password:
        Re-enter new password:
      
- 将哈希后产生的散列值添加进slapd.conf文件

        rootpw {SSHA}散列值
>注意:修改密码时需要注意rootpw前面不要有空格,以及rootpw与密码之间使用Tab键分割。
- 添加日志功能,在文件最后添加:

        vim /etc/openldap/slapd.conf
        loglevel 296
        vim /etc/syslog.conf
        local4.* /var/log/ldap.log

- 使客户端以MD5方式改变密码:

        vim slapd.conf
        #sample security restrictions
        password-hash {MD5}

 - 重启日志服务:

        service syslog restart

 - 开启LDAP服务:

        /usr/sbin/slapd
        netstat -an|grep 389

    如果启动正常应该有“389”端口信息。普通LDAP服务开放389端口。查看日志文件/var/log/ldap.log应该有启动信息。

 - 迁移用户数据到目录服务数据库:

        wget http://www.padl.com/download/MigrationTools.tgz
        tar zxvf MigrationTools.tgz -C /usr/local/openldap
        cd /usr/local/openldap/MigrationTools-47

 - 修改迁移脚本

        vim migrate_common.ph
        $DEFAULT_MAIL_DOMAIN="target2.com";
        $DEFAULT_BASE="dc=target2,dc=com";

 - 创建基本的数据结构

        ./migrate_base.pl> base.ldif
        ldapadd -x -D "cn=root,dc=target2,dc=com" -W -f base.ldif
        ldapsearch -x -H ldap://服务器地址 -b "dc=target2,dc=com"

 - 可以用此命令查询到数据库中已用了基本的层次结构

迁移passwd和group信息

        cat /etc/group > group.tmp
        ./migrate_group.pl group.tmp > group.ldif
        cat group.ldif

        cat /etc/passwd > passwd.tmp
        ./migrate_passwd.pl passwd.tmp > passwd.ldif
        cat passwd.ldif

        ldapadd -x -D "cn=root,dc=boy,dc=com" -W -f passwd.ldif
        ldapadd -x -D "cn=root,dc=boy,dc=com" -W -f group.ldif

- 查询用户信息应该有用户数据

        ldapadd -x -LLL|more
        ldapsearch -x -LLL -b "dc=ethan225,dc=com"|more

通过以上的操作,就将需要导入的组和用户的信息导入到了目录数据库中。
接下来还需要对客户端进行设置,使用LDAP进行登录验证操作。

设置客户端登录

若客户端要使用LDAP进行用户登录认证,则可使用本地计算机中不存在的用户名进行登录操作。

修改配置文件,设置客户端使用LDAP进行认证:

  • /etc/nsswith.conf

    要使身份验证查询通过LDAP服务器须在该文件中找到passwd、shadow、group三行在files后空格添加ldap

      vim /etc/nsswith.conf
      passwd: files ldap
      shadow: files ldap
      group: files ldap
    
  • /etc/sysconfig/authconfig

    该提供身份验证支持LDAP功能,找到以下七行,将值确定为yes:

      vim /etc/sysconfig/authconfig
      USESYSNETAUTH=yes
      USESHADOW=yes
      USELOCAUTHORIZE=yes
      USELDAP=yes
      USELDAPAUTH=yes
      USEMKHOMEDIR=yes
      PASSWDALGORITHM=yes
    
也可以用authconfig-tui命令打开一个图形化的界面来配置
  • /etc/pam.d/system-auth

    pam_unix.so模块是通用模块,使PAM机制对本地的/etc/passwd文件检查用户帐号。
    pma_ldap.so模块可以用来将身份验证重定向到LDAP目录上。

    /etc/pam.d/system-auth文件是CentOS5.2的系统认证PAM文件。在该文件的auth、account、password、session四段中pam_unix.so模块后添加pam_ldap.so模块使身份验证先对本地的/etc/passwd文件检查用户帐号,再对LDAP服务器进行检查。

    同时因为是LDAP认证需要为用户创建根目录,所以还必须在会话(SESSION)阶段增加pam_mkhomedir.so模块,为用户登录自动创建宿主目录。

      cp /etc/pam.d/system-auth /etc/pam.d/system-        auth.old
      vim /etc/pam.d/system-auth
      #%PAM-1.0
      #This file is auto-generated
      #User changes will be destroyed the next time         authconfig is run
      auth required pam_env.so
      auth sufficient pam_unix.so nullok try_first_pass
      auth requisite pam_succeed_if.so uid>=500 quiet
      auth sufficient pam_ldap.so
      auth required pam_deny.so
    
      account required pam_unix.so
      account sufficient pam_succeed_if.so uid<500 quiet
      account required 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
      password sufficient pam_ldap.so use_authtok md5
      password required pam_deny.so
    
      session optional pam_keyinit.so revoke
      session required pam_limits.so
      session [success=1 default=ignore]pam_succeed_if.so service in crond quiet
      session required pam_unix.so
      session required pam_mkhomedir.so skel=/etc/skel/ umask=0022
      session optional pam_ldap.so
    
  • /etc/openldap/ldap.conf

    该文件是LDAP服务器的客户端搜索工具文件

      vim /etc/openldap/ldap.conf
      BASE dc=target2,dc=com
      URI ldap://主服务器名(主), ldap://辅助服务器名 (备) (HOST=主HOST=备这样的形式也可)  
    
  • 客户端调试:

      ldapserch –x –LLL
      ldapsearch –x –LLL >ldapusers.ldif
      ldapsearch –x –LLL user1>user1.ldif
    
  • /etc/ldap.conf

    该文件也是LDAP服务器客户端文件,但是与/etc/openldap/ldap.conf文件有不同功能,找到如下三行去#并配置

      vim /etc/ldap.conf
      base dc=boy,dc=com
      uri ldap://主服务器名或地址 ldap://辅助服务器名或地址
      ssl off
    

    或者:

      pam_groupdn cn=主机名,ou=Hosts,dc=boy,dc=com
      pam_member_attribute uniquemember
    
  • 编一个设备登录组,开启名称缓存服务nscd

      service nscd restart
      chkconfig --level 3 5 nscd on
    

经过以上配置,在客户端就可以使用LDAP目录数据库中的用户信息在客户端进行登录操作了。
在客户端使用getent passwd、getent group 命令会显示所有的用户和组包括本地和LDAP服务器端数据库上的。

LDAP服务器复制

LDAP服务器可以备份冗余来提高系统得安全性。

复制是通过进程slurpd提供的,它会周期性的唤醒,并检查主服务器上的日志文件,从而确定是否有任何更新。这些更新然后会传播到从服务器上。

  • 主服务器关机后:

      vim slapd.conf
      replogfile /var/lib/ldap/openldap-master-replog
      replica uri=ldap://从服务器地址或主机名:389
      (空格)binddn="cn=root,dc=target2,dc=com"
      (空格)bindmethod=simple credentials=密码
    
  • 从服务器上配置:

    增加以下內容,其它同主服务器最初配置方法一样。

      vim slapd.conf
      updatedn "cn=root,dc=target2,dc=com"
      updateref ldap://主服务器地址或名:389
    
  • 从服务器上开启服务并将数据导入和主服务器一致:

      ldapadd -x -D "cn=root,dc=target2,dc=com" -W -f         ldapusers.ldif
    

    导入后再开启主服务器观察是否能复制同步。

  • 主服务器上:

      ldapdelete -x -D "cn=root,dc=target2,dc=com" -W "uid=user1,ou=People,dc=boy,dc=com"
    
从服务器上应该同步。

主服务器上/var/lib/ldap/replica/目录下有两个文件:

- slurpd.replog 复制日志,实际的变化以LDIF格式保存在其中。
- slurpd.status 复制时间纪录,同步时间戳。

复制可以看到一条端口通道

    netstat -an|grep 主服务器地址
主机地址:大于1000的端口号 从服务器地址:389。

slapd.conf配置文件要注意书写格式,默认是以空白符连接上一行的內容,如果是两行,中间不能有空格。

    slurpd -f /etc/ldap/slapd.conf

测试配置文件的语法正确性。

安全性

  • 根CA配置:

    编辑/etc/pki/tls/openssl.cnf 文件

      cp /etc/pki/tls/openssl.cnf /etc/pki/tls/openssl.cnf.bak
      vim /etc/pki/tls/openssl.cnf
      [CA_default]
      default_days = 3650 #证书有效期为十年
      [req]
      default_bits = 2048 #秘钥的字节
      [usr_cert]
      basicConstraints=CA: TRUE #可以签发下级
      [V3_req]
      basicConstraints = CA : TRUE
      cp /etc/pki/tls/openssl.cnf /etc/pki/tls/        openssl.cnf.rootca
    

编辑后改名openssl.cnf.rootca,制作根CA的配置文件,使其能够签发下级证书。

/etc/pki/tls/misc,该目录中的CA脚本文件可以用它来制作根CA。
删除默认CA文件夹

rm -rf /etc/pki/CA
vim CA
DAYS="-days 3650" #10years
CADAYS="-days 3650" #10years
./CA -newca

ll /etc/pki/CA/private/
cakey.pem #密钥

ll /etc/pki/CA/
cacert.pem #根CA的证书

验证,必须要显示以下信息,才表示可以签发下级证书:

openssl x509 -noout -text -in cacert.pem
X509V3 Constraints:
CA:TRUE
  • 签发LDAP服务器证书:

    LDAP服务器证书也由根CA签发,不过该证书在扩展结构上应该是一张终端用户证书,所以必须修改/etc/pki/tls/openssl.cnf文件适应变化。

      cp openssl.cnf.raw openssl.cnf
      vim openssl.cnf
      [CA_default]
      default_days=3650
      [req]
      default_bits=1024
      [usr_cert]
      basicConstraints=CA:FALSE
      [V3_req]
      basicContraints=CA:FALSE
    
      cd /etc/pki/tls/misc/
      ./CA -newreq
      ./CA -sign
    
  • 验证LDAP服务器端证书:

      openssl X509 -noout -text -in newcert.pem
      X509V3 Basic Constraints:
      CA:FALSE
    
      openssl verify -CAfile /etc/pki/CA/cacert.pem newcert.pem
    
成功会显示newcert.pem:OK,表明新证书newcert.pem是由根证书cacert.pem授权。

运行完两个步骤后,会发现当前目录下创建了3个文件:

- newreq.pem 创建证书请求文件,没什么用了
- newcert.pem CA签发的证书
- newkey.pem 证书对应的私钥
  • 辅助服务器上配置openssl.cnf文件同主服务器,唯有FQDN名不同。事实上用CA脚本签发证书是一种简捷方式,原始的命令行方式如下:

      openssl genrsa -es3 -out server.key 1024
    
  • 生成一把服务器RSA私钥

      openssl req -new -key server.key -out server.csr
    
  • 生成服务器证书申请文件。并将该证书申请文件安全(SCP)传送到根CA服务器上签发。

      cp server.csr /etc/pki/CA/private/
      openssl ca -out server.cert -policy_anything -infiles server.csr(有問題)
      openssl ca -out server.cert -infiles server.csr(用此句生成)
    
签发完毕后根CA服务器将自己的证书cacert.pem和server.cert都传回LDAP辅助服务器。
  • LDAP服务器配置使用SSL:

      vim slapd.conf
      TLSCACertificateFile /etc/openldap/cacerts/cacert.pem
      TLSCertificateFile /etc/openldap/cacerts/slapdcert1.pem
      TLSCertificatekeyFile /etc/openldap/cacerts/slapdkey1.pem
      TLSVerifyClient never
    
    第一行设置了根CA证书的存放路径
    第二行是服务器证书存放路径
    第三行是私钥的存放路径
    第四行表明服务器端不需要客户端提供证书这是一个单向认证。
  • 将指定文件复制到指定目录并更改权限为ldap所有,同时保证安全性。

      cp /etc/pki/CA/cacert.pem /etc/openldap/cacerts/
      cp server.cert /etc/openldap/cacerts/slapdcert1.pem
      cp /etc/pki/tls/misc/newcert.pem /etc/openldap/cacerts/slapdcert1.pem
      chown ldap:ldap slapdcert1.pem
      cp server.key /etc/openldap/cacerts/slapdkey1.pem
      cp /etc/pki/tls/misc/newkey.pem /etc/openldap/cacerts/slapdkey1.pem #这个才是证书对应的私钥
      chown ldap:ldap slapdkey1.pem
      chmod 400 slapdkey1.pem
    
  • 复制选项也要改变,因为SSL使用636安全通道。更改slapd.conf文件如下:

      vim slapd.conf
      replica uri=ldaps://辅助服务器名:636
      #starttls=critical
    
  • LDAP客户端配置支持安全通信:

    同理LDAP客户端也要配置支持LDAPS实现安全通信。

    将根CA证书分发给每一个客户端并存放在相应目录。配置/etc/ldap.conf和/etc/openldap/ldap.conf文件支持SSL。

      vim /etc/ldap.conf
      ssl on #启用ssl使用636端口
      ssl start_tls
      tls_checkpeer yes #检查对等体
      tls_cacertfile /etc/openldap/cacerts/cacert.pem #根CA文件路径
      pam_password md5 #密码md5认证
    
      vim/etc/openldap/ldap.conf
      URI ldaps://主服务器器完全名 ldaps://辅助服务器完全名(添加S)
      BASE dc=boy,dc=com
      TLS_CACERT /etc/openldap/cacerts/cacert.pem
      TLS_REQCERT demand #客户端必须要求服务器端证书
    
  • 客户端测试连接命令:

      openssl s_client -connect 服务器完全名:636 -state -CAfile /etc/openldap/cacerts/cacert.pem
      verify return code:0(ok)
      #表示成功
    
      service nscd restart
      ldapsearch -x -LLL -H ldaps://CA:636
      getent passwd
      netstat -an | grep 636
      #通过以上三个命令查看服务是否成功。
      LDAPS采用636通道,安装完毕可关闭389普通服务端口
    
  • 问题

      ldapsearch -x -LLL -H ldaps://CA:636
    
如直接用IP,可能出现下面的报错,这是由于IP和前面CN=CA不一致:

    ldap_bind: Can't contact LDAP server (-1)
    additional info: TLS: hostname does not match CN in peer certificate
这是指主机名称与CN里设置的不一至,应该保证主机名、CN一致。

LDAP密码更改

LDAP用户改密码的标准格式

lappasswd -x -D "cn=admin,ou=People,dc=boy,dc=com" -W "uid=admin,ou=People,dc=boy,dc=com" -S
  • /etc/ldap.secret

    该文件是绑定管理员的密码,需手工编写存放有资格修改用户密码的LDAP管理员密码。要使该文件生效还必须在/etc/ldap.conf 文件中设置rootbinddn uid=admin,ou=People,dc=target2,dc=com
    这样客户端就可以使用passwd 命令修改密码。

    但是必须注意如果本地/etc/passwd中有同名帐户的话则改本地,本地没有同名用户则改远程LDAP服务器数据库中的用户密码。

    辅服务器中的updateref指令对超级管理员无效。

      updateref ldap://LDAP.target2.com:636
    

    表明该辅助服务器只能读不能“写”只能查询不能更改数据

    普通用户向辅助服务器修改数据会出现

      Referral :ldaps://LDAP.boy.com:636
    

    但对超级管理员才cn=root,dc=target2,dc=com 无效。

修改用户密码,用户需要有userPassword项了。

    ldappasswd -x -D "cn=Manager,dc=igoo,dc=cn" -W "uid=miaohongzhi,ou=People,dc=igoo,dc=cn" -S
    New password:
    Re-enter new password:
    Enter bind password:
    Result: Success (0)


注意:"Enter bind password""cn=root,dc=target2,dc=com"管理员的密码。
  • 删除命令ldapdelete

    ldapdelete -x -D “cn=root,dc=target2,dc=com” -W “uid=ldapuser01,ou=People,dc=target2,dc=com”

  • 管理员密码更改

    slappasswd
    New password
    Re-enter new password
    {SSHA}83DJ4KVwqlk1uh9k2uDb8+NT1U4RgkEs

copy到 /path/to/sldap.conf 的 rootpw 即可,重启使用配置文件生效
  • 通过ldapmodify修改条目

      cat modify.ldif
      dn: uid=ldapuser01,ou=People,dc=igoo,dc=cn
      changetype: modify
      replace: loginShell
      loginShell: /bin/false
    

定时备份

vim /usr/local/sbin/ldapbackup.sh
#!/bin/bash
Date=`date +%Y%m%d`
slapcat > /data/backup/ldapdata.ldif.$Date
chmod 700 /usr/local/sbin/ldapbackup.sh
crontab -e
30 0 * * * /usr/local/sbin/ldapbackup.sh

设备登录限制

服务器上数据库中LDAP用户添加host属性可以登录指定主机

dn:uid=testuser,ou=People,dc=boy,dc=com
uid: testuser
cn: testuser
objectClass:account
objectClass:posixAccount
objectClass:shadowAccount
loginShell:/bin/bash
uidNumber:1001
gidNumber:1001
homeDirectory:/home/user1
host:client1.boy.com
host:client2.boy.com

客户端client1.target2.com

vim /etc/ldap.conf
#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 will not be allowed to login.
pam_check_host_attr yes

也可以反过来针对每一个客户端主机来指定可以登录的用户
LDAP数据库中例:

dn:cn=client1.target2.com,ou=Hosts,dc=target2,dc=com
ipHostNumber: 192.168.10.7
cn:client1.target2.com
objectClass:ipHost
objectClass:device
objectClass:extensibleObject
uniqueMember:uid=root,ou=People,dc=target2,dc=com
uniqueMember:uid=testuser,ou=People,dc=target2,dc=com

客户端配置:

vim /etc/ldap.conf
pam_groupdn cn=client1.target2.com,ou=Hosts,dc=target2,dc=com
pam_member_attribute uniquemember

其实还可以做更简单的配置在客户端主机上修改/etc/ldap.conf文件来限定搜索LDAP服务器目录树的范围

vim /etc/ldap.conf
nss_base_passwd ou=IT,ou=People,dc=target2,dc=com
nss_base_shadow ou=IT,ou=People,dc=target2,dc=com
nss_base_group ou=IT,ou=Group,dc=target2,dc=com

这样LDAP帐户在登录时会限定绑定服务器数据库的范围在IT部。

用ACL来控制用户访问LDAP数据库的权限

Openldap使用ACL访问控制列表来实现权限的控制,经典访问控制在LDAP服务器端/etc/openldap/slapd.conf文件中access设置

vim /etc/openldap/slapd.conf
access to attrs=userPassword
by anonymous auth
by dn= “cn=Manager,dc=boy,dc=com” write
by dn=”uid=admin,ou=People,dc=boy,dc=com” write
by self write
access to *
by dn=”cn=Manager,dc=boy,dc=com” write
by self write
by * read

使用该配置匿名用户不能查询他人密码,用户admin拥有修改密码特权。

参考:
http://jianshi-dlw.iteye.com/blog/1557846
http://gxjluck.blog.51cto.com/1211751/794323
http://blog.csdn.net/zhxue123/article/details/7409996