如何使用 iRedMail 的 LDAP 数据库进行用户身份验证?

如何使用 iRedMail 的 LDAP 数据库进行用户身份验证?

我设置了一些服务器,我想使用 LDAP 集中管理用户的访问。我的主要服务器使用 iRedMail 托管电子邮件,并且已经有一个使用 iRedMail 设置的 LDAP 数据库。现在,我想将我的用户帐户与他们的电子邮件帐户绑定在一起(例如,更改他们的电子邮件密码也会更改他们有权访问的服务器上的密码)。我已经搜索过(DuckDuckGoing?)如何使用 iRedMail 的 LDAP 数据库作为 UNIX 帐户的用户身份验证数据库,但我还没有找到任何有用的东西。有人这样做过吗,有什么建议吗?

答案1

所以,我找到了答案。下面是我如何完成此操作的快速指南:

  1. 首先,iRedMail 在安装时会自动生成 SSL 证书。如果您的主机名不是您想要的证书 CN,那么您将需要生成新的 SSL 证书。实际上,无论如何我都会这样做。以下是完成第一步的方法:

    $ cd iRedMail-0.8.5/tools
    $ vi generate_ssl_keys.sh
    
    # Modify the following line
    export HOSTNAME="*.yourdomain.com" # I created a wildcard cert
    
    # Set the rest (e.g., TLS_COUNTRY) to match your information
    
  2. 现在我们需要生成 SSL 证书:

    $ sh generate_ssl_keys.sh
    $ mv certs/iRedMail_CA.pem /etc/pki/tls/certs/
    $ mv private/iRedMail.key /etc/pki/tls/private/
    
  3. 此时我重启了系统。对我来说这比重启一堆服务要简单得多。

  4. 现在,在转到 LDAP 客户端之前,我们需要对 LDAP 服务器进行一些更改。我们要做的第一个更改是将 unixHomeDirectory 添加到 posixAccount 对象类。原因是:我不希望我的用户被困在 iRedMail 与其帐户关联的 homeDirectory 中。

    $ vi /etc/openldap/schema/nis.schema
    
    # Add the following under attributetype nisMapEntry (1.3.6.1.1.1.1.27)
    attributetype ( 1.3.6.1.1.1.1.28 NAME 'unixHomeDirectory'
        DESC 'The absolute path to the users home directory'
        EQUALITY caseExactIA5Match
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
    
    # Associate unixHomeDirectory with the posixAccount objectclass
    objectclass ( 1.3.6.1.1.1.2.0 NAME 'posixAccount'
        DESC 'Abstraction of an account with POSIX attributes'
        SUP top AUXILIARY
        MUST ( cn $ uid $ uidNumber $ gidNumber $ homeDirectory )
        MAY ( userPassword $ loginShell $ gecos $ unixHomeDirectory $ description ) )
    
  5. 现在我们要为用户添加一个 obMemberOf 属性。稍后会与 sssd 一起使用。

    $ vi /etc/openldap/schema/iredmail.schema
    
    # I added this under listAllowedUser attributetype (1.3.6.1.4.1.32349.1.2.3.3)
    attributetype ( 1.3.6.1.4.1.32359.1.2.3.4 NAME 'obMemberOf'
        DESC 'Distinguished name of a group of which the object is a member'
        EQUALITY distinguishedNameMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
    
    # And then I associated it with the objectclass mailUser
    objectclass ( 1.3.6.1.4.1.32349.1.2.4.3 NAME 'mailUser'
        DESC 'Mail User' SUP top AUXILIARY
        MUST ( mail $ uid )
        MAY ( storageBaseDirectory $ mailMessageStore $ homeDirectory $
              userPassword $ mailHost $ mailUID $ mailGID $
              mailQuota $ mailQuotaMessageLimit $
              mailForwardingAddress $ shadowAddress $ accountStatus $
              userRecipientBccAddress $ userSenderBccAddress $
              enabledService $ telephoneNumber $ backupMailAddress $
              mtaTransport $ memberOfGroup $ expiredDate $
              lastLoginDate $ lastLoginIP $ lastLoginProtocol $
              preferredLanguage $ disclaimer $ accountSetting $
              title $ userManager $
              mailWhitelistRecipient $ mailBlacklistRecipient $
              domainGlobalAdmin $ obMemberOf ))
    
  6. 我对 /etc/openldap/slapd.conf 做了以下更改

    # Comment out disallow bind_anon
    # Disallow bind as anonymous.
    #disallow    bind_anon
    
    # Uncommented this line
    # Uncomment below line to allow binding as anonymouse.
    allow bind_anon_cred
    
    #
    access to dn.regex="cn=[^,]+,dc=domain,dc=com"
          by anonymous                    auth
          by self                         write
          by users                        none
    
    # Added these two lines
    access to dn.exact=""
          by * read
    
    # And these two
    access to dn.exact="cn=Subschema"
         by * read
    
    # And gave anonymous read access
    # Set default permission.
    access to *
        by anonymous                    read
        by self                         write
        by users                        read
    
  7. 现在我去了https://www.mydomain.com/iredadmin并添加了一个用户。添加用户后,ldapsearch 返回以下内容:

    # [email protected], Users, mydomain.com, domains, mydomain.com
    dn: [email protected],ou=Users,domainName=mydomain.com,o=domains,dc=mydomain,dc=com
    objectClass: inetOrgPerson
    objectClass: mailUser
    objectClass: shadowAccount
    objectClass: amavisAccount
    mail: [email protected]
    userPassword:: XXX
    uid: user1
    storageBaseDirectory: /var/vmail
    mailMessageStore: vmail1/mydomain.com/d/a/w/user1-2013.11.19.17.43.46/
    homeDirectory: /var/vmail/vmail1/mydomain.com/d/a/w/user1-2013.11.19.17.43.46/
    enabledService: mail
    enabledService: deliver
    enabledService: lda
    enabledService: smtp
    enabledService: smtpsecured
    enabledService: pop3
    enabledService: pop3secured
    enabledService: imap
    enabledService: imapsecured
    enabledService: managesieve
    enabledService: managesievesecured
    enabledService: sieve
    enabledService: sievesecured
    enabledService: forward
    enabledService: senderbcc
    enabledService: recipientbcc
    enabledService: internal
    enabledService: lib-storage
    enabledService: shadowaddress
    enabledService: displayedInGlobalAddressBook
    shadowLastChange: 0
    amavisLocal: TRUE
    mailQuota: 0
    cn: Good User
    givenName: user1
    sn: user1
    preferredLanguage: en_US
    employeeNumber: Application Developer
    accountStatus: active
    
  8. 我们可以看到,使其成为 posixAccount 所需的一切都缺失了。因此,我们要做的就是:

     $ vi /tmp/user1.modify
     # Now, I create a file called /tmp/user1.modify that looks like this
     dn: [email protected],ou=Users,domainName=mydomain.com,o=domains,dc=mydomain,dc=com
     changetype: modify
     add: objectClass
     objectClass: posixAccount
     -
     add: loginShell
     loginShell: /bin/bash
     -
     add: uidNumber
     uidNumber: 2006
     -
     add: gidNumber
     gidNumber: 2006
     -
     add: unixHomeDirectory
     unixHomeDirectory: /home/user1
    
  9. 然后我们运行 ldapmodify 来为帐户添加属性

    ldapmodify -x -D "cn=Manager,dc=mydomain,dc=com" -W -f /tmp/user1.modify
    
  10. 现在我创建一个 LDAP 组。

    vi /tmp/devgroup.ldif
    
    # Paste the following in there
    dn: cn=developers,ou=Groups,domainName=mydomain.com,o=domains,dc=mydomain,dc=com
    objectClass: posixGroup
    objectClass: top
    cn: developers
    userPassword:: {crypt}x
    gidNumber: 1500
    memberUid: user1
    
    # And add to LDAP
    ldapadd -x -D "cn=Manager,dc=mydomain,dc=com" -W -f /tmp/devgroup.ldif
    
  11. 将 user1 添加为开发人员组的 obMemberOf

     vi /tmp/user1.modify
    
     # It should now look like this
     dn: [email protected],ou=Users,domainName=mydomain.com,o=domains,dc=mydomain,dc=com
     changetype: modify
     add: obMemberOf
     obMemberOf: cn=developers,ou=Groups,domainName=mydomain.com,o=domains,dc=mydomain,dc=com
    
     # Run ldapmodify
     ldapmodify -x -D "cn=Manager,dc=mydomain,dc=com" -W -f /tmp/user1.modify
    
  12. 此时,我们有 user1、两个自定义属性(obMemberOf、unixHomeDirectory)和一个供开发人员使用的 LDAP 组。现在是时候设置一些客户端了。我设置的第一个客户端运行的是 Ubuntu 12.04 服务器。以下是该客户端的步骤:

      # First install all the relevant packages
      $ apt-get install ldap-utils libpam-ldap libnss-ldap nslcd
    
      # I need the SSL cert from my iRedMail host
      scp [email protected]:/etc/pki/tls/certs/iRedMail_CA.pem /etc/ssl/certs/cacert.pem
    
      # Now we configure the LDAP client
      $ vi /etc/ldap.conf
    
      # Here's what my ldap.conf ended up looking like:
      # BEGIN /etc/ldap.conf
      host ldap.mydomain.com
      base dc=mydomain,dc=com
      ldap_version 3
      # You can user cn=Manager,dc=yourdomain,dc=com if you'd like. iRedMail sets up this vmail account as read-only, so I went with that instead.
      rootbinddn cn=vmail,dc=mydomain,dc=com
      pam_password ssha
      nss_base_passwd ou=Users,domainName=mydomain.com,o=domains,dc=mydomain,dc=com
      nss_base_shadow ou=Users,domainName=mydomain.com,o=domains,dc=mydomain,dc=com
      nss_base_group ou=Groups,domainName=mydomain.com,o=domains,dc=mydomain,dc=com
      nss_map_attribute homeDirectory unixHomeDirectory
      pam_login_attribute uid
      ssl start_tls
      tls_checkpeer yes
      tls_cacertfile /etc/ssl/certs/cacert.pem
      # END /etc/ldap.conf
    
      # Create file /etc/ldap.secret and put the plain text password for your rootbinddnn in there, then 'chmod 600 /etc/ldap.secret (root:root ownership).
    
      # Next I edit /etc/nslcd.conf. Here is that file
      # BEGIN /etc/nslcd.conf
      uid nslcd
      gid nslcd
      uri ldap://ldap.mydomain.com
      base dc=mydomain,dc=com
      ldap_version 3
      ssl start_tls
      tls_reqcert demand
      tls_cacertfile /etc/ssl/certs/cacert.pem
      # END /etc/nslcd.conf
    
      # Now I edit /etc/ldap/ldap.conf and add the following line to the bottom
      # It is the only uncommented line in the file
      TLS_CACERT    /etc/ssl/certs/cacert.pem
    
      # My PAM files look as follows
    
      # BEGIN /etc/pam.d/common-account
      account   [success=2 new_authtok_reqd=done default=ignore]    pam_unix.so 
      account   [success=1 default=ignore]  pam_ldap.so 
      account   requisite           pam_deny.so
      account   required            pam_permit.so
      # END /etc/pam.d/common-account
    
      # BEGIN /etc/pam.d/common-auth
      auth  [success=2 default=ignore]  pam_unix.so nullok_secure
      auth  [success=1 default=ignore]  pam_ldap.so use_first_pass
      auth  requisite           pam_deny.so
      auth  required            pam_permit.so
      # END /etc/pam.d/common-auth
    
      # BEGIN /etc/pam.d/common-password
      password  [success=2 default=ignore]  pam_unix.so obscure sha512
      password  [success=1 user_unknown=ignore default=die] pam_ldap.so try_first_pass
      password  requisite           pam_deny.so
      password  required            pam_permit.so
      # END /etc/pam.d/common-password
    
      # BEGIN /etc/pam.d/common-session
      session   [default=1]         pam_permit.so
      session   requisite           pam_deny.so
      session   required            pam_permit.so
      session       optional            pam_umask.so
      session   required                    pam_unix.so 
      session   optional            pam_ldap.so 
      session   optional                    pam_systemd.so 
      session required pam_mkhomedir.so skel=/etc/skel umask=0022
      # END /etc/pam.d/common-session
    
      # I then edit /etc/nsswitch.conf and added ldap at the end of the passwd, group and shadow lines
      passwd:         compat ldap
      group:          compat ldap
      shadow:         compat ldap
    
      # Enable the service and restart it
      $ update-rc.d nslcd enable
      $ /etc/init.d/nscd restart
    
      # Test things out
      $ gnutls-cli --x509cafile /etc/ssl/certs/cacert.pem ldap.mydomain.com
      $ ldapsearch -H"ldap://ldap.mydomain.com" -D "cn=vmail,dc=mydomain,dc=com" -b "dc=mydomain,dc=com" -W -d-1 -Z 
      $ getent passwd
      $ id user1
    
      # You should now be able to su to user1 and ssh in as user1.
    
  13. 我设置的下一个客户端是运行 sssd 的 CentOS 6.4 服务器。

      # Install the relevant packages
      $ yum install openldap-clients sssd
      $ chkconfig sssd on
    
      # For now I set SELinux to permissive
      $ echo 0 > /selinux/enforce
    
      # scp  my cert over
      $ scp [email protected]:/etc/pki/tls/certs/iRedMail_CA.pem /tmp
      $ scp [email protected]:/etc/pki/tls/private/iRedMail.key /tmp
    
      # combine the two certs
      $ awk 'FNR==1{print ""}1' /tmp/iRedMail.key /tmp/iRedMail_CA.pem > /etc/openldap/cacerts/iRedMail_CA.pem
      $ cacertdir_rehash /etc/openldap/cacerts/
    
      # Enable sssd.
      $ authconfig --enableldap --enableldapauth --ldapserver=ldaps://ldap.mydomain.com --ldapbasedn="dc=mydomain,dc=com" --update
    
      # I modified my /etc/sssd.conf file to look like this:
      [sssd]
      config_file_version = 2
      services = nss, pam
      domains = LDAP
      [nss]
      filter_users = root,named,avahi,haldaemon,dbus,radiusd,news,nscd
    
      [pam]
    
      [domain/LDAP]
      ldap_search_base = dc=mydomain,dc=com
      ldap_access_filter = obMemberOf=cn=developers,ou=Groups,domainName=mydomain.com,o=domains,dc=mydomain,dc=com
      id_provider = ldap
      auth_provider = ldap
      chpass_provider = ldap
      access_provider = ldap
      ldap_schema = rfc2307
      ldap_uri = ldap://ldap.mydomain.com
      ldap_user_name = uid
      ldap_user_home_directory = unixHomeDirectory
      ldap_user_search_base = ou=Users,domainName=mydomain.com,o=domains,dc=mydomain,dc=com
      ldap_group_search_base = ou=Groups,domainName=mydomain.com,o=domains,dc=mydomain,dc=com
      ldap_default_bind_dn = cn=vmail,dc=mydomain,dc=com
      ldap_default_authtok_type = password
      ldap_default_authtok = p4ssw0rd
      enumerate = true
      cache_credentials = true
      ldap_tls_reqcert = never
      ldap_tls_cacertdir = /etc/openldap/cacerts
    
      # Start sssd in the foreground with debugging on.
      $ /usr/sbin/sssd -i -d7
    
      # Open another terminal and do the following
      $ getent passwd
      $ id user1
      $ ssh user1@localhost
      $ su - user1
    
      # Check the other terminal for any errors and fix as necessary.
      # If no errors... break the sssd process with Ctrl+C
      $ service sssd start
    

以下是我在此过程中遇到的一些错误以及我为解决每个错误所采取的方法。

警告:已设置 LDAP 访问规则“filter”,但未配置 ldap_access_filter。所有域用户都将被拒绝访问。

这就是我在服务器上添加 LDAP 组和 obMemberOf 属性的原因。然后我在 sssd 客户端上将其用作我的 ldap_access_filter(即,任何将 obMemberOf 属性设置为开发组的 DN 的人都可以访问系统。

TLS:跳过“iRedMail_CA.pem”-文件名不符合预期格式(带有数字后缀的证书哈希)

运行“cacertdir_rehash /etc/openldap/cacerts/”似乎可以解决问题。它创建了一个指向 iRedMail_CA.pem 的符号链接(带有数字后缀的证书哈希值)

我遇到了不少其他错误(大量“无效凭证”、“访问被拒绝”和其他访问相关错误)。我稍后会更新此内容以涵盖它们。

答案2

我想知道在这种情况下您是否可以配置 sssd 以使用灵活的 ldap 过滤器并查找不同的(非默认)ldap 属性。

如果您修改了 iRedMail LDAP 模式文件,则应注意将该模式与上游同步。

相关内容