I have a few servers set up and I'd like to centralize access for users using LDAP. I have my primary server that is hosting email using iRedMail, and there already happens to be an LDAP database that was set up with iRedMail. Now, I'd like for my user accounts to be tied to their email accounts (for example, changing their email password also changes their password on servers they have access to). I've done some searching (DuckDuckGoing?) for how to use iRedMail's LDAP database as a user authentication database for UNIX accounts, but I've yet to find anything remotely helpful. Anyone ever done this have any tips?
2 Answers
So, I figured it out. Here's a quick and dirty guide on how I got it done:
First, iRedMail automatically generates an SSL certificate on install. If your hostname is not what you want the CN for the cert to be, then you're going to need to generate a new SSL cert. Actually, I'd do this regardless. Here's how to accomplish step one:
$ 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
Now we need to generate our SSL certs:
$ sh generate_ssl_keys.sh $ mv certs/iRedMail_CA.pem /etc/pki/tls/certs/ $ mv private/iRedMail.key /etc/pki/tls/private/
At this piont I rebooted my system. It was easier for me than restarting a bunch of services.
Now, before we move to our LDAP clients, we need to make some changes to our LDAP server. The first change we will make is to add unixHomeDirectory to the posixAccount objectclass. The reason: I did not want my users being stuck in the homeDirectory that iRedMail associates with their account.
$ 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 ) )
Now we are going to add an obMemberOf attribute for our users. This will be used later with 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 ))
I made the following changes to /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
Now I went to https://www.mydomain.com/iredadmin and added a user. After adding the user, an ldapsearch returns the following:
# [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
As we can see, everything to make this a posixAccount is missing. So, that's what we're going to do:
$ 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
And we run ldapmodify to add the attributes to the account
ldapmodify -x -D "cn=Manager,dc=mydomain,dc=com" -W -f /tmp/user1.modify
Now I create an LDAP group.
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
Add user1 as an obMemberOf the developers group
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
At this point we have user1, two custom attributes (obMemberOf, unixHomeDirectory), and an LDAP group for developers. It's now time to set up a few clients. The first client I set up was running Ubuntu 12.04 server. Here are the steps for that client:
# 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.
The next client I set up was a CentOS 6.4 server running sssd.
# 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
Here are some of the errors I ran into during this process and what I did to fix each of them.
Warning: LDAP access rule 'filter' is set, but no ldap_access_filter configured. All domain users will be denied access.
This is why I added the LDAP group on my server and the obMemberOf attribute. I then used it on the sssd client as my ldap_access_filter (i.e., anyone who has attribute obMemberOf set to the DN for the development group has access to the system.
TLS: skipping 'iRedMail_CA.pem' - filename does not have expected format (certificate hash with numeric suffix)
Running 'cacertdir_rehash /etc/openldap/cacerts/' seemed to fix things. It created a symlink (the certificates hash with numeric suffix) that points to iRedMail_CA.pem
I ran into quite a few other errors (A plethora of "Invalid Credentials," "Access Denied," and other access related errors). I will update this later to cover them as well.
I wonder whether you can configure sssd to use a flexible ldap filter and lookup different (non-default) ldap attributes in this case.
If you modified iRedMail LDAP schema file, you should pay attention to sync this schema with upstream.