部署 OpenLDAP

LDAP 可以集中管理用户信息,使得多个服务器能够共享相同的用户数据库。

建议使用 LLDAP 而不是 OpenLDAP,参见部署 LLDAP

OpenLDAP

安装

  1. 安装 OpenLDAP:

    sudo apt update
    sudo apt install slapd ldap-utils
    

    配置 OpenLDAP:

    sudo dpkg-reconfigure slapd
    
    Omit OpenLDAP server configuration: No
    DNS domain name: example.com
    Organization name: Home Lab
    Administrator password: 自设
    Do you want the database to be removed when slapd is purged: Yes
    Move old database: Yes
    
  2. 初始化目录结构:

    vim base.ldif
    
    dn: ou=People,dc=example,dc=com
    objectClass: organizationalUnit
    ou: People
    
    dn: ou=Groups,dc=example,dc=com
    objectClass: organizationalUnit
    ou: Groups
    
    • dn: Distinguished Name
    • dc: Domain Component
    • ou: Organizational Unit

    导入目录结构配置:

    ldapadd -x -D "cn=admin,dc=example,dc=com" -W -f base.ldif
    

配置证书

  1. 生成证书:

    mkdir -p /etc/ldap/tls && cd /etc/ldap/tls
    
    openssl ecparam -name prime256v1 -genkey -noout -out ca.key  # 生成 CA 私钥
    openssl req -new -x509 -days 3650 -key ca.key -out ca.crt -subj "/C=US/O=Example/CN=Example CA"  # 用 CA 私钥生成自签名证书
    openssl ecparam -name prime256v1 -genkey -noout -out server.key  # 生成服务器私钥
    openssl req -new -key server.key -out server.csr -subj "/C=US/O=Example/CN=ldap.example.com"  # 生成服务器证书签名请求
    openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -extfile <(printf "subjectAltName=DNS:meta-eon-a800-001\nbasicConstraints=CA:FALSE\nkeyUsage=digitalSignature,keyEncipherment\nextendedKeyUsage=serverAuth")  # 使用 CA 私钥签发证书
    
    # 设置权限
    chown -R openldap:openldap /etc/ldap/tls
    chmod 600 /etc/ldap/tls/*.key
    chmod 644 /etc/ldap/tls/*.crt
    
  2. 加载证书:

    vim tls.ldif
    
    dn: cn=config
    changetype: modify
    replace: olcTLSCACertificateFile
    olcTLSCACertificateFile: /etc/ldap/tls/ca.crt
    -
    replace: olcTLSCertificateFile
    olcTLSCertificateFile: /etc/ldap/tls/server.crt
    -
    replace: olcTLSCertificateKeyFile
    olcTLSCertificateKeyFile: /etc/ldap/tls/server.key
    
    sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f tls.ldif
    sudo systemctl restart slapd
    
  3. 信任证书:

    # 将 ca.crt 分发到所有客户端
    sudo cp /etc/ldap/tls/ca.crt /usr/local/share/ca-certificates/sysu-hcp-ca.crt
    sudo update-ca-certificates
    

SSH

  1. 创建 SSH 公钥 schema:

    sudoedit /etc/ldap/schema/openssh-lpk.ldif
    
    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 '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'
      DESC 'OpenSSH LPK objectclass'
      SUP top
      AUXILIARY
      MAY ( sshPublicKey $ uid ) )
    
  2. 导入 schema:

    sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/openssh-lpk.ldif
    

sudo

  1. 下载并安装 sudo schema:

    sudo wget -O /etc/ldap/schema/sudo.ldif https://raw.githubusercontent.com/sudo-project/sudo/main/docs/schema.olcSudo
    sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/sudo.ldif
    
  2. 创建 sudoer 配置

    sudoedit /etc/ldap/schema/sudoers.ldif
    
    dn: ou=sudoers,dc=example,dc=com
    objectClass: top
    objectClass: organizationalUnit
    ou: sudoers
    
    dn: cn=defaults,ou=sudoers,dc=example,dc=com
    objectClass: top
    objectClass: sudoRole
    cn: defaults
    sudoOption: !visiblepw
    sudoOption: env_reset
    
    dn: cn=admins,ou=sudoers,dc=example,dc=com
    objectClass: top
    objectClass: sudoRole
    cn: admins
    sudoUser: %admins
    sudoHost: ALL
    sudoRunAsUser: ALL
    sudoCommand: ALL
    
  3. 导入 sudoer 配置:

    ldapadd -x -D "cn=admin,dc=example,dc=com" -W -f /etc/ldap/schema/sudoers.ldif
    

添加用户

  1. 创建用户配置:

    slappasswd  # 生成用户密码哈希(可选)
    vim users.ldif
    
    dn: uid=alice,ou=People,dc=example,dc=com
    objectClass: inetOrgPerson
    objectClass: posixAccount
    objectClass: shadowAccount
    objectClass: ldapPublicKey
    cn: Alice Zhang
    sn: Zhang
    uid: alice
    uidNumber: 1001
    gidNumber: 1001
    homeDirectory: /home/alice
    loginShell: /bin/bash
    sshPublicKey: ssh-ed25519 AAAAC3Nz... alice@laptop
    userPassword: {SSHA}<hash>
    
    • cn: Common Name
    • sn: Surname
  2. 导入用户配置:

    ldapadd -x -D "cn=admin,dc=example,dc=com" -W -f users.ldif        # 导入
    ldapsearch -x -LLL -H ldap://localhost -b "dc=example,dc=com" uid  # 验证
    

添加组

  1. 创建 admins 组:
vim admins.ldif
dn: cn=admins,ou=Groups,dc=example,dc=com
objectClass: top
objectClass: posixGroup
cn: admins
gidNumber: 10000
ldapadd -x -D "cn=admin,dc=example,dc=com" -W -f admins.ldif
  1. 添加用户:
vim addmember.ldif
dn: cn=admins,ou=Groups,dc=example,dc=com
changetype: modify
add: memberUid
memberUid: alice
ldapmodify -x -D "cn=admin,dc=example,dc=com" -W -f addmember.ldif

SSSD

  1. 安装 SSSD:

    sudo apt install sssd sssd-ldap libpam-sss libnss-sss libsss-sudo
    

    一些教程安装 nslcd/nscd,这是比较过时的配置,新系统建议使用 SSSD

    配置 SSSD:

    sudoedit /etc/sssd/sssd.conf
    
    [sssd]
    services = nss, pam, ssh, sudo
    domains = default
    
    [domain/default]
    id_provider = ldap
    auth_provider = ldap
    sudo_provider = ldap
    
    ldap_uri = ldap://example.com
    ldap_search_base = dc=example,dc=com
    ldap_sudo_search_base = ou=sudoers,dc=example,dc=com
    # 默认 bind DN 和密码
    ldap_default_bind_dn = cn=admin,dc=example,dc=com
    ldap_default_authtok = password
    # TLS 设置
    ldap_id_use_start_tls = true
    ldap_tls_reqcert = demand
    # LDAP 字段映射
    ldap_user_ssh_public_key = sshPublicKey
    # 其他
    cache_credentials = true
    enumerate = true
    auto_private_groups = true
    
    sudo chmod 600 /etc/sssd/sssd.conf
    sudo systemctl enable --now sssd
    
  2. NSS 与 PAM 集成。

    确保如下行包含 sss

    sudoedit /etc/nsswitch.conf
    
    passwd:         files systemd sss
    group:          files systemd sss
    shadow:         files systemd sss
    sudoers:        files sss
    
  3. PAM 启用 SSS 认证:

    sudo pam-auth-update
    
    [*] SSS authentication
    [*] Create home directory on login
    
  4. 配置 sshd 从 LDAP 获取公钥:

    sudoedit /etc/ssh/sshd_config.d/50-cloud-init.conf
    
    AuthorizedKeysCommand /usr/bin/sss_ssh_authorizedkeys
    AuthorizedKeysCommandUser nobody
    
    sudo systemctl restart sshd
    
  5. 验证:

    getent passwd alice
    getent group alice
    sudo -u nobody /usr/bin/sss_ssh_authorizedkeys alice
    

备份

sudo slapcat > backup.ldif   # 导出 LDAP
sudo slapadd -l backup.ldif  # 恢复 LDAP

LDAP 知识

ObjectClass

  • inetOrgPerson:结构类,提供基础属性(cn, sn, uid)
  • posixAccount:辅助类,提供 Unix 账户属性(uidNumber, gidNumber, homeDirectory, loginShell)
  • ldapPublicKey:辅助类,提供 sshPublicKey(需要 openssh-lpk 模式)

Troubleshooting

ldapsearch 无法查询到用户添加结果

697d0ca6 conn=1004 op=42 ADD dn="uid=ubuntu,ou=People,dc=example,dc=com"
697d0ca6 conn=1004 op=42 RESULT tag=105 err=0 text=
697d0ca6 conn=1004 op=43 UNBIND
697d0ca6 conn=1004 fd=12 closed
697d0ca6 connection_read(12): no connection!
697d0cb7 conn=1005 fd=12 ACCEPT from IP=172.16.0.1:57924 (IP=0.0.0.0:389)
697d0cb7 conn=1005 op=0 BIND dn="" method=128
697d0cb7 conn=1005 op=0 RESULT tag=97 err=0 text=
697d0cb7 conn=1005 op=1 SRCH base="dc=example,dc=com" scope=2 deref=0 filter="(objectClass=*)"
697d0cb7 conn=1005 op=1 SRCH attr=uid
697d0cb7 conn=1005 op=1 SEARCH RESULT tag=101 err=32 nentries=0 text=
697d0cb7 conn=1005 op=2 UNBIND
697d0cb7 conn=1005 fd=12 closed

原因:匿名用户没有权限读取 LDAP 目录中的数据。

解决方法:使用 admin 用户登录

ldapsearch -x \
  -H ldap://localhost \
  -b "dc=example,dc=com" \
  -D "cn=admin,dc=example,dc=com" -W \
  "(objectClass=*)" uid
posted @ 2025-08-21 21:14  Undefined443  阅读(39)  评论(0)    收藏  举报