Total Pageviews

Wednesday, 15 November 2017

Setting up OpenLDAP server with OpenSSH-LPK on Ubuntu 14.04

This post documents how to set up a secure OpenLDAP server that is able to make OpenLDAP client servers accept authorized SSH access requests from users. The following steps assume the OpenLDAP server (slapd) and phpLDAPadmin are installed as referenced in the initial setup.

Instructions and references

Understanding cn=config (LDAP database)

The default installation of OpenLDAP in recent versions of Ubuntu uses the new runtime configuration (RTC) system or olc (OpenLDAP Configuration). This installation uses cn=config (the LDAP database) for configuration rather than the old style slapd.conf.

Schemas

The schemas can be imported dynamically into cn=config database, without restarting slapd. The schemas to be imported can placed in /etc/ldap/schema.
The following schema in ldif format will be used and discussed in the subsequent sections:
  • openssh-lpk.ldif
  • ldap_disable_bind_anon.ldif
  • ssl.ldif

Importing openssh-lpk scheme

ldapadd -Y EXTERNAL -H ldapi:/// -f openssh-lpk.ldif
where openssh-lpk.ldif is:
dn: cn=openssh-lpk,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: openssh-lpk
olcAttributeTypes: ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey'
  DESC 'MANDATORY: OpenSSH Public key'
  EQUALITY octetStringMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
olcObjectClasses: ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY
  DESC 'MANDATORY: OpenSSH LPK objectclass'
  MAY ( sshPublicKey $ uid )
  )

Forcing authentication

By default, OpenLDAP allows anonymous query from any client servers. You may want to enable authentication so that only authenticated clients are able to query the server:
ldapadd -Y EXTERNAL -H ldapi:/// -f ldap_disable_bind_anon.ldif
where ldap_disable_bind_anon.ldif is:
dn: cn=config
changetype: modify
add: olcDisallows
olcDisallows: bind_anon

dn: cn=config
changetype: modify
add: olcRequires
olcRequires: authc

dn: olcDatabase={-1}frontend,cn=config
changetype: modify
add: olcRequires
olcRequires: authc

Securing LDAP with TLS

  • Install the package that provides certtool:
    apt-get install gnutls-bin
    
  • Generate new certificate (self-signed) and key:
    mkdir -p /etc/ldap/gnutls
    cd  /etc/ldap/gnutls
    certtool --generate-self-signed --load-privkey ldap.gnutls.key --outfile ldap.gnutls.crt
    
  • Fix permission of private key:
    chmod +r /etc/ldap/gnutls/ldap.gnutls.key
    

Importing SSL schema

ldapmodify -Y EXTERNAL -H ldapi:/// -f ssl.ldif
where ssl.ldif is:
dn: cn=config
changetype: Modify
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ldap/gnutls/ldap.gnutls.key
-
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ldap/gnutls/ldap.gnutls.crt
-
add: olcTLSCipherSuite
olcTLSCipherSuite: NORMAL
-
add: olcTLSCRLCheck
olcTLSCRLCheck: none
-
add: olcTLSVerifyClient
olcTLSVerifyClient: never

Enabling LDAPS

By default, only ldap and ldapi (Unix domain socket) are enabled. Make ldaplisten to only 127.0.0.1 and keep the latter so that you can run ldap utilty commands against ldapi:/// without providing credentials if working on the same server.
Edit /etc/default/slapd and ensure the following line:
SLAPD_SERVICES="ldap://127.0.0.1:389/ ldaps:/// ldapi:///"

Configuring /etc/ldap/ldap.conf

Edit /etc/ldap/ldap.conf and add the following line:
TLS_REQCERT never

Testing the above LDAPS config

ldapsearch -d 9 -D "cn=Bob,ou=users,dc=example,dc=com" \
 -w password -b "dc=example,dc=com" -H "ldaps://ldap.example.org" "objectClass=*"

Customizing phpLDAPadmin config and templates

You can customize template configurations (/etc/phpldapadmin/config.php).
For example, change the base uid and gid to a greater value:
$servers->setValue('auto_number','min',array('uidNumber'=>3000,'gidNumber'=>3000));
Add
$config->custom->appearance['theme'] = 'tango';
You can also customize templates for various components, for example, POSIX account:
  • /etc/phpldapadmin/templates/creation/posixAccount.xml
Customize themes and styles:
  • /usr/share/phpldapadmin/lib/page.php
  • /usr/share/phpldapadmin/htdocs/css/tango/style.css

Adding a user with SSH public key in phpLDAPadmin

First, create a user with the “Generic: User Account” template. Then, go to the “objectClass” attribute section, click “add value”, and choose the “ldapPublicKey” attribute. After you submit, go back to the user edit page, click “Add new attribute” on the top part, and choose “sshPublicKey”, paste the public key into the text area, and finally click “Update Object”.
----------------

Setting up OpenLDAP client with SSH access on Ubuntu 14.04

This post documents how to set up an OpenLDAP client server (Ubuntu 14.04) that can make its OpenSSH server to load authorized keys from a pre-configured OpenLDAP server with ldaps:// available (discussed in the above post, please read this first if you haven’t). Users are able to SSH access this client server, while their SSH public keys are stored on the OpenLDAP server. The SSH authentication process on the client server is mainly facilitated by ssh-ldap-pubkey.

Install packages

apt-get -y install libpam-ldap nscd ldap-utils
apt-get -y install python-pip python-ldap
# https://github.com/jirutka/ssh-ldap-pubkey
pip install ssh-ldap-pubkey

Configure SSH server

  • Add the following lines to /etc/ssh/sshd_config:
    AuthorizedKeysCommand /usr/local/bin/ssh-ldap-pubkey-wrapper
    AuthorizedKeysCommandUser nobody
    
  • Restart SSH server
    service ssh restart
    

Configure PAM

  • Edit /etc/ldap.conf:
    uri ldaps://ldap.example.com
    binddn cn=OpenLDAP Client,ou=users,dc=example,dc=com
    bindpw password
    
  • Edit /etc/pam.d/common-auth and add the following line:
    account required    pam_access.so
    
  • Edit /etc/pam.d/common-password and remove use_authtok parameter
  • Edit /etc/pam.d/common-session and add the following line:
    session required    pam_mkhomedir.so skel=/etc/skel umask=0022
    

Configure NSS, login access control and sudo

  • Edit /etc/nsswitch.conf:
    passwd:         compat ldap
    group:          compat ldap
    shadow:         compat ldap
    
  • Edit /etc/security/access.conf, replace ldap-team with actual group name:
    - : ALL EXCEPT root (admin) (wheel) (ldap-team): ALL EXCEPT LOCAL
    
  • Edit /etc/sudoers using visudo command and add the following lines. Replace ldap-team with actual group name:
    %ldap-team ALL=(ALL) ALL
    
  • Restart nscd
    service nscd restart
  • 附录:setup-ldap-client.sh:
  • #!/bin/bash
    # vim: softtabstop=4 shiftwidth=4 expandtab fenc=utf-8 spell spelllang=en cc=120
    
    set -e
    
    # Check Ubuntu release
    [ "$(lsb_release -sc)" = "trusty" ] || {
        echo 'This script should be run on Ubuntu 14.04.' >&2
        exit 1
    }
    
    # LDAP group name of team members to be granted access on this server,
    LDAP_TEAM_NAME=$1
    LDAP_BASE="dc=example,dc=com"
    LDAP_URI="ldaps://ldap.example.com"
    LDAP_BINDDN="cn=OpenLDAP Client,ou=users,dc=example,dc=com"
    LDAP_BINDPW="password"
    
    USAGE="usage: ./$(basename $0) LDAP_TEAM_NAME"
    
    # Check required positional parameters
    [ $# -ne 1 ] && {
        echo "$USAGE" >&2
        exit 1
    }
    # Install required packages
    export DEBIAN_FRONTEND=noninteractive
    # The following command will implicitly install libnss-ldap
    apt-get -y install libpam-ldap nscd ldap-utils
    apt-get -y install python-pip python-ldap
    pip install ssh-ldap-pubkey
    
    # Configure SSH server
    grep 'AuthorizedKeysCommand' /etc/ssh/sshd_config > /dev/null || {
        cat >> /etc/ssh/sshd_config <<EOF
    AuthorizedKeysCommand /usr/local/bin/ssh-ldap-pubkey-wrapper
    AuthorizedKeysCommandUser nobody
    EOF
    }
    
    # Restart SSH server
    service ssh restart
    
    # Edit /etc/ldap.conf
    mv /etc/ldap.conf /etc/ldap.conf.bak
    cat > /etc/ldap.conf <<EOF
    base $LDAP_BASE
    uri $LDAP_URI
    ldap_version 3
    binddn $LDAP_BINDDN
    bindpw $LDAP_BINDPW
    pam_password md5
    nss_initgroups_ignoreusers backup,bin,daemon,games,gnats,irc,landscape,libuuid,list,lp,mail,man,messagebus,news,pollinate,proxy,root,sshd,sync,sys,syslog,uucp,www-data
    bind_timelimit 3
    timelimit 3
    EOF
    
    # Edit /etc/ldap/ldap.conf
    cp /etc/ldap/ldap.conf /etc/ldap/ldap.conf.bak
    grep 'TLS_REQCERT' /etc/ldap/ldap.conf > /dev/null || {
        cat >> /etc/ldap/ldap.conf <<EOF
    TLS_REQCERT     never
    EOF
    }
    
    # Configure PAM
    # Add pam_access.so
    grep 'pam_access.so' /etc/pam.d/common-auth > /dev/null || {
        cat >> /etc/pam.d/common-auth <<EOF
    account required    pam_access.so
    EOF
    }
    
    # Remove use_authtok from /etc/pam.d/common-password
    sed -i -r 's/(.*)(use_authtok)(.*)/\1\3/g' /etc/pam.d/common-password
    
    # Add pam_mkhomedir.so
    grep 'pam_mkhomedir.so' /etc/pam.d/common-session > /dev/null || {
        cat >> /etc/pam.d/common-session <<EOF
    session required    pam_mkhomedir.so skel=/etc/skel umask=0022
    EOF
    }
    
    # Configure NSS
    sed -i -r 's/(^passwd:)(\s+)(.*)/\1\2compat ldap/' /etc/nsswitch.conf
    sed -i -r 's/(^group:)(\s+)(.*)/\1\2compat ldap/' /etc/nsswitch.conf
    sed -i -r 's/(^shadow:)(\s+)(.*)/\1\2compat ldap/' /etc/nsswitch.conf
    
    # Edit /etc/security/access.conf
    grep -- '^- : ALL EXCEPT root' /etc/security/access.conf > /dev/null || {
        cat >> /etc/security/access.conf <<EOF
    + : ($LDAP_TEAM_NAME) : ALL
    - : ALL EXCEPT root (admin) (wheel) : ALL EXCEPT LOCAL
    EOF
    }
    
    # Edit /etc/sudoers
    grep -F -- "%$LDAP_TEAM_NAME" /etc/sudoers > /dev/null || {
        cat >> /etc/sudoers <<EOF
    %$LDAP_TEAM_NAME ALL=(ALL) ALL
    EOF
    }
    
    # Restart nscd
    service nscd restart
    ----------------------------------
  • Setting up nss-ldapd on Ubuntu 14.04

    The last few posts discussed ‘setting up an OpenLDAP server’ and ‘configuring basic client server’. However, that client server uses nss-ldap with some known issues as presented here. With this old and seemingly buggy setup, I simply can’t make nss_initgroups_ignoreuses option work to bypass querying the LDAP server when authenticating local or system users on the server, and have no idea what nssldap-update-ignoreusers command actually does. When the LDAP server is down or there is network issues connecting the LDAP server, the default configuration will simply block local users from logging in the server (at least for a long time until the query is considered timed out). Also, as I found after checking /var/log/auth.log, it queries the LDAP server even when doing a Bash completion, because it was very slow when I pressed the TAB key after a path name. Setting bind_policy option to soft and timelimit and bind_timelimit to smaller values may just alleviate the symptom but does not solve the problem.
    So I decide to use nss-ldapd that comes with the libnss-ldapd package.
    apt-get install libpam-ldap nscd ldap-utils libnss-ldapd
    
    Running the above command will automatically remove the libnss-ldap package and prompt interacive post-install steps for you to configure the LDAP parameters. You can disable this interactive behavior and directly place your config in /etc/nslcd.conf with the following command:
    export DEBIAN_FRONTEND=noninteractive
    apt-get -y install libpam-ldap nscd ldap-utils libnss-ldapd
    
    Then, put your config in /etc/nslcd.conf:
    uid nslcd
    gid nslcd
    uri ldaps://ldap.example.com
    base dc=example,dc=com
    binddn cn=OpenLDAP Client,ou=users,dc=example,dc=com
    bindpw password
    tls_reqcert never
    nss_initgroups_ignoreusers ALLLOCAL
    bind_timelimit 3
    timelimit 3
    
    The last line nss_initgroups_ignoreusers ALLLOCAL prevents group membership lookups through LDAP for all local users.
    The remaining settings for PAM, sudoers and access.conf are essentially the same as the old nss-ldap setup. Just make sure to restart the LDAP nameservice daemon, nslcd, after making changes to /etc/nslcd.conf:
    service nslcd restart
    
    If nscd cache daemon is also enabled and you make some changes to the user from the LDAP, you may want to clear the cache:
    nscd --invalidate=passwd
    nscd --invalidate=group
    
    The nslcd daemon also has the advantage that it can be easily stopped in order to temporarily disable the LDAP lookup. This makes the management of LDAP access more easy.
    Finally, here is the setup script:
  • #!/bin/bash
    # vim: softtabstop=4 shiftwidth=4 expandtab fenc=utf-8 spell spelllang=en cc=120
    
    set -e
    
    # Check Ubuntu release
    [ "$(lsb_release -sc)" = "trusty" ] || {
        echo 'This script should be run on Ubuntu 14.04.' >&2
        exit 1
    }
    
    # LDAP group name of team members to be granted access on this server,
    LDAP_TEAM_NAME=$1
    LDAP_BASE="dc=example,dc=com"
    LDAP_URI="ldaps://ldap.example.com"
    LDAP_BINDDN="cn=OpenLDAP Client,ou=users,dc=example,dc=com"
    LDAP_BINDPW="password"
    
    USAGE="usage: ./$(basename $0) LDAP_TEAM_NAME"
    
    # Check required positional parameters
    [ $# -ne 1 ] && {
        echo "$USAGE" >&2
        exit 1
    }
    # Install required packages
    export DEBIAN_FRONTEND=noninteractive
    apt-get -y install libpam-ldap nscd ldap-utils libnss-ldapd
    apt-get -y install python-pip python-ldap
    pip install ssh-ldap-pubkey
    
    # Configure SSH server
    grep 'AuthorizedKeysCommand' /etc/ssh/sshd_config > /dev/null || {
        cat >> /etc/ssh/sshd_config <<EOF
    AuthorizedKeysCommand /usr/local/bin/ssh-ldap-pubkey-wrapper
    AuthorizedKeysCommandUser nobody
    EOF
    }
    
    # Restart SSH server
    service ssh restart
    
    # Edit /etc/ldap.conf
    # If using nss-ldapd, /etc/ldap.conf will be not used by nslcd. However, it is
    # still read by /usr/local/bin/ssh-ldap-pubkey-wrapper to authorize SSH users
    mv /etc/ldap.conf /etc/ldap.conf.bak
    cat > /etc/ldap.conf <<EOF
    base $LDAP_BASE
    uri $LDAP_URI
    ldap_version 3
    binddn $LDAP_BINDDN
    bindpw $LDAP_BINDPW
    pam_password md5
    nss_initgroups_ignoreusers backup,bin,daemon,games,gnats,irc,landscape,libuuid,list,lp,mail,man,messagebus,news,pollinate,proxy,root,sshd,sync,sys,syslog,uucp,www-data
    bind_timelimit 3
    timelimit 3
    EOF
    
    cat > /etc/nslcd.conf <<EOF
    uid nslcd
    gid nslcd
    uri $LDAP_URI
    base $LDAP_BASE
    binddn $LDAP_BINDDN
    bindpw $LDAP_BINDPW
    tls_reqcert never
    nss_initgroups_ignoreusers ALLLOCAL
    bind_timelimit 3
    timelimit 3
    reconnect_retrytime 3
    EOF
    
    # Edit /etc/ldap/ldap.conf
    cp /etc/ldap/ldap.conf /etc/ldap/ldap.conf.bak
    grep 'TLS_REQCERT' /etc/ldap/ldap.conf > /dev/null || {
        cat >> /etc/ldap/ldap.conf <<EOF
    TLS_REQCERT     never
    EOF
    }
    
    # Configure PAM
    # Add pam_access.so
    grep 'pam_access.so' /etc/pam.d/common-auth  > /dev/null || {
        cat >> /etc/pam.d/common-auth <<EOF
    account required    pam_access.so
    EOF
    }
    
    # Remove use_authtok from /etc/pam.d/common-password
    sed -i -r 's/(.*)(use_authtok)(.*)/\1\3/g' /etc/pam.d/common-password
    
    # Add pam_mkhomedir.so
    grep 'pam_mkhomedir.so' /etc/pam.d/common-session > /dev/null || {
        cat >> /etc/pam.d/common-session <<EOF
    session required    pam_mkhomedir.so skel=/etc/skel umask=0022
    EOF
    }
    
    # Configure NSS
    sed -i -r 's/(^passwd:)(\s+)(.*)/\1\2compat ldap/' /etc/nsswitch.conf
    sed -i -r 's/(^group:)(\s+)(.*)/\1\2compat ldap/' /etc/nsswitch.conf
    sed -i -r 's/(^shadow:)(\s+)(.*)/\1\2compat ldap/' /etc/nsswitch.conf
    
    # Edit /etc/security/access.conf
    grep -- '^- : ALL EXCEPT root' /etc/security/access.conf > /dev/null || {
        cat >> /etc/security/access.conf <<EOF
    + : ($LDAP_TEAM_NAME) : ALL    
    - : ALL EXCEPT root staging-devops (admin) (wheel) : ALL EXCEPT LOCAL
    EOF
    }
    
    # Edit /etc/sudoers
    grep -F -- "%ldap-admin" /etc/sudoers > /dev/null || {
        cat >> /etc/sudoers <<EOF
    %ldap-admin ALL=(ALL) ALL
    EOF
    }
    grep -F -- "%$LDAP_TEAM_NAME" /etc/sudoers > /dev/null || {
        cat >> /etc/sudoers <<EOF
    %$LDAP_TEAM_NAME ALL=(ALL) ALL
    EOF
    }
    
    # Set vim as default editor
    echo 3 | update-alternatives --config editor
    echo
    
    # Restart nscd
    service nscd restart
    
    # Restart nslcd
    service nslcd restart
    ----------------------------------------

    在Linux vps,安装OpenLDAP及管理工具phpldapadmin

    总结:
             先写总结,再写正文,嘿嘿嘿。这还是第一次认真的写个文档,写个总结,哈哈。大概在一个月前,第一次听说这个东西,完全没有概念,刚开始的时候看理论的知识,看了几次之后就没看了,看不懂啊。太抽象了,真的太抽象了。然后就把它晾在一边了,又过了一段时间,想了想,既然知道了这个东西,还是得好好学学,好好了解一下。整个过程是在虚拟机上测试完成,期间遇到了太多太多的坑,一个问题就是好几天。这些只是基础的一些东西,还得好好的看看官方文档,嘿嘿嘿。
             最大的收获就是整个学习过程中的解决问题的办法和思想,理论的知识看不懂,没关系,一定要一定要动手去做,有时候看书,觉得挺有理,但是不去动手做,永远都学不会,当你动手做的过程中就慢慢的理解了这个东西是干嘛的;还有一点就是不要怕难,就算一个东西再难,只要肯花时间,肯动手做,一定学的会;还有思考的方式,当你在一个问题是纠结一天了,几天的时候,不要陷进去了,换个方向想想,另一种解决办法马上就出来了。
    文档信息
    目        的:搭建一套完整的OpenLDAP系统,实现账号的统一管理。
                        1:OpenLDAP服务端的搭建
                        2:PhpLDAPAdmin的搭建
                        3:OpenLDAP的打开日志信息
                        4:OpenLDAP与migrationtools实现导入系统账号的相关信息
                        5:OpenLDAP客户端的配置
                        6:OpenLDAP与SSH
                        7:OpenLDAP限制用户登录系统
                        8:OpenLDAP强制用户一登录系统更改密码
                        9:OpenLDAP与系统账号结合Samba
                       10:OpenLDAP的主从
                       11:OpenLDAP的双主
    作        者:李   乐
    日        期:2017-01-09
    联系方式:836217653@qq.com
    系统环境信息
    操作系统:CentOS release 6.7
    基础的环境准备
    关闭防火墙:/etc/init.d/iptables stop  && chkconfig iptables off
    关闭NetworkManager:/etc/init.d/NetworkManager stop && chkconfig NetworkManager off
    SeLinux设为disabled:getenforce 是否为Disabled,若不是,则修改:
             1:临时的生效  setenforce 0,再getenforce的时候为permissive
             2:修改配置文件,然后重启  vim /etc/sysconfig/selinux 把SELINUX=disabled
    yum源仓库的配置
             1)mkdir /yum
             2)vim /etc/yum.repos.d/ll.repo
                      [local]
                      name = local
                      baseurl = file:///yum
                      gpgcheck = 0
                      enabled = 1
             3)挂载 mount /mnt/hgfs/软件/CentOS-6.7-x86_64-bin-DVD1to2/CentOS-6.7-x86_64-bin-DVD1.iso /yum -o loop
             4)yum clean all 清除缓存
             5)yum makecache 创建缓存
    一:OpenLDAP服务器的搭建
    1)安装OpenLDAP的相关
             yum -y install openldap openldap-servers openldap-clients openldap-devel compat-openldap   其中compat-openldap这个包与主从有很大的关系
    安装完后,可以看到自动创建了ldap用户:
          
    可以通过rpm -qa |grep openldap查看安装了哪些包:
          
    2)OpenLDAP的相关配置文件信息
          /etc/openldap/slapd.conf:OpenLDAP的主配置文件,记录根域信息,管理员名称,密码,日志,权限等
          /etc/openldap/slapd.d/*:这下面是/etc/openldap/slapd.conf配置信息生成的文件,每修改一次配置信息,这里的东西就要重新生成
          /etc/openldap/schema/*:OpenLDAP的schema存放的地方
          /var/lib/ldap/*:OpenLDAP的数据文件
          /usr/share/openldap-servers/slapd.conf.obsolete 模板配置文件
          /usr/share/openldap-servers/DB_CONFIG.example 模板数据库配置文件
          OpenLDAP监听的端口:
          默认监听端口:389(明文数据传输)
          加密监听端口:636(密文数据传输)
    3)初始化OpenLDAP的配置
          cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
          cp /usr/share/openldap-servers/slapd.conf.obsolete /etc/openldap/slapd.conf
    4)修改配置文件
          首先,slappasswd生成密文密码123456,拷贝这个到/etc/openldap/slapd.conf里
          
         这里的rootpw必须顶格写,而且与后面的密码文件用Tab键隔开
         
         修改对应的
         
        
    5)重新生成配置文件信息文件
          先检测/etc/openldap/slapd.conf是否有错误:slaptest -f /etc/openldap/slapd.conf
          
        这里报错是因为在第三步后没有重新生成配置文件,启动slapd。而是直接修改配置文件去了。先启动slapd:/etc/init.d/slapd restart
        
       这里又报错,这是因为没有给/var/lib/ldap授权,授权后chown -R ldap.ldap /var/lib/ldap/,再重启slapd,/etc/init.d/slapd restart,可以看到成功的
        
      接着回到检测/etc/openldap/slapd.conf是否有错误:slaptest -f /etc/openldap/slapd.conf
      
      可以看到没问题,然后重新生成配置文件的配置信息:
      先删除最先的配置文件生成的信息:rm -rf /etc/openldap/slapd.d/*
      重新生成:slaptest -f /etc/openldap/slapd.conf -F /etc/openldap/slapd.d/
      查看是否生成的是自己修改的配置文件信息:cat /etc/openldap/slapd.d/cn\=config/olcDatabase\=\{2\}bdb.ldif
      
     授权:chown -R ldap.ldap /etc/openldap/slapd.d/
     重启:/etc/init.d/slapd restart
     
     到这里为止,OpenLDAP服务端基本上完成了,我们可以通过PhpLDAPAdmin来登录看一下,那先得安装PhpLDAPAdmin
    二:PhpLDAPAdmin的搭建
    1)安装EPEL仓库,镜像里没有PhpLDAPAdmin这个的安装包,所以得安装EPEL仓库
          yum clean all
          yum makecache
    2)安装PhpLDAPAdmin
         yum install -y phpldapadmin
    3)修改phpldapadmin的配置文件,访问控制权限vim /etc/httpd/conf.d/phpldapadmin.conf,允许谁访问
    4)修改配置文件:vim /etc/phpldapadmin/config.php
          $servers->setValue(‘login’,’attr’,’dn’);    这一行的注释去掉
        //$servers->setValue(‘login’,’attr’,’uid’);  这一行注释掉
         
    5)重启httpd服务/etc/init.d/httpd restart
    6)在浏览器输入OpenLDAP服务端的IP        10.0.0.138/ldapadmin
         
    7)登录,输入管理员的DN,也就是配置文件里配置的
        
    8)认证,报错
     
     这是因为在第一步搭建OpenLDAP服务端的时候,并没有把管理员的账号信息导入,编辑root.ldif,然后导入
     dn: dc=lemon,dc=com
     objectclass: dcObject
     objectclass: organization
     o: Yunzhi,Inc.
     dc: lemon
     dn: cn=Captain,dc=lemon,dc=com
     objectclass: organizationalRole
     cn: Captain
     这里得注意每一个属性: 后必须有空格,但是值的后面不能有任何空格
     然后导入:ldapadd -x -D “cn=Captain,dc=lemon,dc=com” -W -f root.ldif
     
     然后再通过浏览器去访问的话:
     
      也可以通过命令行查询:ldapsearch -x -b “cn=Captain,dc=lemon,dc=com”
     
     到这里,PhpLDAPAdmin搭建完了,接下来,咱们得把日志打开,这样的话好排错,嘿嘿嘿
    三:OpenLDAP的打开日志信息
    1:现在配置文件里加上日志行 ,这里的日志级别有很多种,-1的话会记录很多日志信息
         vim /etc/openldap/slapd.conf 加上loglevel -1
       
       这里修改了配置文件,所有得重新生成配置文件的信息
        rm -rf /etc/openldap/slapd.d/*
        slaptest -f /etc/openldap/slapd.conf -F /etc/openldap/slapd.d/
        chown -R ldap.ldap /etc/openldap/slapd.d/
    2:在 vim /etc/rsyslog.conf加上
          local4.*                                                /var/log/slapd/slapd.log
          
         然后重启/etc/init.d/rsyslog restart
    3:创建日志文件目录,授权
          mkdir /var/log/slapd
          chmod 755 /var/log/slapd/
          chown ldap.ldap /var/log/slapd/
    4:重启slapd服务,/etc/init.d/slapd restart
    5:就可以看到日志信息了cat /var/log/slapd/slapd.log
    :OpenLDAP与migrationtools实现导入系统账号的相关信息
    1:安装migrationtools
           yum -y install migrationtools
    2:修改migrationtools的配置文件,在/usr/share/migrationtools/这个目录下有很多migrationtools的文件
          vim /usr/share/migrationtools/migrate_common.ph 修改以下的两个地方
          
     3:生成基础的数据文件,可以自己修改这个生成的base.ldif文件,把不需要的去掉
          /usr/share/migrationtools/migrate_base.pl > base.ldif
         
    4:把base.ldif导入OpenLDAP
          ldapadd -x -D “cn=Captain,dc=lemon,dc=com” -W -f base.ldif
          
          这里会报错,我们可以通过-c参数强制加入
           
    导入之后,通过PhpLdapAdmin可以看到已经导入进来了:
      
     5:把系统的用户生成ldif文件
            cd  /usr/share/migrationtools
           ./migrate_passwd.pl /etc/passwd passwd.ldif
           ./migrate_group.pl /etc/group group.ldif
          
       可以看到生成的文件,然后根据自己需要修改这两个ldif文件:
       passwd.ldif只留一个test1测试用户:
      
     group.ldif留对应的test1:
     
     把用户导入进去:ldapadd -x -D “cn=Captain,dc=lemon,dc=com” -W -f passwd.ldif
     
     把组导进去:ldapadd -x -D “cn=Captain,dc=lemon,dc=com” -W -f group.ldif
     
     然后就可以看到:
     
    在这里就已经完成把系统的账号属性导入了OpenLDAP,然后就通过添加OpenLDAP用户,来进行验证,所以得先做好客户端的设置
    五:OpenLDAP客户端的配置
    1:停掉sssd服务  service sssd stop && chkconfig sssd off
    2:安装nslcd服务  yum install nss-pam-ldapd
    3:修改vim /etc/nslcd.conf这个配置文件
         
    4:修改vim /etc/pam_ldap.conf
         
        
    5: vim /etc/pam.d/system-auth 修改,把sss行的注释掉,改成ldap的
      
    6:vim /etc/nsswitch.conf   修改nsswitch.conf配置文件,修改后,默认登录的用户通过本地配置文件进行查找并匹配。当匹配不到用户信息时,会通过后端配置的LDAP认证服务进行匹配
     
    7:vim /etc/sysconfig/authconfig   确保标记的已打开为yes
         USESHADOW=yes 启用密码验证
         USELDAPAUTH=yes 启用OpenLDAP验证
         USELOCAUTHORIZE=yes 启用本地验证
         USELDAP=yes  启用LDAP认证协议
        
    8:重启nslcd服务
         /etc/init.d/nslcd restart
    9:验证,先通过OpenLDAP增加一个用户,在test1的基础上,复制一个test2的条目
                  
     
    后面的根据自己的修改
     
    可以看到已经成功的添加了test2的用户,这是OpenLDAP添加的,在本地是没有的,用cat /etc/passwd 看是没有test2用户的
    测试:su – test2
    在/etc/pam.d/system-auth配置文件里添加这一行:session     optional      pam_mkhomedir.so skel=/etc/skel/ umask=0022
    重启 /etc/init.d/nslcd restart
    在进行测试:就可以了
    查看系统用户列表:
    服务端查询:ldapsearch -x -b “ou=People,dc=lemon,dc=com” |grep dn
    客户端查询:ldapsearch -H ldap://10.0.0.138 -x -b “ou=People,dc=lemon,dc=com” |grep dn
    查询单个用户:ldapsearch -x -b “uid=test1,ou=People,dc=lemon,dc=com” |grep dn
    客户端的配置到这里ok啦。有账号肯定要能通过ssh登录系统
    六:OpenLDAP与SSH
    1:vim /etc/ssh/sshd_config
    2:vim /etc/pam.d/sshd  用于第一次登陆的账户自动创建家目录
    3:vim /etc/pam.d/password-auth
    4:重启sshd
    七:OpenLDAP限制用户登录系统
    在账号中,不能让每个用户都能登录系统,所以要限制用户登录
    1:vim /etc/pam.d/sshd 在这里加上pam_access.so模块
    2:vim /etc/security/access.conf  这里限制test2用户ssh登录系统
    测试:可以看到就只有test2登录不上
    八:OpenLDAP强制用户一登录系统更改密码
    1:修改配置文件
          在前面打开注释
          moduleload ppolicy.la
          modulepath /usr/lib/openldap
          modulepath /usr/lib64/openldap
    还要在database config前面加上这两段
    access to attrs=userPassword
            by self write
            by anonymous auth
            by dn=”cn=Captain,dc=lemon,dc=com” write
            by * none
    access to *
            by self write
            by dn=”cn=Captain,dc=lemon,dc=com” write
            by * read
    在文件的末尾添加:
    overlay ppolicy
    ppolicy_default cn=Captain,ou=pwpolicies,dc=lemon,dc=com
    2:重新生成配置文件数据库:
    [root@lele openldap]# vim /etc/openldap/slapd.conf
    [root@lele openldap]# rm -rf /etc/openldap/slapd.d/*
    [root@lele openldap]#  slaptest -f /etc/openldap/slapd.conf -F /etc/openldap/slapd.d
    config file testing succeeded
    [root@lele openldap]# chown -R ldap.ldap /etc/openldap/slapd.d/
    [root@lele openldap]# /etc/init.d/slapd restart
    Stopping slapd:                                            [  OK  ]
    Starting slapd:                                            [  OK  ]
    可以通过配置文件的数据信息看到ppolicy模块已经加进来了
    cat /etc/openldap/slapd.d/cn\=config/cn\=module\{0\}.ldif

    3:编辑
    cat 1.ldif
    dn: ou=pwpolicies,dc=lemon,dc=com
    objectClass: organizationalUnit
    ou: pwpolicies
    4:ldapadd -x -D “cn=Captain,dc=lemon,dc=com” -W -f 1.ldif
    添加进去
    可以在PhpLdapAdmin上看到:
    5:添加cn=Captain,ou=pwpolicies,dc=lemon,dc=com这个的一些属性值
    [root@ll ~]# cat 2.ldif
    dn: cn=Captain,ou=pwpolicies,dc=lemon,dc=com
    cn: Captain
    objectClass: pwdPolicy
    objectClass: person
    pwdAllowUserChange: TRUE
    pwdAttribute: userPassword
    pwdExpireWarning: 259200
    pwdFailureCountInterval: 0
    pwdGraceAuthNLimit: 5
    pwdInHistory: 5
    pwdLockout: TRUE
    pwdLockoutDuration: 300
    pwdMaxAge: 2592000
    pwdMaxFailure: 5
    pwdMinAge: 0
    pwdMinLength: 8
    pwdMustChange: TRUE
    pwdSafeModify: TRUE
    sn: dummy value
    把属性值添加进去
    在PhpLdapAdmin可以看到:
     
    6:在vim /etc/pam_ldap.conf中的末尾添加:使得客户端能识别服务端的密码策略
         pam_password md5
         bind_policy soft
         pam_lookup_policy yes
         pam_password clear_remove_old
    7:重启nslcd
         /etc/init.d/nslcd restart
    8:测试
    修改用户的属性,用test3做测试
    [root@ll ~]# cat modify.ldif
    dn: uid=test3,ou=people,dc=lemon,dc=com
    changetype: modify
    replace: pwdReset
    pwdReset: TRUE
    ldapmodify -x -D “cn=Captain,dc=le,dc=com” -W -f modify.ldif  导入
    ldapwhoami -x -D uid=test3,ou=people,dc=lemon,dc=com -W -e ppolicy -v   查看test3用户的策略信息
    这里显示输入test3 的原始密码,然后输入新修改的密码

     当修改完后,就没有必须改变密码的那一句话了

     这里可以啦
    九:OpenLDAP与系统账号结合Samba
           默认的Samba服务器支持本地系统用户(smbpasswd添加后)访问Samba资源,不支持OpenLDAP服务器账号访问Samba共享资源,配置完后,OpenLDAP每新增一个用户,就自动支持Samba,就可以用这个账号直接访问Samba,不需要存在于本地用户,不用smbpasswd用户
    1:安装samba
           yum -y install samba
    2:把Samba.schema文件拷贝到LDAP的schema目录下,把原来的覆盖掉
           cp /usr/share/doc/samba-3.6.23/LDAP/samba.schema /etc/openldap/schema/
    3:修改配置文件vim /etc/openldap/slapd.conf
          在include的地方,加上Samba的schema
          
     3:修改了配置文件,就有重新生成配置文件数据
          rm -rf /etc/openldap/slapd.d/*
          slaptest -f /etc/openldap/slapd.conf -F /etc/openldap/slapd.d/
          config file testing succeeded
          chown -R ldap.ldap /etc/openldap/slapd.d/
          /etc/init.d/slapd restart
    4:修改Samba的配置文件
          添加:
          security = user
            passdb backend = ldapsam:ldap://10.0.0.138
            ldap suffix = “dc=lemon,dc=com”
            ldap group suffix = “cn=group”
            ldap user suffix = “ou=people”
            ldap admin dn = “cn=Captain,dc=lemon,dc=com”
            ldap delete dn = no
            pam password change = yes
            ldap passwd sync = yes
            ldap ssl = no
     
     对应这里的
             
    在最后的时候添加共享的文件:
    [public]
    comment = Public Stuff
    path = /tmp/lile
    public = yes
    writable = yes
    printable = no
    5:创建共享文件夹,并且授权
         mkdir /tmp/lile
         chmod 777 /tmp/lile/
    6:把OpenLDAP的密码传给Samba,smbpasswd -w 123456  这里的密码是OpenLDAP的管理员密码
           
         若不加,会报错:
          
    7:重启smb
          /etc/init.d/smb restart
          /etc/init.d/nmb restart
    8:  Samba开通之后,可以看到这里的开关也打开了
     
     9:测试
    先把系统用户test1用smbpasswd -a test1 加到Samba的用户下,就可以看到:
    test1用户下多了Samba的特性,原来是没有的
    然后基于test1,在PhpLdapAdmin添加test2用户,不用smbpasswd,就只是OpenLDAP用户,复制的时候一定要重新改一下这里的密码,要不然登不进,
     
     然后,就可以用windos去访问了,这里有一个概念就是OpenLDAP添加了的用户,不要再用smbpasswd去添加了,可以直接登录Samba
    十:OpenLDAP的主从
    1:做主从和双主的时候,一定要确认安装了 compat-openldap这个包
    2:在主上的配置文件   10.0.0.138
         备份原来的配置文件:cp /etc/openldap/slapd.conf /etc/openldap/slapd.bak
         先停掉服务 /etc/init.d/slapd stop
         vim /etc/openldap/slapd.conf 修改配置文件
         添加       index entryCSN,entryUUID                eq
         
         这里的注释去掉:
         
         
         在文件的最后添加:
         overlay syncprov                      后端工作再overlay模式
         syncprov-checkpoint 100 10   当满足修改100个条目或者10分钟的条件时主动以推的方式执行
         syncprov-sessionlog 100        会话日志条目的最大数量
         
         然后重新生成配置文件的数据文件:
         rm -rf /etc/openldap/slapd.d/*
         slaptest -f /etc/openldap/slapd.conf -F /etc/openldap/slapd.d/
         chown -R ldap.ldap /etc/openldap/slapd.conf
         chown -R ldap.ldap /etc/openldap/slapd.d
         /etc/init.d/slapd restart
    3:导出主的数据文件 ldapsearch -x -b ‘dc=lemon,dc=com’ > root.ldif,拷贝到从上scp    scp root.ldif 10.0.0.140:~/
    4:把主的配置文件slapd.conf 拷贝到从10.0.0.140上 用scp /etc/openldap/slapd.conf 10.0.0.140:~/
    5:从上从主上拷贝了配置文件,
    去掉
          overlay syncprov
          syncprov-checkpoint 100 10
          syncprov-sessionlog 100
    然后再加上

    syncrepl rid=003
    provider=ldap://10.0.0.138:389/
    type=refreshOnly
    retry=”60 10 600 +”                                             尝试时间
    interval=00:00:00:10                                            设置同步更新时间(日:时:分:秒)
    searchbase=”dc=lemon,dc=com”                    
    scope=sub                                                           匹配根域所有条目
    schemachecking=off                                          同步更新时是否开启schema语法检测
    bindmethod=simple                                            同步验证模式为简单模式(即明文)
    binddn=”cn=Captain,dc=lemon,dc=com”        使用Captain用户读取目录树信息
    attrs=”*,+”                                                             同步所有属性信息
    credentials=123456                                             管理员密码
     重新生成数据配置文件
      rm -rf /etc/openldap/slapd.d/*
      slaptest -f /etc/openldap/slapd.conf -F /etc/openldap/slapd.d/
      chown -R ldap.ldap /etc/openldap/slapd.conf
      chown -R ldap.ldap /etc/openldap/slapd.d
      /etc/init.d/slapd restart
    6:测试
    在主的10.0.0.138上添加一个test7的用户,在从上刷新一下,是同步到的
     十一:OpenLDAP的双主
    在主从的基础上,修改配置,这是主的:
    serverID 2
    overlay syncprov
    syncrepl rid=001       (这里的格式一定要注意,中间这一段要用Tab键Tab一下,如果不的话会报错如下)
      provider=ldap://10.0.0.140
      type=refreshAndPersist
      searchbase=”dc=lemon,dc=com”
      schemachecking=simple
      binddn=”cn=Captain,dc=lemon,dc=com”
      credentials=123456
      retry=”60 +”
    mirrormode on
    这是从的
    serverID 1
    overlay syncprov
    syncrepl rid=001        (这里的格式一定要注意,中间这一段要用Tab键Tab一下)
      provider=ldap://10.0.0.138:389/
      retry=”60 10 600 +”
      searchbase=”dc=lemon,dc=com”
      schemachecking=off
      bindmethod=simple
      binddn=”cn=Captain,dc=lemon,dc=com”
      credentials=123456
    mirrormode on
    测试:在两台机上分别新建一个用户,看是否在对方能刷新到,主从与双主都只是备份的关系,若一台挂了,立即切换到另一台,则需做高可用和负载均衡.
    -------------------

    OpenLDAP Installation and Configuration in Ubuntu 12.10 Server / Debian 6

    OpenLDAP is a free open source Light Weight Directory Access protocol developed by the OpenLDAP project. It is a platform independent protocol, so that it runs on all Linux/Unix like systems, Windows, AIX, Solaris and Android.
    In this tutorial i am gonna to show you how to install and configure OpenLDAP server in Ubuntu 12.10 server. Though it is tested on Ubuntu 12.10, it may work on Debian too. In this how-to my testbox details are given below.
    Operating System : Ubuntu 12.10 Server
    Hostname         : server.unixmen.com
    IP Address       : 192.168.1.200
    Replace the above values with your own scenario.

    Install OpenLDAP in Ubuntu 12.10 server

    unixmen@server:~$ sudo apt-get install slapd ldap-utils
    During the installtion it will ask the password for LDAP admin account. Enter your admin password here.
    unixmen@server: ~_001
    Re-enter the password.
    unixmen@server: ~_002

    Configure OpenLDAP

    Open the “/etc/ldap/ldap.conf” file and find and edit the lines as shown below with your domain name and IP Address.
    unixmen@server:~$ sudo vi /etc/ldap/ldap.conf
    #
    # LDAP Defaults
    #
    # See ldap.conf(5) for details
    # This file should be world readable but not world writable.
    BASE    dc=unixmen,dc=com
    URI     ldap://192.168.1.200
    #SIZELIMIT      12
    #TIMELIMIT      15
    #DEREF          never
    # TLS certificates (needed for GnuTLS)
    TLS_CACERT      /etc/ssl/certs/ca-certificates.crt
    Run the Configuration assistant.
    unixmen@server:~$ sudo dpkg-reconfigure slapd
    The following screen should appear. Select “No” and press Enter.
    unixmen@server: ~_003
    Enter the DNS domain name.
    unixmen@server: ~_001
    Enter the Organization name(i.e your company name).
    unixmen@server: ~_002
    Enter the LDAP admin password which you created in the earlier step.
    unixmen@server: ~_006
    Re-enter the password.
    unixmen@server: ~_007
    Select the backend database.
    unixmen@server: ~_008
    Select Yes to delete the database automatically when we are planning to remove LDAP server.
    unixmen@server: ~_009.
    Select Yes to move old database.
    unixmen@server: ~_010
    Select No and Press Enter.
    unixmen@server: ~_011
    LDAP server is up and running now.

    Test LDAP server

    Enter the following command “ldapsearch -x”, then you will have the following result.
    unixmen@server:~$ ldapsearch -x
    # extended LDIF
    #
    # LDAPv3
    # base <dc=unixmen,dc=com> (default) with scope subtree
    # filter: (objectclass=*)
    # requesting: ALL
    #
    
    # unixmen.com
    dn: dc=unixmen,dc=com
    objectClass: top
    objectClass: dcObject
    objectClass: organization
    o: unixmen
    dc: unixmen
    
    # admin, unixmen.com
    dn: cn=admin,dc=unixmen,dc=com
    objectClass: simpleSecurityObject
    objectClass: organizationalRole
    cn: admin
    description: LDAP administrator
    
    # search result
    search: 2
    result: 0 Success
    
    # numResponses: 3
    # numEntries: 2

    LDAP Server Administration

    Administration of LDAP server in command mode is quite difficult, so that here i have used a easier GUI administration tool called “phpldapadmin”.

    Install phpldapadmin

    unixmen@server:~$ sudo apt-get install phpldapadmin
    Create a symbolic link for phpldapadmin directory.
    unixmen@server:~$ sudo ln -s /usr/share/phpldapadmin/ /var/www/phpldapadmin
    Now open the “/etc/phpldapadmin/config.php” file and replace the domain names with your own values. Goto “Define LDAP Servers” section in the config file and edit the following lines as shown below.
    unixmen@server:~$ sudo vi /etc/phpldapadmin/config.php 
    $servers = new Datastore();
    $servers->newServer('ldap_pla');
    $servers->setValue('server','name','Unixmen LDAP Server');
    $servers->setValue('server','host','192.168.1.200');
    $servers->setValue('server','base',array('dc=unixmen,dc=com'));
    $servers->setValue('login','bind_id','cn=admin,dc=unixmen,dc=com');
    Restart the apache service.
    unixmen@server:~$ sudo /etc/init.d/apache2 restart
    Make sure that you have opened apache server port “80” and LDAP default port “389” in your firewall/router configuration.
    unixmen@server:~$ sudo ufw allow 80
    Rules updated
    Rules updated (v6)
    unixmen@server:~$ sudo ufw allow 389
    Rules updated
    Rules updated (v6)
    Now point your web browser with “http://192.168.1.200/phpldapadmin”. The following screen should appear.
    phpLDAPadmin (1.2.2) - - Mozilla Firefox_012
    Click “login” on the left pane and make sure the domain details are correct and enter ldap admin password which you have created in the previous steps and press “Authenticate”.
    phpLDAPadmin (1.2.2) - - Mozilla Firefox_013
    Now the main console screen of phpldapadmin will open. You can see the LDAP domain “unixmen.com” will be found there. Here you can add objects such as Organizational Unit, Users and groups etc.
    phpLDAPadmin (1.2.2) - - Mozilla Firefox_011

    Sample Configuration

    Lets create some sample objects using phpldapadmin interface and check them whether they are presented in the LDAP server configuration.
    Click on the “+” sign near the line “dc=unixmen” and click “Create new entry here” link.
    Selection_012
    Select “Generic-Organizational Unit” and enter the name of the Organizational unit(Ex.sales) and Click “Create Object”.
    phpLDAPadmin (1.2.2) - - Mozilla Firefox_014
    Click “Commit”.
    phpLDAPadmin (1.2.2) - - Mozilla Firefox_015
    Now the newly created OU will be found under the main ldap domain.
    Selection_016
    Click on the sales ou tree on the left pane and click on “Create a child entry”.
    Selection_017
    Select “Generic:Address book entry”. Enter firstname as “senthil”, last name as “kumar” and Common name(cn) as “senthil kumar” and click “Create Object”.
    phpLDAPadmin (1.2.2) - - Mozilla Firefox_018
    Click “Commit”.
    phpLDAPadmin (1.2.2) - - Mozilla Firefox_019
    Now the newly created user “senthil kumar” will be found under “sales” ou.
    Selection_020
    Also you can verify using the command “ldapsearch -x”.
    unixmen@server:~$ ldapsearch -x
    # extended LDIF
    #
    # LDAPv3
    # base <dc=unixmen,dc=com> (default) with scope subtree
    # filter: (objectclass=*)
    # requesting: ALL
    #
    
    # unixmen.com
    dn: dc=unixmen,dc=com
    objectClass: top
    objectClass: dcObject
    objectClass: organization
    o: unixmen
    dc: unixmen
    
    # admin, unixmen.com
    dn: cn=admin,dc=unixmen,dc=com
    objectClass: simpleSecurityObject
    objectClass: organizationalRole
    cn: admin
    description: LDAP administrator
    
    # sales, unixmen.com
    dn: ou=sales,dc=unixmen,dc=com
    objectClass: organizationalUnit
    objectClass: top
    ou: sales
    
    # senthil kumar, sales, unixmen.com
    dn: cn=senthil kumar,ou=sales,dc=unixmen,dc=com
    cn: senthil kumar
    givenName: senthil
    sn: kumar
    objectClass: inetOrgPerson
    objectClass: top
    
    # search result
    search: 2
    result: 0 Success
    
    # numResponses: 5
    # numEntries: 4
     
    from  https://www.unixmen.com/openldap-installation-configuration-ubuntu-12-1013-0413-10-debian-67-2/ 

     --------------

    Setting up OpenLDAP

    Davor Ocelic

    SPINLOCK — advanced GNU/Linux and Unix solutions for commercial and education sectors.
    Last update: Nov 30, 2016. — Verify everything is up to date
    This documentation is free; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
    It is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    Abstract
    The purpose of this article is to give you a straightforward, Debian/Ubuntu-friendly way of installing and configuring OpenLDAP.
    By the end of this guide, you will have a functional LDAP server that will serve as a central authentication system for user logins onto all machines in the network, without the need to manually create users' accounts on individual machines.
    However, for improved authentication security and a true networked solution, it is recommended to use LDAP in combination with Kerberos, with a matching Kerberos setup explained in MIT Kerberos 5 Guide.
    (If you would be interested in that solution, follow the MIT Kerberos 5 Guide first.)
    This article is part of Spinlock Solutions's practical 4-piece introductory series to infrastructure-based Unix networks, containing Debian GNU Guide, MIT Kerberos 5 Guide, OpenLDAP Guide and OpenAFS Guide.

    Introduction

    LDAP is a service that has been traditionally captivating system administrators' and advanced users' interest, but its (seemingly or not) high entry barrier and infrastructure requirements have been preventing many from using it.
    LDAP has already been the topic of numerous publications. Here, we will present only the necessary summary; enough information to establish the context and to achieve practical results.
    You do not need to follow any external links; however, the links have been provided both throughout the article and listed all together at the end, to serve as pointers to more precise technical treatment of individual topics.

    The role of LDAP within a network

    OpenLDAP is an open source implementation of the Lightweight Directory Access Protocol. Directory itself is a tree-structured, read-optimized database. Yellow pages or a phonebook are good associations to have in mind, even though LDAP is much more powerful.
    We will use OpenLDAP to provide a central authentication location for user logins anywhere on the network, with their home directories being automatically created on their first access to individual machines.
    This guide can be followed standalone to make OpenLDAP both perform authentication and serve user meta data. However, using LDAP for authentication as shown here is not secure due to plain text connections made to the LDAP server and passwords traveling over the wire. It is therefore advised to use LDAP in combination with a superior and secure network authentication mechanism Kerberos, which is explained in another article from the series, the MIT Kerberos 5 Guide.
    That said, let's move onto our LDAP setup.
    From a technical perspective, LDAP directory consists of a set of hierarchically organized entries. Each entry belongs to certain Object Classes and contains various key=value pairs called attributes.
    Each entry is uniquely identified by a Distinguished name ("DN"). DN is formed as a list of components, separated by commas, that provide "full path" to the entry, starting from the top of the tree. For example, company Example, Inc. would have the root of the tree in dc=example,dc=com. A person employed by Example, Inc. would then have a corresponding LDAP entry with DN cn=person,ou=People,dc=example,dc=com.
    Which attributes may or must be present in an entry is governed by the entry's objectClasses.
    You might notice that the individual components of the DN, such as cn=person above, are also formed as key=value pairs. Those "keys", cn, ou and dc, stand for Common Name, Organizational Unit and Domain Component. They are a part of every-day LDAP terminology that you will get used to.
    Let's quickly identify LDAP-specific elements in our setup:
    • LDAP is not in any way related to traditional system usernames or other data. However, part of its functionality in our setup will consist in storing information traditionally found in Unix files /etc/passwd and /etc/group, thus making that data network-accessible at a centralized location.
      People's login names will be used in pairing people with the corresponding information in the LDAP tree. For example, username person will map to an LDAP entry uid=person,ou=People,dc=example,dc=com.
    • LDAP can be configured to contain user passwords. Passwords can be used both for authenticating as specific users and gaining access to protected entries, and for verifying whether the user knows the correct password.
      When a user opens a LDAP client and moves to browse the directory, his DN and password are used to establish the identity and access privileges. When LDAP is configured to perform user authentication, his DN and password are only used to perform a connection to the LDAP directory — successful connection ("bind") implies the user knew the correct password.
    You can find the complete OpenLDAP documentation at the OpenLDAP website. For an authoritative OpenLDAP book, see Gerald Carter's LDAP System Administration by O'Reilly.

    Glue layers: integrating LDAP with system software

    NSS

    On all GNU/Linux-based platforms, NSS is available for network data retrieval configuration. NSS is an implementation of the Name Service Switch mechanism.
    NSS will allow for inclusion of LDAP into the "user data" path of all services, regardless of whether they natively support LDAP or not.
    You can find the proper introduction (and complete documentation) on the NSS website. Also take a look at the nsswitch.conf(5) manual page.

    PAM

    Likewise, on all GNU/Linux-based platforms, another piece of the puzzle, Linux-PAM, is available for service-specific authentication configuration. Linux-PAM is an implementation of PAM ("Pluggable Authentication Modules") from Sun Microsystems.
    Network services, instead of having hard-coded authentication interfaces and decision methods, invoke PAM through a standard, pre-defined interface. It is then up to PAM to perform any and all authentication-related work, and report the result back to the application.
    Exactly how PAM reaches the decision is none of the service's business. In traditional set-ups, that is most often done by asking and verifying usernames and passwords. In advanced networks, that could be retina scans or — Kerberos tickets, as explained in another article from the series, MIT Kerberos 5 Guide.
    You can find the proper introduction (and complete documentation) on the Linux-PAM website. Pay special attention to the PAM Configuration File Syntax page. Also take a look at the Linux-PAM(7) and pam(7) manual pages.

    Conventions

    Let's agree on a few conventions before going down to work:
    • Our platform of choice, where we will demonstrate a practical setup, will be Debian GNU. The setup will also work on Ubuntu, and if any notable differences exist they will be noted.
    • If using Debian GNU, install and configure sudo. On Ubuntu sudo will already be installed and configured to work for your regular user account.
      Sudo is a program that will allow you to carry out system administrator tasks from your normal user account. All the examples in this article requiring root privileges use sudo, so you will be able to copy-paste them to your shell.
      To install sudo on Debian GNU only, run:
      su -c 'apt-get install sudo'
      
      If asked for a password, type in the root user's password.
      To configure sudo on Debian GNU only, run the the following, replacing USERNAME with your login name:
      su -c 'echo "USERNAME ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers'
      
    • Packages that we will install during the complete procedure will ask us a series of questions through the so-called debconf interface. To configure debconf to a known state, run:
      sudo dpkg-reconfigure debconf
      
      When asked, answer interface=Dialog and priority=low.
    • Monitoring log files is crucial in detecting problems. The straightforward, catch-all routine to this is opening a terminal and running:
      cd /var/log; sudo tail -F daemon.log sulog user.log auth.log debug kern.log syslog dmesg messages kerberos/{krb5kdc,kadmin,krb5lib}.log
      

      The command will keep printing log messages to the screen as they arrive.
    • Our test system will be called monarch.spinlock.hr and have an IP address of 192.168.7.12. Both the server and the client will be installed on the same machine. However, to differentiate between client and server roles where relevant, the client will be referred to as monarch.spinlock.hr and the server as ldap1.spinlock.hr. The following addition will be made to /etc/hosts to completely support this scheme:
      192.168.7.12 monarch.spinlock.hr monarch krb1.spinlock.hr krb1 ldap1.spinlock.hr ldap1
      

      Caution

      Note that in some installations the system's network hostname is assigned to the localhost address 127.0.0.1. This can and will cause problems for network operations, so make sure that your "localhost" entry in /etc/hosts looks exactly like the following (nothing more, nothing less):
      127.0.0.1  localhost
      

      Finally, test that the network setup is as expected. Pinging the hostnames should report proper FQDNs and IPs as shown:
      ping -c1 localhost
      PING localhost (127.0.0.1) 56(84) bytes of data.
      ....
      
      ping -c1 monarch
      PING monarch.spinlock.hr (192.168.7.12) 56(84) bytes of data.
      ....
      
      ping -c1 ldap1
      PING ldap1.spinlock.hr (192.168.7.12) 56(84) bytes of data.
      ....
      

    OpenLDAP

    Server installation

    OpenLDAP's server component is called slapd, and is basically all that we will need.
    sudo apt-get install slapd ldap-utils
    
    Debconf answers for reference:
    Omit OpenLDAP server configuration? No
    
    DNS domain name: spinlock.hr
    
    Organization name? spinlock.hr
    
    Administrator password: PASSWORD
    
    Confirm password: PASSWORD
    
    Database backend to use: MDB
    
    Do you want the database to be removed when slapd is purged? No
    
    Allow LDAPv2 protocol? No
    
    As soon as the installation is done, the OpenLDAP server (command slapd) will start.

    Initial configuration

    Introduction

    For a general introduction, it is important to know that the server-side configuration, including the ObjectClasses, attributes, syntaxes, matching rules and other details of the LDAP data structure are, at startup, loaded from the configuration files found under the directory /etc/ldap/slapd.d/.
    These configuration files are kept in the LDIF format as it is expected that the configuration would be modified using the standard LDAP data modification utilities in runtime, and that the slapd server would then save the new values as LDIF files to preserve configuration data across restarts.
    However, when manual interventions to the files are required, the LDIF-formatted files still allow for reasonably convenient text-based editing.
    This configuration style, modifiable in runtime, is known under a couple different names, notably olc (On-Line Configuration), cn=config and slapd.d.
    Previously, OpenLDAP used a standard, text-based configuration file found in /etc/ldap/slapd.conf. However, while still supported, that approach is no longer recommended as it requires server restarts to apply configuration changes, and cn=config is nowadays the default method.

    Note

    Since the /etc/ldap/slapd.conf configuration has traditionally been documented in this Guide, it will be kept listed in addition to slapd.d for reference, but it should be considered obsolete.
    If you happen to have a /etc/ldap/slapd.conf file in your configuration and no /etc/ldap/slapd.d/ directory, convert to slapd.d by running:
    sudo slaptest -f /etc/ldap/slapd.conf -F /etc/ldap/slapd.d
    
    And then make sure that your slapd has been started with -F /etc/ldap/slapd.d instead of with -f /etc/ldap/slapd.conf by running the following two checks:
    grep -e -F /etc/init.d/slapd
    ps aux | grep slapd
    
    (Both should list "-F" instead of "-f".)

    cn=config configuration

    The cn=config is a special LDAP database that keeps the OpenLDAP server configuration, and is viewable and modifiable in runtime.
    Changes made to it are instantly applied to the running server and are also saved under /etc/ldap/slapd.d/, to preserve the configuration across server restarts.
    So here is what we want to do:
    To make the necessary configuration changes, we want to take advantage of the existing, default configuration in cn=config which is allowing local root user to connect to the slapd socket in /var/run/slapd/ldapi and modify the cn=config database.
    Using this approach, we first want verify that all the necessary LDAP schema definitions (core, cosine, nis and inetorgperson) have been loaded.
    Any errors about duplicate entries in this step are fine, and the relevant part that is instructing our client to authenticate as local user and to connect to the slapd Unix socket is "-Y EXTERNAL -H ldapi:///":
    sudo ldapadd -c -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/core.ldif
    sudo ldapadd -c -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/cosine.ldif
    sudo ldapadd -c -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/nis.ldif
    sudo ldapadd -c -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/inetorgperson.ldif
    
    (Another way to make sure these schemas are loaded is to run ls -al /etc/ldap/slapd.d/cn=config/cn=schema/.)
    Then we want to replace the default "olcLogLevel: none" with "olcLogLevel: 256":
    echo "dn: cn=config
    changetype: modify
    replace: olcLogLevel
    olcLogLevel: 256" > /var/tmp/loglevel.ldif
    
    sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f /var/tmp/loglevel.ldif
    
    SASL/EXTERNAL authentication started
    SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
    SASL SSF: 0
    modifying entry "cn=config"
    
    Then we want to add an "eq" (equality) search index for the attribute "uid":
    echo "
    dn: olcDatabase={1}mdb,cn=config
    changetype: modify
    add: olcDbIndex
    olcDbIndex: uid eq
    " > /var/tmp/uid_eq.ldif
    
    sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f /var/tmp/uid_eq.ldif
    
    SASL/EXTERNAL authentication started
    SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
    SASL SSF: 0
    modifying entry "olcDatabase={1}mdb,cn=config"
    
    And finally, we want to allow the LDAP administrator account to see and modify the cn=config configuration database in the same way that write access would be granted on the actual data tree dc=spinlock, dc=hr.
    This will effectively allow accessing and modifying slapd configuration from any location as long as the user knows the correct administrator DN and password. It will come very handy in the learning phase, for viewing and modifying the configuration using a graphical LDAP client:
    echo "dn: olcDatabase={0}config,cn=config
    changetype: modify
    add: olcAccess
    olcAccess: to * by dn="cn=admin,dc=spinlock,dc=hr" write" > /var/tmp/access.ldif
    
    sudo ldapmodify -c -Y EXTERNAL -H ldapi:/// -f /var/tmp/access.ldif
    
    SASL/EXTERNAL authentication started
    SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
    SASL SSF: 0
    modifying entry "olcDatabase={0}config,cn=config"
    

    slapd.conf configuration (obsolete)

    For reference, here is the equivalent configuration as the above, in the old slapd.conf style:

    Note

    This whole section should be ignored unless you are purposely using /etc/ldap/slapd.conf or are attempting to compare it to slapd.d.
    Make sure all the schema files are enabled:
    include         /etc/ldap/schema/core.schema
    include         /etc/ldap/schema/cosine.schema
    include         /etc/ldap/schema/nis.schema
    include         /etc/ldap/schema/inetorgperson.schema
    
    Change the verbosity level from 0 or "none" to 256:
    loglevel 256
    
    Search for line "index objectClass eq" and add another search index. In particular combinations, it may be possible to receive no results when the searched entries are not indexed, so this step is important:
    index           objectClass eq
    index           uid         eq
    
    To make the new index option apply, run the following commands:
    sudo invoke-rc.d slapd stop
    sudo slapindex
    sudo chown -R openldap:openldap /var/lib/ldap
    sudo invoke-rc.d slapd start
    

    Client-side configuration

    Our OpenLDAP server is already running, so let's configure /etc/ldap/ldap.conf, a common configuration file for all LDAP clients. This will allow us to run ldapsearch and other commands without having to specify all the basic parameters by hand each time.
    Enable the following two lines in /etc/ldap/ldap.conf, creating the file if necessary:
    BASE  dc=spinlock, dc=hr
    URI ldap://192.168.7.12/
    

    Initial test

    It's already the time to test the installation. Our OpenLDAP server does not contain much information, but a basic read operation can be performed normally.
    In LDAP terms, read operation is called a "search". To perform a search using generic command-line utilities, we have ldapsearch and slapcat available.
    Ldapsearch (and other LDAP utilities prefixed "ldap") perform operations "online", using the LDAP protocol.
    Slapcat (and other OpenLDAP utilities prefixed "slap") perform operations "offline", directly by opening files on the local filesystem. For this reason, they can only be ran locally on the OpenLDAP server and they require administrator privileges. When they involve writing to the database, the OpenLDAP server usually needs to be stopped first.
    In the output of the two search commands, you will notice two LDAP entries, one representing the top level element in the tree, and another representing the LDAP administrator's entry. In the slapcat output, notice the extra attributes not printed with ldapsearch. One of those is userPassword, which is not shown to us when we are anonymously accessing the directory using ldapsearch, due to the default access restrictions in place.
    ldapsearch -x
    
    # extended LDIF
    #
    # LDAPv3
    # base <dc=spinlock, dc=hr> (default) with scope subtree
    # filter: (objectclass=*)
    # requesting: ALL
    #
    
    # spinlock.hr
    dn: dc=spinlock,dc=hr
    objectClass: top
    objectClass: dcObject
    objectClass: organization
    o: spinlock.hr
    dc: spinlock
    
    # admin, spinlock.hr
    dn: cn=admin,dc=spinlock,dc=hr
    objectClass: simpleSecurityObject
    objectClass: organizationalRole
    cn: admin
    description: LDAP administrator
    
    # search result
    search: 2
    result: 0 Success
    
    # numResponses: 3
    # numEntries: 2
    

    sudo slapcat
    
    dn: dc=spinlock,dc=hr
    objectClass: top
    objectClass: dcObject
    objectClass: organization
    o: spinlock.hr
    dc: spinlock
    structuralObjectClass: organization
    entryUUID: 350a2db6-87d3-102c-8c1c-1ffeac40db98
    creatorsName:
    modifiersName:
    createTimestamp: 20080316183324Z
    modifyTimestamp: 20080316183324Z
    entryCSN: 20080316183324.797498Z#000000#000#000000
    
    dn: cn=admin,dc=spinlock,dc=hr
    objectClass: simpleSecurityObject
    objectClass: organizationalRole
    cn: admin
    description: LDAP administrator
    userPassword:: e2NyeXB0fVdSZDJjRFdRODluNHM=
    structuralObjectClass: organizationalRole
    entryUUID: 350b330a-87d3-102c-8c1d-1ffeac40db98
    creatorsName:
    modifiersName:
    createTimestamp: 20080316183324Z
    modifyTimestamp: 20080316183324Z
    entryCSN: 20080316183324.804398Z#000000#000#000000
    

    Creating basic tree structure

    As explained, the LDAP database is structured as a tree. The top level element in the tree for your organization is often its domain name. In case of a domain spinlock.hr, the toplevel tree element would be dc=spinlock,dc=hr.
    On the next level below, an organization is often divided into "organizational units", such as people, groups, hosts, services, networks, protocols, etc.
    Accordingly, to support people's Unix "meta data" in our LDAP directory, we will be interested in creating two of the mentioned organizational units, People and Group. The two will roughly correspond to the Unix /etc/passwd and /etc/group files.
    Ldap data is interchanged in a textual format called LDIF. Command-line LDAP utilities receive and produce data in this format. Note that the LDIF stream can also contain commands, such as for adding, modifying or removing LDAP entries.
    Knowing this, we'll put together a simple LDIF file, /var/tmp/ou.ldif, that will instruct the server to add the two organizational units. Pay attention to the empty line separating the entries:
    dn: ou=People,dc=spinlock,dc=hr
    ou: People
    objectClass: organizationalUnit
    
    dn: ou=Group,dc=spinlock,dc=hr
    ou: Group
    objectClass: organizationalUnit
    
    To load the LDIF file into the server, let's show an example using the offline tool, slapadd:
    sudo invoke-rc.d slapd stop
    sudo slapadd -c -v -l /var/tmp/ou.ldif
    
    added: "ou=People,dc=spinlock,dc=hr" (00000003)
    added: "ou=Group,dc=spinlock,dc=hr" (00000004)
    _#################### 100.00% eta   none elapsed            none fast!         
    Closing DB...
    
    sudo invoke-rc.d slapd start
    
    Let's use ldapsearch to verify the entries have been created.
    ldapsearch -x ou=people
    
    # extended LDIF
    #
    # LDAPv3
    # base <dc=spinlock, dc=hr> (default) with scope subtree
    # filter: ou=people
    # requesting: ALL
    #
    
    # People, spinlock.hr
    dn: ou=People,dc=spinlock,dc=hr
    ou: People
    objectClass: organizationalUnit
    
    # search result
    search: 2
    result: 0 Success
    
    # numResponses: 2
    # numEntries: 1
    

    Creating user accounts

    In the same manner we've created the two organizational units, let's create our first group and a person belonging to it. Again, we approach the problem by constructing and loading an LDIF file, /var/tmp/user1.ldif, paying attention to the empty line separating the entries:
    dn: cn=mirko,ou=group,dc=spinlock,dc=hr
    cn: mirko
    gidNumber: 20000
    objectClass: top
    objectClass: posixGroup
    
    dn: uid=mirko,ou=people,dc=spinlock,dc=hr
    uid: mirko
    uidNumber: 20000
    gidNumber: 20000
    cn: Mirko
    sn: Mirko
    objectClass: top
    objectClass: person
    objectClass: posixAccount
    objectClass: shadowAccount
    loginShell: /bin/bash
    homeDirectory: /home/mirko
    
    To load the LDIF file into the server, let's show an example using the online tool, ldapadd. Since, as said previously, ldapadd uses the LDAP protocol, we'll have to bind to the server as system administrator and type in the correct admin password (defined during slapd installation):
    ldapadd -c -x -D cn=admin,dc=spinlock,dc=hr -W -f /var/tmp/user1.ldif
    
    Enter LDAP Password: PASSWORD
    
    adding new entry "cn=mirko,ou=group,dc=spinlock,dc=hr"
    
    adding new entry "uid=mirko,ou=people,dc=spinlock,dc=hr"
    
    
    Now to define the new user's password, let's run an online tool ldappasswd. (This step is not needed if you plan to use LDAP in combination with Kerberos as explained in MIT Kerberos 5 Guide.)
    ldappasswd -x -D cn=admin,dc=spinlock,dc=hr -W -S uid=mirko,ou=people,dc=spinlock,dc=hr
    
    New password: NEW USER PASSWORD
    
    Re-enter new password: NEW USER PASSWORD
    
    Enter LDAP Password:  ADMIN PASSWORD
    
    Result: Success (0)
    

    Note

    You might notice that all entries always have to be "fully qualified" and that you cannot omit the suffix (dc=spinlock,dc=hr) or other components of the DN. This often leads to command line examples that are long and cryptic, and look just like boring, unnecessary work. If you perceive that as a problem, you'll solve it by either getting accustomed to it to the point of not noticing it any more, or you will later switch to using graphical LDAP clients that fill in most of that information for you.
    Now let's use ldapsearch to verify the user entry has been created. Note that the password field, userPassword, will not be shown even if we created it, due to the configured access restrictions that apply to anonymous users.
    ldapsearch -x uid=mirko
    
    # extended LDIF
    #
    # LDAPv3
    # base <dc=spinlock, dc=hr> (default) with scope subtree
    # filter: uid=mirko
    # requesting: ALL
    #
    
    # mirko, people, spinlock.hr
    dn: uid=mirko,ou=people,dc=spinlock,dc=hr
    uid: mirko
    uidNumber: 20000
    gidNumber: 20000
    cn: Mirko
    sn: Mirko
    objectClass: top
    objectClass: person
    objectClass: posixAccount
    loginShell: /bin/bash
    homeDirectory: /home/mirko
    
    # search result
    search: 2
    result: 0 Success
    
    # numResponses: 2
    # numEntries: 1
    
    Congratulations! You now have a working LDAP setup.

    NSS configuration

    Now that we have a new user created in LDAP, we should allow the system to see it. For example, let's test for existence of users root and mirko. The administrator will be present, while mirko will not:
    id root
    uid=0(root) gid=0(root) groups=0(root)
    
    id mirko
    id: mirko: No such user
    
    To enable the system see and use LDAP accounts, we need to install libnss-ldap, libpam-ldap and nscd.
    sudo apt-get install libnss-ldap libpam-ldap nscd
    
    All debconf answers for reference:
    LDAP server URI: ldap://192.168.7.12/ (Note the "ldap://", not "ldapi://")
    
    Distinguished name of the search base: dc=spinlock,dc=hr
    
    LDAP version to use: 3
    
    Does the LDAP database require login? No
    
    Special LDAP privileges for root? No
    
    Make the configuration file readable/writable by its owner only? No
    
    Allow LDAP admin account to behave like local root? Yes
    
    Make local root Database admin. No
    
    Does the LDAP database require login? No
    
    LDAP administrative account: cn=admin,dc=spinlock,dc=hr
    
    LDAP administrative password: PASSWORD
    
    Local crypt to use when changing passwords. md5
    
    PAM profiles to enable: --->
      If not using Kerberos, select 'Unix authentication' and 'LDAP Authentication'
      If using Kerberos, select 'Unix authentication' and 'Kerberos authentication'
    
    Debconf answers will be saved and reflected in the configuration file /etc/libnss-ldap.conf. To confirm the configuration, locate and verify the following two lines in /etc/libnss-ldap.conf:
    base dc=spinlock,dc=hr
    uri ldap://192.168.7.12/
    
    Finally, to activate the LDAP NSS module, edit /etc/nsswitch.conf by replacing the two lines mentioning passwd and group with the following:
    passwd:         files ldap
    group:          files ldap
    
    Nscd (the Name Service Caching Daemon) is used to cache metadata locally, instead of querying the LDAP server each time. It is a very efficient service in the long run, but we will stop it for for the moment, during testing, to always retrieve the data directly from the LDAP server:
    sudo invoke-rc.d nscd stop
    
    Now we can verify that LDAP users have become visible:
    id mirko
    
    uid=20000(mirko) gid=20000(mirko) groups=20000(mirko)
    

    PAM configuration

    The final step in this article pertains to integrating LDAP into the system authentication procedure.
    We will need to verify the configuration of the package libpam-ldap that has been installed in the previous step.
    The default PAM configuration will require the user to be present either in the local password file or in LDAP, and to know the correct password, for the authentication process to continue.
    First, the debconf answers related to libpam-ldap have already been saved and reflected in the configuration file /etc/pam_ldap.conf.
    To confirm the configuration, locate and verify the following two lines in /etc/pam_ldap.conf:
    base dc=spinlock,dc=hr
    uri ldap://192.168.7.12/
    
    Second, the answer to the debconf question "PAM profiles to enable" has aso been reflected in the four PAM-related configuration files: /etc/pam.d/common-account, /etc/pam.d/common-auth, /etc/pam.d/common-password and /etc/pam.d/common-session.
    Here's how the active parts of these config files should look like, for reference:

    /etc/pam.d/common-account

    # Disable if using Kerberos:
    account [success=2 new_authtok_reqd=done default=ignore]        pam_unix.so
    account [success=1 default=ignore]      pam_ldap.so
    
    # Enable if using Kerberos:
    #account [success=1 new_authtok_reqd=done default=ignore]        pam_unix.so
    
    account requisite                       pam_deny.so
    
    account required                        pam_permit.so
    
    # Enable if using Kerberos:
    #account required                        pam_krb5.so minimum_uid=1000
    

    /etc/pam.d/common-auth

    # Disable if using Kerberos:
    auth    [success=2 default=ignore]      pam_unix.so nullok_secure
    auth    [success=1 default=ignore]      pam_ldap.so use_first_pass
    
    # Enable if using Kerberos:
    #auth    [success=2 default=ignore]      pam_krb5.so minimum_uid=1000
    #auth    [success=1 default=ignore]      pam_unix.so nullok_secure try_first_pass
    
    auth    requisite                       pam_deny.so
    
    auth    required                        pam_permit.so
    

    /etc/pam.d/common-password

    # Disable if using Kerberos:
    password        [success=2 default=ignore]      pam_unix.so obscure sha512
    password        [success=1 user_unknown=ignore default=die]     pam_ldap.so use_authtok try_first_pass
    
    # Enable if using Kerberos:
    #password        [success=2 default=ignore]      pam_krb5.so minimum_uid=1000
    #password        [success=1 default=ignore]      pam_unix.so obscure use_authtok try_first_pass sha512
    
    password        requisite                       pam_deny.so
    
    password        required                        pam_permit.so
    

    /etc/pam.d/common-session

    session [default=1]                     pam_permit.so
    
    session requisite                       pam_deny.so
    
    session required                        pam_permit.so
    
    # Enable if using Kerberos:
    #session  optional  pam_krb5.so minimum_uid=1000
    
    session required        pam_unix.so 
    
    # Disable if using Kerberos:
    session optional                        pam_ldap.so 
    
    It is advisable not to be making basic changes in these files manually, as modifications require detailed knowledge of the PAM config file syntax.
    Changes can be made by running the following line that will reconfigure the package and re-generate the configuration files:
    sudo dpkg-reconfigure libpam-ldap 
    
    For manual modifications, you will want to look at PAM Configuration File Syntax and pay special attention to seemingly insignificant variations — with PAM, they often make a whole world of difference.
    Finally, you will want to start nscd that was stopped during one of the previous steps:
    sudo invoke-rc.d nscd start
    
    Note that authentication through LDAP, as shown here, is not secure, due to connections to the LDAP server being made in plain text and passwords traveling over the wire.
    Instead of encrypting the connection to the LDAP server, one could install Kerberos as explained in MIT Kerberos 5 Guide. If Kerberos is set up after LDAP, run dpkg-reconfigure libpam-ldap afterwards to choose "Unix authentication" and "Kerberos authentication" instead of "LDAP Authentication", and verify the resulting PAM configuration files as per the actual /etc/pam.d/ configs provided above.

    Logging in into the system

    When users authenticate successfully, and they log in, they will be placed in their home directory. In a central network authentication scheme, where the user accounts are created centrally instead of on the individual machines, their home directories may not exist on particular systems. This problem can be solved by using the pam_mkhomedir PAM module, which can create the users' home directories on the fly, if they are found missing during login.
    Add the following line to the bottom of /etc/pam.d/common-session:
    session required        pam_mkhomedir.so skel=/etc/skel/ umask=0022
    
    Implicitly, this means that the users' home directories will be created separately on all of the individual machines they log in to. This may present a problem as people will have different files on different machines. It won't be completely unacceptable in itself if Kerberos is used as the Kerberized network will allow secure and passwordless copying of files between the machines, but it will still be far from a perfect solution. To solve that problem with an advanced, secure, heavy-duty distributed network filesystem, you could read the next article in the series, the OpenAFS Guide.
    In any case, having everything adjusted as shown using pam_mkhomedir, login to the system should succeed as user mirko:
    Login: mirko
    Password: PASSWORD
    
    Debian GNU/Linux tty5
    
    Creating directory '/home/mirko'.
    
    Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
    permitted by applicable law.
    mirko@host:~$
    
    

    Conclusion

    At this point, you have a functional LDAP installation.
    You can rely on LDAP for central network authentication and sharing of user metadata (user IDs, group IDs, real names, group memberships, etc.).
    With a good foundation we've built, for further information on LDAP, please refer to other available resources:
    Finally, as said above, the described authentication through LDAP is not done in a network-secure manner, due to plain text connections and passwords traveling over the wire. To solve that problem, using Kerberos for network authentication instead of LDAP is recommended, as explained in the previous article in the series, the MIT Kerberos 5 Guide.
    Also, as said above, the users' home directories will be created separately on all of the hosts the users would log in to. To solve that problem and have a shared home directory on all of the systems, using a distributed filesystem AFS is recommended, as explained in the next article in the series, the OpenAFS Guide.

    from http://techpubs.spinlocksolutions.com/dklar/ldap.html

-------------------

使用OpenLDAP管理系统权限

Configuring Your System to Authenticate Using OpenLDAP

This section provides a brief overview of how to configure your Red Hat Linux system to authenticate using OpenLDAP. Unless you’re an OpenLDAP expert, you will probably need more documentation than is provided here. Please refer to the references provided in the section called LDAP Resources on the Web for more information.

Install the Necessary LDAP Packages

First, you’ll need to make sure that the appropriate packages are installed on both the LDAP server and the LDAP client machines. The LDAP server needs the openldap package.

The LDAP client machines need the following packages installed: openldap,auth_ldapnss_ldap and pam_ldap.

Edit Configuration Files

Edit /etc/openldap/slapd.conf

The slapd.conf file, located in /etc/openldap, contains the configuration information needed by your slapd LDAP server. You’ll need to edit this file to make it specific to your domain and your server.

The suffix line names the domain for which the LDAP server will provide information. The suffix line should be changed from:

suffix 		"dc=your-domain, dc=com"

so that it reflects your domain name. For example:

suffix		"dc=acmewidgets, dc=com"

or

suffix 		"dc=acmeuniversity, dc=org"

The rootdn entry is the DN for a user who is unrestricted by the access control or administrative limit parameters set for operations on the LDAP directory. The rootdn user can be thought of as the root user for the LDAP directory. The rootdn line needs to be changed

from:

rootdn		"cn=root, dc=your-domain, dc=com"

to something like:

rootdn		"cn=root, dc=redhat, dc=com"

or

rootdn		"cn=ldapmanager, dc=my_organization, dc=org"

Change the rootpw line from:

rootpw 		secret

to something like

rootpw		{crypt}s4L9sOIJo4kBM

In the above example, you’re using an encrypted root password, which is a much better idea than leaving a plain text root password in the slapd.conf file. To make this crypt string, you should either copy it out of a passwd file, or use Perl:

perl -e "print crypt('passwd','a_salt_string');"

In the previous Perl line, salt_string is a two character salt, and passwd is the plain text version of the password.

You could also copy a passwd entry out of /etc/passwd, but this won’t work if the passwd entry is an MD5 password (the default in Red Hat Linux 6.2).

Edit ldap.conf

Edit the ldap.conf files in /etc and in /etc/openldap on the LDAP server and clients.

Edit /etc/ldap.conf, the configuration file for nss_ldap and pam_ldap, to reflect your organization and search base. The file /etc/openldap/ldap.conf is the configuration file for the command line tools like ldapsearch,ldapadd, etc., and it will also need to be edited for your LDAP setup. Client machines will need to have both of these files modified for your system.

Edit /etc/nsswitch.conf

To use nss_ldap, you’ll need to add ldap to the appropriate fields in /etc/nsswitch.conf. (Be very careful when editing this file; be sure that you know what you’re doing.) For

example:

passwd: files ldap
shadow: files ldap
group: files ldap

Copy the PAM Configuration Files

To use pam_ldap, you’ll need to copy the PAM configuration files from /usr/doc/nss_ldap&lt;version&gt;/pam.d/ to your /etc/pam.d/ directory. These are a set of PAM configuration files that allow all of the standard PAM-enabled applications to use LDAP for authentication. (PAM is beyond the scope of this LDAP overview, so if you need help, consult the section called User Authentication with PAM in Chapter 2 and/or PAM man pages.)

Migrate Your Old Authentication Information to LDAP Format

The /usr/share/openldap/migration directory contains a set of shell and Perl scripts for migrating your old authentication information into LDAP format. (Yes, you’ll need to have Perl on your system to use these scripts.)

First, you’ll need to modify the migrate_common.ph file so that it reflects your domain. The default DNS domain should be changed from:

$DEFAULT_MAIL_DOMAIN = "padl.com";

to something like:

$DEFAULT_MAIL_DOMAIN = "your_company.com";

The default base should also be changed, from:

$DEFAULT_BASE = "dc=padl,dc=com";

to something like:

$DEFAULT_BASE = "dc=your_company,dc=com";

Next, you’ll need to decide which script to use. The following table should tell you:

Table 8-1. LDAP Migration Scripts

Existing name serviceIs LDAP running?Use this script:
/etc flat filesyesmigrate_all_online.sh
/etc flat filesnomigrate_all_offline.sh
NetInfoyesmigrate_all_netinfo_online.sh
NetInfonomigrate_all_netinfo_offline.sh
NIS (YP)yesmigrate_all_nis_online.sh
NIS (YP)Nomigrate_all_nis_offline.sh

Run the appropriate script based on your existing name service.

The README and the migration-tools.txt files in /usr/share/openldap/migratio provide more details.

------------------

LDAP服务器的概念和原理

1. 目录服务


目录是一个为查询、浏览和搜索而优化的专业分布式数据库,它呈树状结构组织数据,就好象Linux/Unix系统中的文件目录一样。目录数据库和关系数据库不同,它有优异的读性能,但写性能差,并且没有事务处理、回滚等复杂功能,不适于存储修改频繁的数据。所以目录天生是用来查询的,就好象它的名字一样。 目录服务是由目录数据库和一套访问协议组成的系统。类似以下的信息适合储存在目录中:

  • 企业员工信息,如姓名、电话、邮箱等;
  • 公用证书和安全密钥;
  • 公司的物理设备信息,如服务器,它的IP地址、存放位置、厂商、购买时间等;

LDAP是轻量目录访问协议(Lightweight Directory Access Protocol)的缩写,LDAP是从X.500目录访问协议的基础上发展过来的,目前的版本是v3.0。与LDAP一样提供类似的目录服务软件还有ApacheDSActive DirectoryRed Hat Directory Service 。

2. LDAP特点


  • LDAP的结构用树来表示,而不是用表格。正因为这样,就不能用SQL语句了
  • LDAP可以很快地得到查询结果,不过在写方面,就慢得多
  • LDAP提供了静态数据的快速查询方式
  • Client/server模型,Server 用于存储数据,Client提供操作目录信息树的工具
  • 这些工具可以将数据库的内容以文本格式(LDAP 数据交换格式,LDIF)呈现在您的面前
  • LDAP是一种开放Internet标准,LDAP协议是跨平台的Interent协议

3. LDAP组织数据的方式


4. 基本概念


在浏览LDAP相关文档时经常会遇见一些概念,下面是常见概念的简单解释。

4.1 Entry

条目,也叫记录项,是LDAP中最基本的颗粒,就像字典中的词条,或者是数据库中的记录。通常对LDAP的添加、删除、更改、检索都是以条目为基本对象的。

  • dn:每一个条目都有一个唯一的标识名(distinguished Name ,DN),如上图中一个 dn:”cn=baby,ou=marketing,ou=people,dc=mydomain,dc=org” 。通过DN的层次型语法结构,可以方便地表示出条目在LDAP树中的位置,通常用于检索。

  • rdn:一般指dn逗号最左边的部分,如cn=baby。它与RootDN不同,RootDN通常与RootPW同时出现,特指管理LDAP中信息的最高权限用户。

  • Base DN:LDAP目录树的最顶部就是根,也就是所谓的“Base DN”,如”dc=mydomain,dc=org”。

4.2 Attribute

每个条目都可以有很多属性(Attribute),比如常见的人都有姓名、地址、电话等属性。每个属性都有名称及对应的值,属性值可以有单个、多个,比如你有多个邮箱。

属性不是随便定义的,需要符合一定的规则,而这个规则可以通过schema制定。比如,如果一个entry没有包含在 inetorgperson 这个 schema 中的objectClass: inetOrgPerson,那么就不能为它指定employeeNumber属性,因为employeeNumber是在inetOrgPerson中定义的。

LDAP为人员组织机构中常见的对象都设计了属性(比如commonName,surname)。下面有一些常用的别名:

属性别名语法描述值(举例)
commonNamecnDirectoryString姓名
surnamesnDirectoryString
organizationalUnitNameouDirectoryString单位(部门)名称
organization oDirectoryString组织(公司)名称
telephoneNumber TelephoneNumber电话号码
objectClass  内置属性organizationalPerson

4.3 ObjectClass

对象类是属性的集合,LDAP预想了很多人员组织机构中常见的对象,并将其封装成对象类。比如人员(person)含有姓(sn)、名(cn)、电话(telephoneNumber)、密码(userPassword)等属性,单位职工(organizationalPerson)是人员(person)的继承类,除了上述属性之外还含有职务(title)、邮政编码(postalCode)、通信地址(postalAddress)等属性。

通过对象类可以方便的定义条目类型。每个条目可以直接继承多个对象类,这样就继承了各种属性。如果2个对象类中有相同的属性,则条目继承后只会保留1个属性。对象类同时也规定了哪些属性是基本信息,必须含有(Must 活Required,必要属性):哪些属性是扩展信息,可以含有(May或Optional,可选属性)。

对象类有三种类型:结构类型(Structural)、抽象类型(Abstract)和辅助类型(Auxiliary)。结构类型是最基本的类型,它规定了对象实体的基本属性,每个条目属于且仅属于一个结构型对象类。抽象类型可以是结构类型或其他抽象类型父类,它将对象属性中共性的部分组织在一起,称为其他类的模板,条目不能直接集成抽象型对象类。辅助类型规定了对象实体的扩展属性。每个条目至少有一个结构性对象类。

对象类本身是可以相互继承的,所以对象类的根类是top抽象型对象类。以常用的人员类型为例,他们的继承关系:

下面是inetOrgPerson对象类的在schema中的定义,可以清楚的看到它的父类SUB和可选属性MAY、必要属性MUST(继承自organizationalPerson),关于各属性的语法则在schema中的attributetype定义。

# inetOrgPerson
# The inetOrgPerson represents people who are associated with an
# organization in some way.  It is a structural class and is derived
# from the organizationalPerson which is defined in X.521 [X521].
objectclass     ( 2.16.840.1.113730.3.2.2
    NAME 'inetOrgPerson'
        DESC 'RFC2798: Internet Organizational Person'
    SUP organizationalPerson
    STRUCTURAL
        MAY (
                audio $ businessCategory $ carLicense $ departmentNumber $
                displayName $ employeeNumber $ employeeType $ givenName $
                homePhone $ homePostalAddress $ initials $ jpegPhoto $
                labeledURI $ mail $ manager $ mobile $ o $ pager $
                photo $ roomNumber $ secretary $ uid $ userCertificate $
                x500uniqueIdentifier $ preferredLanguage $
                userSMIMECertificate $ userPKCS12 )
        )

4.4 Schema

对象类(ObjectClass)、属性类型(AttributeType)、语法(Syntax)分别约定了条目、属性、值,他们之间的关系如下图所示。所以这些构成了模式(Schema)——对象类的集合。条目数据在导入时通常需要接受模式检查,它确保了目录中所有的条目数据结构都是一致的。

schema(一般在/etc/ldap/schema/目录)在导入时要注意前后顺序。

4.5 backend & database

ldap的后台进程slapd接收、响应请求,但实际存储数据、获取数据的操作是由Backends做的,而数据是存放在database中,所以你可以看到往往你可以看到backend和database指令是一样的值如 bdb 。一个 backend 可以有多个 database instance,但每个 database 的 suffix 和 rootdn 不一样。openldap 2.4版本的模块是动态加载的,所以在使用backend时需要moduleload back_bdb指令。

bdb是一个高性能的支持事务和故障恢复的数据库后端,可以满足绝大部分需求。许多旧文档里(包括官方)说建议将bdb作为首选后端服务(primary backend),但2.4版文档明确说hdb才是被首先推荐使用的,这从 2.4.40 版默认安装后的配置文件里也可以看出。hdb是基于bdb的,但是它通过扩展的索引和缓存技术可以加快数据访问,修改entries会更有效率,有兴趣可以访问上的链接或slapd.backends

另外config是特殊的backend,用来在运行时管理slapd的配置,它只能有一个实例,甚至无需显式在slapd.conf中配置。

4.6 TLS & SASL

分布式LDAP 是以明文的格式通过网络来发送信息的,包括client访问ldap的密码(当然一般密码已然是二进制的),SSL/TLS 的加密协议就是来保证数据传送的保密性和完整性。

SASL (Simple Authenticaion and Security Layer)简单身份验证安全框架,它能够实现openldap客户端到服务端的用户验证,也是ldapsearch、ldapmodify这些标准客户端工具默认尝试与LDAP服务端认证用户的方式(前提是已经安装好 Cyrus SASL)。SASL有几大工业实现标准:Kerveros V5、DIGEST-MD5、EXTERNAL、PLAIN、LOGIN。

Kerveros V5是里面最复杂的一种,使用GSSAPI机制,必须配置完整的Kerberos V5安全系统,密码不再存放在目录服务器中,每一个dn与Kerberos数据库的主体对应。DIGEST-MD5稍微简单一点,密码通过saslpasswd2生成放在sasldb数据库中,或者将明文hash存到LDAP dn的userPassword中,每一个authid映射成目录服务器的dn,常和SSL配合使用。参考将 LDAP 客户端配置为使用安全性

EXTERNAL一般用于初始化添加schema时使用,如ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/core.ldif

4.7 LDIF

LDIF(LDAP Data Interchange Format,数据交换格式)是LDAP数据库信息的一种文本格式,用于数据的导入导出,每行都是“属性: 值”对,见 openldap ldif格式示例

OpenLDAP(2.4.3x)服务器安装配置方法见这里

参考

LDAP基础概念 LDAP-HOWTO openldap doc admin24

No comments:

Post a Comment