Авторизация в системе через LDAP

Задача — сделать возможным вход и работу в системе пользователей, существующих только в базе LDAP.
Необходимые пакеты: nss_ldap и pam_ldap.

Прежде всего нужно определить запросы к LDAP-серверу. Рассмотрим две реализации: OpenLDAP и Active Directory.

  1. OpenLDAP

    Запросы к серверу будут выглядеть как (&(objectClass=posixAccount)(uid=test)). Чтобы избежать ошибок индексирования, в /etc/openldap/slapd.conf на стороне сервера необходимо добавить:

    index uid pres,eq,sub
    

    Теперь определим клиентский /etc/ldap.conf:

    host example.com
    base dc=local,dc=ru
    uri ldap://example.com:389/
    ldap_version 3
    
    binddn cn=admin,dc=local,dc=ru
    bindpw password 
    
    scope one
    
    timelimit 30
    bind_timelimit 30
    bind_policy soft
    nss_connect_policy persist
    
    pam_password md5
    pam_filter objectclass=posixAccount
    pam_login_attribute uid
    pam_member_attribute gid
    
    nss_base_passwd ou=Users,dc=local,dc=ru
    nss_base_shadow ou=Users,dc=local,dc=ru
    nss_base_group  ou=Group,dc=local,dc=ru
    
    nss_reconnect_tries 4
    nss_reconnect_sleeptime 1
    nss_reconnect_maxsleeptime 16
    nss_reconnect_maxconntries 2
    

    Пример файла LDIF для создания пользователя на сервере:

    dn: uid=test,ou=Users,dc=local,dc=ru
    uid: test
    cn: test
    objectclass: account
    objectclass: posixAccount
    objectclass: top
    loginshell: /bin/bash
    uidnumber: 2004
    gidnumber: 2004
    homedirectory: /home/test_directory
    gecos: test
    userpassword: {MD5}CY9rzUYh03PK3k6DJie09g==
    

    После этого запись о пользователе будет определяться как:

    test:*:2004:2004:test:/home/test_directory:/bin/bash

  2. Active Directory

    В данном случае /etc/ldap.conf будет выглядеть так:

    host example.com
    base dc=local,dc=ru
    uri ldap://example.com
    ldap_version 3
    
    binddn cn=admin,dc=local,dc=ru
    bindpw password
    
    nss_map_objectclass posixAccount user
    nss_map_objectclass shadowAccount user
    nss_map_attribute uid msSFU30Name
    nss_map_attribute uidNumber uidNumber
    nss_map_attribute gidNumber gidNumber
    nss_map_attribute homeDirectory unixHomeDirectory
    nss_map_attributes loginShell loginShell
    nss_map_objectclass posixGroup primaryGroupID
    pam_login_attribute msSFU30Name
    pam_filter objectclass=user
    pam_password ad
    sasl_secprops maxssf=0
    

Настройка NSS

В файле /etc/nsswitch.conf нужно указать, что пользователей следует брать и из LDAP:

passwd:      compat ldap
shadow:      compat ldap
group:       compat ldap

Теперь команда getent passwd должна показывать пользователей, существующих как в локальной системе, так и в базе LDAP.

Настройка PAM

Осталось связать LDAP-пользователей с авторизацией в системе. Это выполняется с помощью файла /etc/pam.d/system-auth.

⚠️ Внимание: порядок строк в этом файле имеет значение!

Пример полного содержимого:

auth            required        pam_env.so
auth            sufficient      pam_ssh.so
auth            sufficient      pam_unix.so try_first_pass likeauth nullok
auth            sufficient      pam_ldap.so use_first_pass
auth            required        pam_deny.so

account         required        pam_unix.so
account         [default=bad success=ok user_unknown=ignore]      pam_ldap.so

password        required        pam_cracklib.so difok=2 minlen=8 dcredit=2 ocredit=2 retry=3
password        required        pam_unix.so try_first_pass use_authtok nullok sha512 shadow
password        sufficient      pam_ldap.so use_authtok
password        required        pam_deny.so

session         optional        pam_ssh.so
session         required        pam_limits.so
session         required        pam_env.so
session         required        pam_unix.so
session         optional        pam_permit.so
session         required        pam_mkhomedir.so skel=/etc/skel/ umask=0
session         optional        pam_ldap.so