部署 OpenLDAP
LDAP 可以集中管理用户信息,使得多个服务器能够共享相同的用户数据库。
建议使用 LLDAP 而不是 OpenLDAP,参见部署 LLDAP
OpenLDAP
安装
-
安装 OpenLDAP:
sudo apt update sudo apt install slapd ldap-utils配置 OpenLDAP:
sudo dpkg-reconfigure slapdOmit 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 -
初始化目录结构:
vim base.ldifdn: ou=People,dc=example,dc=com objectClass: organizationalUnit ou: People dn: ou=Groups,dc=example,dc=com objectClass: organizationalUnit ou: Groupsdn: Distinguished Namedc: Domain Componentou: Organizational Unit
导入目录结构配置:
ldapadd -x -D "cn=admin,dc=example,dc=com" -W -f base.ldif
配置证书
-
生成证书:
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 -
加载证书:
vim tls.ldifdn: 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.keysudo ldapmodify -Y EXTERNAL -H ldapi:/// -f tls.ldif sudo systemctl restart slapd -
信任证书:
# 将 ca.crt 分发到所有客户端 sudo cp /etc/ldap/tls/ca.crt /usr/local/share/ca-certificates/sysu-hcp-ca.crt sudo update-ca-certificates
SSH
-
创建 SSH 公钥 schema:
sudoedit /etc/ldap/schema/openssh-lpk.ldifdn: 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 ) ) -
导入 schema:
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/openssh-lpk.ldif
sudo
-
下载并安装 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 -
创建 sudoer 配置
sudoedit /etc/ldap/schema/sudoers.ldifdn: 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 -
导入 sudoer 配置:
ldapadd -x -D "cn=admin,dc=example,dc=com" -W -f /etc/ldap/schema/sudoers.ldif
添加用户
-
创建用户配置:
slappasswd # 生成用户密码哈希(可选) vim users.ldifdn: 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 Namesn: Surname
-
导入用户配置:
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 # 验证
添加组
- 创建 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
- 添加用户:
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
-
安装 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 = truesudo chmod 600 /etc/sssd/sssd.conf sudo systemctl enable --now sssd -
NSS 与 PAM 集成。
确保如下行包含
sss:sudoedit /etc/nsswitch.confpasswd: files systemd sss group: files systemd sss shadow: files systemd sss sudoers: files sss -
PAM 启用 SSS 认证:
sudo pam-auth-update[*] SSS authentication [*] Create home directory on login -
配置 sshd 从 LDAP 获取公钥:
sudoedit /etc/ssh/sshd_config.d/50-cloud-init.confAuthorizedKeysCommand /usr/bin/sss_ssh_authorizedkeys AuthorizedKeysCommandUser nobodysudo systemctl restart sshd -
验证:
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

浙公网安备 33010602011771号