openldap tls 高可用部署

 openldap tls 部署

LDAP相关概念
dn(Distinguished Name):区分名称,LDAP中每个条目都有自己的dn,dn是该条目在整棵树中的唯一标识,如同文件系统中,带路径的文件名就是DN。
rdn(Relative dn):相对区别名称,好比linux中的相对路径。
dc(Domain Component):域名组件。其格式是将完整的域名分成几部分,如将http://example.com变成
dc=example,dc=com。

uid(User ID):用户ID,如 san.zhang。
ou(Organization Unit):组织单元。
cn(Common Name):公共名称。
sn(surname):姓氏。
c(Country):国家,如“CN”或者“US”。
o(Organization):组织名,如XXX银行,XXX部门,XXX公司等等。

一、安装openldap
1. 使用yum命令安装openldap
yum install  -y openldap compat-openldap openldap-clients openldap-servers openldap-devel

2. 签发证书
生成CA根证书的步骤
生成CA私钥(.key)-->生成CA证书请求(.csr)-->自签名得到根证书(.crt)

# Generate CA private key 
openssl genrsa -out ca.key 2048 

# Generate CSR  生成.csr文件时,需要在提示下输入组织相关的信息
openssl req -new -key ca.key -out ca.csr

# Generate Self Signed certificate(CA 根证书)
openssl x509 -req -days 36500 -in ca.csr -signkey ca.key -out ca.crt
#Signature ok
#subject=/C=CN/ST=HZ/L=Hangzhou/O=Vimll/OU=vimll/CN=vimll.com/emailAddress=admin@vimll.com
#Getting Private key
通常情况,我们部署在内网的服务会采用这种自签名的证书,只有部署公网服务时才会向CA机构申请证书。

生成用户证书的步骤
生成私钥(.key)-->生成证书请求(.csr)-->用CA根证书签名得到证书(.crt)

# private key
openssl genrsa -out server.key 2048 

# generate csr
openssl req -new -key server.key -out server.csr

cp /etc/pki/tls/openssl.cnf ./
mkdir -p newcerts
touch index.txt
echo "00" > serial

vim /etc/pki/tls/openssl.cnf
dir             = /nfs/tang/k8s/certs
# generate certificate
openssl ca -days 36500 -cert ca.crt -keyfile ca.key -in server.csr -out server.crt -config openssl.cnf

TLSCACertificateFile /nfs/tang/k8s/certs/ca.crt
TLSCertificateFile /nfs/tang/k8s/certs/server.crt
TLSCertificateKeyFile /nfs/tang/k8s/certs/server.key

3. OpenLDAP的相关配置文件信息
/etc/openldap/slapd.conf:OpenLDAP的主配置文件,记录根域信息,管理员名称,密码,日志,权限等
/etc/openldap/slapd.d/*:这下面是/etc/openldap/slapd.conf配置信息生成的文件,每修改一次配置信息,这里的东西就要重新生成
/etc/openldap/schema/*:OpenLDAP的schema存放的地方
/var/lib/ldap/*:OpenLDAP的数据文件
/usr/share/openldap-servers/slapd.conf.obsolete 模板配置文件
/usr/share/openldap-servers/DB_CONFIG.example 模板数据库配置文件
OpenLDAP监听的端口: 默认监听端口:389(明文数据传输) 加密监听端口:636(密文数据传输)

4. 整合kerberos
wget http://web.mit.edu/kerberos/dist/krb5/1.19/krb5-1.19.4.tar.gz
tar -xvzf krb5-1.19.4.tar.gz
cd krb5-1.19.4/src/plugins/kdb/ldap/libkdb_ldap/
cp kerberos.schema /etc/openldap/schema

5. 实现mirror mode模式
vim /etc/openldap/slapd.conf
在/etc/openldap目录下编辑添加slapd.conf配置文件,添加如下内容:

cat > /etc/openldap/slapd.conf << EOF
###################################导入schema#################################
#导入核心的schema
include /etc/openldap/schema/core.schema
#如果要整合kerberos,则需要导入kerberos.schema,否则不需要该schema
include /etc/openldap/schema/kerberos.schema
include /etc/openldap/schema/corba.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/dyngroup.schema
include /etc/openldap/schema/inetorgperson.schema
include /etc/openldap/schema/java.schema
include /etc/openldap/schema/misc.schema
include /etc/openldap/schema/nis.schema
include /etc/openldap/schema/openldap.schema
include /etc/openldap/schema/ppolicy.schema
include /etc/openldap/schema/collective.schema
###################################导入schema#################################

#接受LDAP2绑定请求
allow bind_v2
pidfile /var/run/openldap/slapd.pid
argsfile /var/run/openldap/slapd.args
#日志级别设置
# 设置-1能记录更多日志
loglevel -1  
# loglevel 296

###################################模块设置#################################
#指定模块的路径,modulepath可以配置多个
modulepath /usr/lib64/openldap
moduleload syncprov.la
###################################模块设置#################################

###################################开启sasl设置,默认关闭#################################
#TLSCACertificatePath /etc/openldap/certs
#TLSCertificateFile "\"OpenLDAP Server\""
#TLSCertificateKeyFile /etc/openldap/certs/password
###################################开启sasl设置,默认关闭#################################

###################################进行全局设置#################################
#设置serverID,采用mirror mode模式进行部署,需保证两台服务的serverID不同,一台为1、一台为2,必须使用hostname进行配置,否则无法启动成功
serverID 1 ldap://k8s01
serverID 2 ldap://k8s02
serverID 3 ldap://k8s03
###################################进行全局设置#################################

###################################数据库权限控制#################################
#数据库通用权限配置,会配置到olcDatabase={-1}frontend.ldif该文件中,访问所有数据库的通用权限
access to * 
        by anonymous auth 
        by self write 
        by users read
#config数据库配置
database config
#数据库管理员账户
rootdn "cn=config"
#数据库管理员密码,使用slappasswd -s Tang@123456命令生成,默认使用SSHA的方式进行编码,可以通过-h进行指定编码方式 slappasswd -h{md5} -s Tang@123456
rootpw {SSHA}K3vJ69p1IBtu9rwSK4hEBogmACDzIsS7
#权限设置
access to * 
        by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage 
        by * break

#进行配置同步备份
syncrepl rid=001
              provider=ldap://k8s01
              bindmethod=simple
              binddn="cn=config"
              credentials=Tang@123456
              searchbase="cn=config"
              schemachecking=on
              type=refreshAndPersist
              retry="60 +"

syncrepl rid=002
              provider=ldap://k8s02
              bindmethod=simple
              binddn="cn=config"
              credentials=Tang@123456
              searchbase="cn=config"
              schemachecking=on
              type=refreshAndPersist
              retry="60 +"

syncrepl rid=003
              provider=ldap://k8s03
              bindmethod=simple
              binddn="cn=config"
              credentials=Tang@123456
              searchbase="cn=config"
              schemachecking=on
              type=refreshAndPersist
              retry="60 +"              
#设置同步模块
overlay syncprov
#开启mirrormode设置
mirrormode on

#监控数据库配置,设置访问监控数据库的权限,开启该模块会对访问openldap服务的相关信息进行监控
database monitor
#设置访问monitor数据库的用户权限
access to *
        by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" read
        by dn.base="cn=admin,dc=vimll,dc=com" read
        by * none
###################################数据库权限控制#################################

###################################数据库配置#################################
#设置数据库类型为lmdb,官方推荐
database mdb
#进行权限设置
access to attrs=userPassword,shadowLastChange   
        by self write    
        by anonymous auth    
        by * none
#数据库匹配的前缀
suffix "dc=vimll,dc=com"
checkpoint 1024 15
#数据库管理员账户
rootdn "cn=admin,dc=vimll,dc=com"
#数据库管理员密码,使用slappasswd -s Tang@123456命令生成
rootpw {SSHA}K3vJ69p1IBtu9rwSK4hEBogmACDzIsS7
#数据库存储数据路径  目录如果不存在则需要创建并授权给ldap用户
directory /var/lib/mdb
#数据库存储最大值
maxsize 1048576
#数据库索引设置,索引objectclass、cn、uid
index objectclass,entryCSN,entryUUID eq
#数据库索引设置,索引linux账户
index uid,uidNumber,gidNumber eq,pres
#数据库索引设置,索引kerberos账户,未配置kerberos可省略
index ou,krbPrincipalName eq,pres,sub
#设置同步模块
overlay syncprov
syncprov-checkpoint 100 10
syncprov-sessionlog 100

#mirror mode相关设置
#rid:保证每台服务器的rid是一样的
#provider:指向另外一台服务的ldap地址
#bindmethod:制定简单的鉴权模式,表示未开启sasl或者ssl模式
#binddn:设置进行同步的账户,默认等同于数据库账户
#credentials:设置同步账户的密码,默认等同于数据库账户
#searchbase:设置同步的根路径
#schemachecking:采用refreshAndPersist
#retry:重试次数,如果同步失败,每隔60s同步一次
syncrepl rid=101
              provider=ldap://k8s01
              bindmethod=simple
              binddn="cn=admin,dc=vimll,dc=com"
              credentials=Tang@123456
              searchbase="dc=vimll,dc=com"
              schemachecking=on
              type=refreshAndPersist
              retry="60 +"

syncrepl rid=102
              provider=ldap://k8s02
              bindmethod=simple
              binddn="cn=admin,dc=vimll,dc=com"
              credentials=Tang@123456
              searchbase="dc=vimll,dc=com"
              schemachecking=on
              type=refreshAndPersist
              retry="60 +"

syncrepl rid=103
              provider=ldap://k8s03
              bindmethod=simple
              binddn="cn=admin,dc=vimll,dc=com"
              credentials=Tang@123456
              searchbase="dc=vimll,dc=com"
              schemachecking=on
              type=refreshAndPersist
              retry="60 +"
#开启mirror mode模式
mirrormode on
###################################数据库配置#################################
EOF

配置同步其他节点:
scp /etc/openldap/schema/kerberos.schema k8s02:/etc/openldap/schema/
scp /etc/openldap/schema/kerberos.schema k8s03:/etc/openldap/schema/
scp /etc/openldap/slapd.conf k8s02:/etc/openldap/
scp /etc/openldap/slapd.conf k8s03:/etc/openldap/

mkdir /var/lib/mdb/
rm -rf /var/lib/mdb/*
cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/mdb/DB_CONFIG
chown ldap:ldap -R  /var/lib/mdb
chown -R ldap:ldap /etc/openldap/
systemctl enable --now slapd

rm -rf /etc/openldap/slapd.d/*
slaptest -f /etc/openldap/slapd.conf -F /etc/openldap/slapd.d/
chown -R ldap:ldap /etc/openldap/
systemctl restart slapd

6. 初始化根目录
openldap的根目录需要我们事先进行初始化才可用,我们使用ldapadd的命令方式向openldap服务添加根目录,具体操作如下: 编辑文件base.ldif,添加如下内容:

cat > base.ldif << EOF
dn: dc=vimll,dc=com
objectClass: top
objectClass: dcObject
objectclass: organization
o: JTKJ
dc: vimll

dn: ou=People,dc=vimll,dc=com
objectClass: organizationalUnit
ou: people

dn: ou=Group,dc=vimll,dc=com
objectClass: organizationalUnit
ou: group
EOF

执行如下命令,添加根目录:
#-x表示进行简单认证,-D用来绑定服务器的DN,-w绑定DN的密码,-f使用ldif文件进行条目添加的文件
ldapadd -x -H ldap://127.0.0.1:389   -D "cn=admin,dc=vimll,dc=com" -w Tang@123456 -f base.ldif
执行成功以后,会将根目录数据同步到两台openldap服务器上,这样就是实现mirror mode的高可用模式,可执行如下命令进行验证是否插入成功:
#-b指定要查询的根节点
ldapsearch -x -H ldap://127.0.0.1:389 -b "dc=vimll,dc=com" -D "cn=admin,dc=vimll,dc=com" -w Tang@123456

7. 开启openldap日志访问功能
查看openldap配置是否开启日志记录功能
less /etc/openldap/slapd.d/cn\=config.ldif
#如果存在olcLogLevel:配置项的话,则已开启日志功能
olcLogLevel: Stats
如果未开启日志配置,执行如下指令,开启日志设置
编辑log_config.ldif文件,添加如下内容,保存退出,使用ldapmodify进行动态修改openldap服务配置:

cat > log_config.ldif << EOF
dn: cn=config
changetype: modify
add: olcLogLevel
#stats为打印日志的级别,可根据不同的级别设置不同的值
olcLogLevel: stats
EOF

在openldap4.X版本以后,推荐使用ldapmodify指令修改openldap的配置,而无须重启openldap服务,因此执行如下指令将需要修改的配置内容同步到cn=config.ldif配置文件中去。
ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f log_config.ldif

配置方法二
# vim /etc/openldap/slapd.conf 加上loglevel -1
loglevel -1
# 这里修改了配置文件,所有得重新生成配置文件的信息
rm -rf /etc/openldap/slapd.d/*
slaptest -f /etc/openldap/slapd.conf -F /etc/openldap/slapd.d/
chown -R ldap.ldap /etc/openldap/slapd.d/ 
systemctl restart slapd

配置rsyslog
修改/etc/rsyslog.conf配置文件,添加如下内容:

cat >> /etc/rsyslog.conf << EOF
local4.*  /var/log/slapd/slapd.log
EOF
然后重启rsyslog应用:

mkdir -p /var/log/slapd
chown ldap.ldap /var/log/slapd/
systemctl restart rsyslog
systemctl restart slapd
# 重启看到日志   ls /var/log/slapd/ 然后再目录/var/log/slapd/slapd.log目录下就可以看到slapd产生的日志了。

# 启用tls
cat > addcerts.ldif << EOF
dn: cn=config
changetype: modify
replace: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/openldap/cacerts/ca.crt
-
replace: olcTLSCertificateFile
olcTLSCertificateFile: /etc/openldap/certs/server.crt
-
replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/openldap/certs/server.key
EOF

ldapmodify -Y EXTERNAL -H ldapi:/// -f addcerts.ldif

##所有节点
vim /etc/sysconfig/slapd
SLAPD_URLS="ldapi:/// ldap:/// ldaps:///"

vim /etc/openldap/ldap.conf
更新为:
TLS_CACERTDIR /etc/openldap/cacerts
TLS_CACERT /etc/openldap/cacerts/ca.cert.pem
TLS_REQCERT allow

#never  不需要验证 client 端的身份,Client 端只需要有 CA 证书就可以了
#allow  Server会要求 client 提供证书,如果 client 端没有提供证书,会话会正常进行
#try    Client端提供了证书,但是 Server 端有可能不能校验这个证书,这个证书会被忽略,会话正常进行
#demand Server端需要认证 client 端的身份,Client 端需要有自己的证书和私钥

systemctl restart slapd

二、openldap 初始化操作
1. #创建自定义ou
cat > add_custom_ou.ldif << EOF
dn: ou=Users,dc=vimll,dc=com
objectClass: organizationalUnit
objectClass: top
ou: Users

dn: ou=GitLab,dc=vimll,dc=com
objectClass: organizationalUnit
objectClass: top
ou: GitLab

EOF

ldapadd -x -H ldap://127.0.0.1:389   -D "cn=admin,dc=vimll,dc=com" -w Tang@123456 -f add_custom_ou.ldif

2. #创建自定义子ou
cat > add_custom_ou_son.ldif << EOF
dn: ou=Jenkins,ou=Group,dc=vimll,dc=com
objectClass: organizationalUnit
objectClass: top
ou: Jenkins

dn: ou=GitLab,ou=Group,dc=vimll,dc=com
objectClass: organizationalUnit
objectClass: top
ou: GitLab

dn: ou=Users,ou=people,dc=vimll,dc=com
objectClass: organizationalUnit
objectClass: top
ou: Jira

dn: ou=Confluence,ou=Group,dc=vimll,dc=com
objectClass: organizationalUnit
objectClass: top
ou: Confluence

dn: ou=Admin,ou=People,dc=vimll,dc=com
objectClass: organizationalUnit
objectClass: top
ou: Admin

dn: ou=Users,ou=People,dc=vimll,dc=com
objectClass: organizationalUnit
objectClass: top
ou: Users
EOF

ldapadd -x -H ldap://127.0.0.1:389   -D "cn=admin,dc=vimll,dc=com" -w Tang@123456 -f add_custom_ou_son.ldif

3. #在People ou 子ou Users下面创建users用户组
cat > group_users.ldif << EOF
dn: cn=users,ou=Users,ou=People,dc=vimll,dc=com
objectClass: posixGroup
objectClass: top
cn: users
gidNumber: 1000
EOF

ldapadd -x -H ldap://127.0.0.1:389   -D "cn=admin,dc=vimll,dc=com" -w Tang@123456 -f group_users.ldif

4. 创建账户
添加用户wuyutang, 位置在People OU的子OU Users下,并绑定到People的用户组Users,创建tang用户于Users ou下,并绑定用户组Users.
cat > usersadd.ldif << EOF
dn: cn=wuyutang,ou=Users,ou=People,dc=vimll,dc=com
objectClass: top
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
cn: wuyutang
sn: wu
uid: wuyutang
userPassword: 123456
uidNumber: 1008
gidNumber: 1000
homeDirectory: /home/wuyutang
mail: wuyutang@vimll.com
title: add user wuyutang

dn: cn=tang,ou=Users,dc=vimll,dc=com
objectClass: top
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
cn: tang
sn: tang
uid: tang
userPassword: 123456
uidNumber: 1009
gidNumber: 1000
homeDirectory: /home/tang
mail: tang@vimll.com
title: add user tang
EOF

ldapadd -x -H ldap://127.0.0.1:389   -D "cn=admin,dc=vimll,dc=com" -w Tang@123456 -f usersadd.ldif

5. 为用户设置密码
ldappasswd -x -h 127.0.0.1 -p 389 -D "cn=admin,dc=vimll,dc=com" -w "Tang@123456"  "cn=tang,ou=Users,dc=vimll,dc=com"
New password: DoUGE7is

6. 搜索信息
# 搜索全部
ldapsearch -x -H ldap://127.0.0.1:389 -b "dc=vimll,dc=com" -D "cn=admin,dc=vimll,dc=com" -w Tang@123456 

# 正则匹配
ldapsearch -x -H ldap://127.0.0.1:389 -b "dc=vimll,dc=com" -D "cn=admin,dc=vimll,dc=com" -w Tang@123456  "cn=wu*"
ldapsearch -x -H ldap://127.0.0.1:389 -b "dc=vimll,dc=com" -D "cn=admin,dc=vimll,dc=com" -w Tang@123456  "ou=*"
# userPassword:: MTIzNDU2   用户密码行 可用以下命令查看用户真实密码
echo MTIzNDU2 |base64 -d

# 验证用户密码策略是否正确
ldapwhoami -x -H ldap://127.0.0.1:389   -D "cn=wuyutang,ou=Users,ou=People,dc=vimll,dc=com" -w Tang123 -e ppolicy -v

7. 删除操作
# 删除用户
ldapdelete -x -H ldap://127.0.0.1:389 -D "cn=admin,dc=vimll,dc=com" -w "Tang@123456" "cn=tang,ou=Users,dc=vimll,dc=com"
# 删除用户组
ldapdelete -x -H ldap://127.0.0.1:389 -D "cn=admin,dc=vimll,dc=com" -w "Tang@123456" "cn=users,ou=Users,ou=People,dc=vimll,dc=com"

8. modify 修改操作
cat > user-modify.ldif << EOF
dn: cn=tang,ou=Users,dc=vimll,dc=com
changetype: add
objectClass: top
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
cn: tang
sn: tang
uid: tang
userPassword: 123456
uidNumber: 1009
gidNumber: 1000
homeDirectory: /home/tang
mail: tang@vimll.com
title: add user tang
EOF

ldapmodify -x -H ldap://127.0.0.1:389 -D "cn=admin,dc=vimll,dc=com" -w "Tang@123456" -f user-modify.ldif

# 添加组织单元OU
dn: ou=Users,ou=people,dc=vimll,dc=com
changetype: add
objectClass: organizationalUnit
objectClass: top
ou: Jira

# 添加组,并关联用户admin到组
dn: cn=admin,ou=Users,ou=peoples,dc=vimll,dc=com
changetype: add
objectClass: groupOfUniqueNames
objectClass: top
cn: admin
uniqueMember: cn=admin,ou=Users,ou=People,dc=vimll,dc=com

ldapsearch -x -H ldap://127.0.0.1:389 -D "cn=admin,dc=vimll,dc=com" -w Tang@123456 -b "uid=admin,ou=People,dc=vimll,dc=com" dn uniqueMember

#  修改属性
dn: cn=tang,ou=Users,dc=vimll,dc=com
changetype: modify
replace: titletitle: this is a new title

# 添加属性
dn: cn=tang,ou=Users,dc=vimll,dc=com
changetype: add
add: description
description: this is a add description

# modrdn 修改
cat > modrdn.ldif << EOF
dn: cn=tang,ou=Users,dc=vimll,dc=com
changetype: modrdn
newrdn: cn=tang123
deleteoldrdn: 0
newsuperior: ou=Users,dc=vimll,dc=com
EOF

ldapmodify -x -H ldap://127.0.0.1:389 -D "cn=admin,dc=vimll,dc=com" -w "Tang@123456" -f modrdn.ldif

# 修改密码
cat > changepwd.ldif << EOF
dn: cn=tang123,ou=Users,dc=vimll,dc=com
changetype: modify
replace: userPassword
userPassword: Tang123
EOF

ldapmodify -x -H ldap://127.0.0.1:389 -D "cn=admin,dc=vimll,dc=com" -w "Tang@123456" -f changepwd.ldif

9. LDAP用户权限配置
## 创建顶级Manager OU并创建admins(管理),readonly(只读),password_manager(密码管理)等子ou
cat > add_manager_ou_and_sonou.ldif << EOF
dn: ou=Manager,dc=vimll,dc=com
objectClass: organizationalUnit
objectClass: top
ou: Manager

dn: ou=admins,ou=Manager,dc=vimll,dc=com
objectClass: organizationalUnit
objectClass: top
ou: admins

dn: ou=readonly,ou=Manager,dc=vimll,dc=com
objectClass: organizationalUnit
objectClass: top
ou: readonly

dn: ou=password_manager,ou=Manager,dc=vimll,dc=com
objectClass: organizationalUnit
objectClass: top
ou: password_manager
EOF

ldapadd -x -H ldap://127.0.0.1:389   -D "cn=admin,dc=vimll,dc=com" -w Tang@123456 -f add_manager_ou_and_sonou.ldif

## 配置权限
#查看确定olcDatabase配置文件, 比如我的是olcDatabase={2}mdb.ldif, 根据olcDatabase={2}mdb.ldif配置文件来确定dn位置来重新编写访问控制
# ls -l /etc/openldap/slapd.d/cn=config
......略
-rw------- 1 ldap ldap  2099 Feb 24 18:06 olcDatabase={2}mdb.ldif

cat > change-acl.ldif << EOF 
dn: olcDatabase={2}mdb,cn=config
changetype: modify
delete: olcAccess
-
add: olcAccess
olcAccess: {0}to * 
  by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage 
  by * break
olcAccess: {1}to attrs=userPassword,shadowLastChange
  by self write
  by dn="cn=admin,dc=vimll,dc=com" write
  by dn.children="ou=admins,ou=Manager,dc=vimll,dc=com" read  
  by dn.children="ou=password_manager,ou=Manager,dc=vimll,dc=com" write
  by anonymous auth
  by * none
olcAccess: {2}to *
  by self read
  by dn="cn=admin,dc=vimll,dc=com" write
  by dn.children="ou=admins,ou=Manager,dc=vimll,dc=com" write
  by dn.children="ou=password_manager,ou=Manager,dc=vimll,dc=com" read
  by dn.children="ou=readonly,ou=Manager,dc=vimll,dc=com" read
  by * none
EOF

#  对密码属性访问控制
olcAccess: {1}to attrs=userPassword,shadowLastChange
#  对全局属性访问控制(密码除外)
olcAccess: {2}to *

ldapmodify -Y EXTERNAL -H ldapi:/// -f change-acl.ldif

## 验证:分别在几个管理ou下创建对应账户,然后访问ldap,验证权限,ldif配置文件示例

cat > add_readOnly.ldif << EOF
dn: cn=readuser,ou=readonly,ou=Manager,dc=vimll,dc=com
objectClass: simpleSecurityObject
objectClass: organizationalRole
description: LDAP read only user
cn: readuser
userPassword: Readuser@123
EOF

cat > add_pwd-manager.ldif << EOF
dn: cn=pwd-manager,ou=password_manager,ou=Manager,dc=vimll,dc=com
objectClass: simpleSecurityObject
objectClass: organizationalRole
description: LDAP change-pwd only user
cn: pwd-manager
userPassword: Pwd-manager@123
EOF

cat > add_admins.ldif << EOF
dn: cn=myadmin,ou=admins,ou=Manager,dc=vimll,dc=com
objectClass: simpleSecurityObject
objectClass: organizationalRole
description: LDAP admin user
cn: myadmin
userPassword: Myadmin@123
EOF

ldapadd -x -H ldap://127.0.0.1:389   -D "cn=admin,dc=vimll,dc=com" -w Tang@123456 -f add_readOnly.ldif
ldapadd -x -H ldap://127.0.0.1:389   -D "cn=admin,dc=vimll,dc=com" -w Tang@123456 -f add_pwd-manager.ldif
ldapadd -x -H ldap://127.0.0.1:389   -D "cn=admin,dc=vimll,dc=com" -w Tang@123456 -f add_admins.ldif

10. ldap 加载额外模块
## 禁止匿名访问
cat > disable_anon.ldif << EOF
dn: cn=config
changetype: modify
add: olcDisallows
olcDisallows: bind_anon

dn: cn=config
changetype: modify
add: olcRequires
olcRequires: authc

dn: olcDatabase={-1}frontend,cn=config
changetype: modify
add: olcRequires
olcRequires: authc
EOF

ldapadd -Y EXTERNAL -H ldapi:/// -f  disable_anon.ldif

### ppolicy模块
#配置module模块
cat > module.ldif << EOF
dn: cn=module,cn=config
objectClass: olcModuleList
cn: module
olcModulepath: /usr/lib/ldap
olcModuleload: accesslog.la
olcModuleload: auditlog.la
olcModuleLoad: ppolicy.la
#olcModuleload: memberof.la
EOF
ldapadd -Y EXTERNAL -H ldapi:/// -f  module.ldif

#配置默认配置
cat > ppolicy_db.ldif << EOF
dn: olcOverlay=ppolicy,olcDatabase={1}hmdb,cn=config
changetype: add
objectClass: olcConfig
objectClass: olcOverlayConfig
objectClass: olcPPolicyConfig
olcOverlay: ppolicy
olcPPolicyDefault: cn=default,ou=Policies,dc=vimll,dc=com
olcPPolicyHashCleartext: TRUE
olcPPolicyUseLockout: TRUE
EOF

ldapadd -Y EXTERNAL -H ldapi:/// -f ppolicy_db.ldif

#创建组
cat > ppolicy_group.ldif << EOF
dn: ou=Policies,dc=vimll,dc=com
objectClass: top
objectClass: organizationalUnit
ou: Policies
EOF

ldapadd -x -H ldap://127.0.0.1:389   -D "cn=admin,dc=vimll,dc=com" -w Tang@123456 -f ppolicy_group.ldif

# 创建默认密码策略
cat > ppolicy_rulues.ldif << EOF
dn: cn=default,ou=Policies,dc=vimll,dc=com
cn: default
objectClass: top
objectClass: device
objectClass: pwdPolicy
objectClass: pwdPolicyChecker
pwdAttribute: 2.5.4.35
pwdInHistory: 8
pwdMinLength: 8
pwdMaxFailure: 3
pwdFailureCountInterval: 1800
pwdCheckQuality: 2
pwdMustChange: TRUE
pwdGraceAuthNLimit: 0
pwdMaxAge: 3600
pwdExpireWarning: 1209600
pwdLockoutDuration: 900
pwdLockout: TRUE
EOF

ldapadd -x -H ldap://127.0.0.1:389   -D "cn=admin,dc=vimll,dc=com" -w Tang@123456 -f ppolicy_rulues.ldif

#pqchecker模块
cat > pqchecker.ldif << EOF
dn: cn=default,ou=Policies,dc=vimll,dc=com
changetype: modify
add: pwdcheckmodule
pwdCheckModule: pqchecker.so
#-
#add: objectClass
#objectclass: pwdPolicyChecker
EOF

ldapadd -x -H ldap://127.0.0.1:389   -D "cn=admin,dc=vimll,dc=com" -w Tang@123456 -f pqchecker.ldif

#审核模块audit
cat > audit.ldif << EOF
dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: auditlog

dn: olcOverlay=auditlog,olcDatabase={2}mdb,cn=config
changetype: add
objectClass: olcOverlayConfig
objectClass: olcAuditLogConfig
olcAuditlogFile: /var/log/slapd/auditlog.log

dn: olcDatabase={2}mdb,cn=config
changetype: modify
add: olcAccess
olcAccess: {0}to attrs=userPassword,shadowLastChange 
  by self write 
  by dn="cn=admin,dc=vimll,dc=com" write 
  by anonymous auth by * read
olcAccess: {1}to * 
  by self write 
  by dn="cn=admin,dc=vimll,dc=com" write
  by * read
EOF

ldapadd -Y EXTERNAL -H ldapi:/// -f  audit.ldif

11. sudo 模块加载
cat > sudo-overlay.ldif << EOF
dn: cn=sudo,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: sudo
olcAttributeTypes: {0}( 1.3.6.1.4.1.15953.9.1.1 NAME 'sudoUser' DESC 'User(s) who may  run sudo' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
olcAttributeTypes: {1}( 1.3.6.1.4.1.15953.9.1.2 NAME 'sudoHost' DESC 'Host(s) who may run sudo' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
olcAttributeTypes: {2}( 1.3.6.1.4.1.15953.9.1.3 NAME 'sudoCommand' DESC 'Command(s) to be executed by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
olcAttributeTypes: {3}( 1.3.6.1.4.1.15953.9.1.4 NAME 'sudoRunAs' DESC 'User(s) impersonated by sudo (deprecated)' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
olcAttributeTypes: {4}( 1.3.6.1.4.1.15953.9.1.5 NAME 'sudoOption' DESC 'Options(s) followed by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
olcAttributeTypes: {5}( 1.3.6.1.4.1.15953.9.1.6 NAME 'sudoRunAsUser' DESC 'User(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
olcAttributeTypes: {6}( 1.3.6.1.4.1.15953.9.1.7 NAME 'sudoRunAsGroup' DESC 'Group(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
olcAttributeTypes: {7}( 1.3.6.1.4.1.15953.9.1.8 NAME 'sudoNotBefore' DESC 'Start of time interval for which the entry is valid' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )
olcAttributeTypes: {8}( 1.3.6.1.4.1.15953.9.1.9 NAME 'sudoNotAfter' DESC 'End of time interval for which the entry is valid' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )
olcAttributeTypes: {9}( 1.3.6.1.4.1.15953.9.1.10 NAME 'sudoOrder' DESC 'an integer to order the sudoRole entries' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
olcObjectClasses: {0}( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' DESC 'SudoerEntries' SUP top STRUCTURAL MUST cn MAY ( sudoUser $ sudoHost $ sudoCommand $ sudoRunAs $ sudoRunAsUser $ sudoRunAsGroup $ sudoOption $ sudoOrder $ sudoNotBefore $ sudoNotAfter $ description ) )
EOF

cat > sudo.ldif << EOF
dn: ou=SUDOers,dc=vimll,dc=com
description: SUDOers
objectClass: organizationalUnit
objectClass: top
ou: SUDOers

dn: cn=defaults,ou=SUDOers,dc=vimll,dc=com
objectClass: top
objectClass: sudoRole
cn: defaults
description: Default sudoOption's go here
sudoOption: !visiblepw
sudoOption: always_set_home
sudoOption: match_group_by_gid
sudoOption: always_query_group_plugin
sudoOption: env_reset
sudoOption: env_keep =  "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS"
sudoOption: env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
sudoOption: env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
sudoOption: env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
sudoOption: env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"
sudoOption: secure_path = /sbin:/bin:/usr/sbin:/usr/bin
sudoOrder: 1

dn: cn=%wheel,ou=SUDOers,dc=vimll,dc=com
objectClass: top
objectClass: sudoRole
cn: %wheel
sudoUser: %wheel
sudoUser: wuyutang
sudoHost: ALL
sudoRunAsUser: ALL
sudoCommand: ALL
sudoOption: !authenticate
sudoOrder: 2
EOF

ldapadd -Y EXTERNAL -H ldapi:///  -f sudo-overlay.ldif
ldapadd -x -H ldap://127.0.0.1:389   -D "cn=admin,dc=vimll,dc=com" -w Tang@123456 -f sudo.ldif

## sshPublicKey 证书模块
cat > openssh-lpk-openldap.ldif << EOF
#
# LDAP Public Key Patch schema for use with openssh-ldappubkey
#                              useful with PKA-LDAP also
#
# Author: Eric AUGE <eau@phear.org>
#
# LDIF for openLDAP Directory Server.
# Based on the original schema, modified by Jakub Jelen.
#
dn: cn=openssh-lpk,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: openssh-lpk
olcAttributeTypes: {0}( 1.3.6.1.4.1.24552.500.1.1.1.13
  NAME 'sshPublicKey' DESC 'MANDATORY: OpenSSH Public key'
  EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
olcObjectClasses: {0}( 1.3.6.1.4.1.24552.500.1.1.2.0
  NAME 'ldapPublicKey' DESC 'MANDATORY: OpenSSH LPK objectclass'
  SUP top AUXILIARY MUST ( sshPublicKey $ uid ) )
EOF

ldapadd -Y EXTERNAL -H ldapi:///  -f openssh-lpk-openldap.ldif

## 给用户添加证书
cat > mod_users.ldif << EOF
dn: cn=wuyutang,ou=Users,ou=People,dc=vimll,dc=com
changetype: modify
replace: homeDirectory
homeDirectory: /home/wuyutang
-
add: objectClass
objectClass: ldapPublicKey
-
add: sshPublicKey
sshPublicKey: ssh-rsa AAAAB3NzaC1yc2E-----------
EOF

ldapmodify -x -H ldap://127.0.0.1:389 -D "cn=admin,dc=vimll,dc=com" -w "Tang@123456" -f mod_users.ldif

三、 集成 sssd 使用
yum install -y install openldap-clients sssd sssd-client sssd-ldap sssd-tools authconfig nss-pam-ldapd oddjob-mkhomedir
echo "sudoers: file sss" >> /etc/nsswitch.conf

cat > /etc/sssd/sssd.conf << EOF
[domain/default]
debug_level = 9
autofs_provider = ldap
id_provider = ldap
auth_provider = ldap
chpass_provider = ldap

ldap_uri              = ldaps://ldap.vimll.com
ldap_search_base      = dc=vimll,dc=com
ldap_sudo_search_base = ou=sudoers,dc=vimll,dc=com
ldap_default_bind_dn  = cn=readuser,ou=readonly,ou=Manager,dc=vimll,dc=com
ldap_default_authtok  = Readuser@123

ldap_tls_reqcert = never
ldap_id_use_start_tls = False
cache_credentials = True
ldap_tls_cacertdir = /etc/openldap/cacerts

ldap_user_object_class = posixAccount
ldap_user_name = uid
ldap_user_uid_number = uidNumber
override_homedir = /home/%u
default_shell = /bin/bash
entry_cache_timeout = 120
ldap_search_timeout              = 10
ldap_network_timeout             = 10
ldap_opt_timeout                 = 10
ldap_enumeration_search_timeout  = 60
ldap_enumeration_refresh_timeout = 300
ldap_connection_expire_timeout   = 600
ldap_sudo_smart_refresh_interval = 600
ldap_sudo_full_refresh_interval  = 10800
[sssd]
services = nss, sudo, pam, autofs, ssh
config_file_version = 2
domains = default
domains = default
[nss]
homedir_substring = /home
filter_groups = root
filter_users = root
entry_negative_timeout        = 20
entry_cache_nowait_percentage = 50
[pam]
[sudo]
[autofs]
[ssh]
[pac]
[ifp]
[secrets]
[session_recording]
EOF

chmod 600 /etc/sssd/sssd.conf
systemctl enable --now  sssd oddjobd

authconfig --enablesssd --enablesssdauth --enablemkhomedir --enablerfc2307bis --enableldap --enableldapauth --disableldaptls --disableforcelegacy --disablekrb5 --ldapserver ldaps://ldap.vimll.com --ldapbasedn "dc=vimll,dc=com" --updateall

systemctl restart sssd oddjobd sshd
systemctl status sssd oddjobd sshd

# 验证
id tang;id wuyutang