本文发布于Cylon的收藏册,转载请著名原文链接~
生产服务器硬件配置需求
ldap服务对系统环境的要求不高,一般在生产场景,ldap服务应该最少是两台,这样某一台物理服务器岩机才不会因单点问题影响生产业务故障,对于硬件要求,本质上openldap使用硬件资源并不大,网上有两个帖子提出了openldap的硬件需求:
- 2003年openldap官网留言,我想安装一个 LDAP 服务器来验证邮件服务器的用户,目前有200个用户需要多少内存和CPU?[1]
- 1GHZ PIII/512MB 足以
- 运行于Ubuntu LXC 之上的openldap,用户150,000,sladp进程常驻内存为200-300MB,mdb数据库文件大小为377MB,10 并发平均响应时间为 9-11 毫秒 [13]
操作系统:Centos7/8 64bit。
操 作 系 统 | 其 它 |
---|---|
CentOS-7.6 | 当前很稳定且免费的Linux版本。 |
网卡及IP资源
名 称 | 接 口 | IP | 用途 |
---|---|---|---|
ldap主服务器01 | eth0 | 10.0.0.17 | 外部管理IP,用于WAN数据转发。 |
eth1 | 10.0.0.17 | 备用管理IP,用于LAN内数据转发。 | |
ldap从服务器02 | eth0 | 10.0.0.8 | 管理IP,用于LAN数据转发。 |
eth1 | 10.0.0.18 | 外部管理IP,用于WAN数据转发。 |
Tips:内外网IP分配可采用最后8位相同的方式,这样使于管理。
openldap master服务安装
CentOS/Redhat 安装OpenLDAP组件
yum install -y \
openldap \
openldap-servers \
openldap-clients \
openldap-devel \
compat-openldap
Ubuntu18.04/22.04/20.04
sudo apt -y install slapd ldap-utils
默认OpenLDAP服务所使用的端口为389,此端口采用明文传输数据,数据信息得不到保障。所以可以通过配置CA及结合TLS/SASL实现数据加密传输,所使用端口为636。
编译安装
yum install -y \
libtool-ltdl \
libtool-ltdl-devel \
gcc \
openssl \
openssl-devel
Openldap依赖的相关软件:
openldap参数配置优化
openldap配置文件分为五部分
- sladp进程配置部分
- frontend:是一个特殊的
olcDatabaseConfig
配置提供权限认证 - database:存储的真实引擎
- backend:backend在slapd中不是真是的数据库,而是提供的一种转发方式
openldap目录布局
/etc/openldap/slapd.d/*
:/etc/openldap/slapd.ldif
配置信息生成的文件,每修改一次配置信息,这里的东西就要重新生成。/var/lib/ldap/*
:OpenLDAP的数据文件。/usr/share/openldap-servers/DB_CONFIG.example
:模板数据库配置文件。/usr/share/openldap-servers/slapd.ldif
:默认模板配置文件。
默认OpenLdap服务所使用的端口为389,此端口采用明文传输数据,数据信息得不到保障。所以可以通过配置CA及结合TLS/SSL实现数据加密传输,所使用端口为636。
cp /usr/share/openldap-servers/slapd.ldif /etc/openldap/
指定密码,不提示
$ slappasswd -s 111
{SSHA}QnB7dO98+hoCUgiaAYaiJWnDzlhn2Tn6
# 指定要搜索的后缀
olcSuffix: dc=cylon,dc=org
# rootdn,使用这个dn可以登录服务器
olcRootDN: cn=admin,dc=cylon,dc=org
olcDbDirectory: /var/lib/ldap
# 指定ldapserver管理员密码==
olcRootPW: {SSHA}QnB7dO98+hoCUgiaAYaiJWnDzlhn2Tn6
日志及缓存参数。
# 设置日志级别,记录日志信息方便调试 stats 256(日志连接/操作/结果)
olcLogLevel: stats
# 设置ldap可以缓存的记录数
olcDbCacheSize: 1000
# checkpoint 可以吧内存中的数据写会数据文件的操作,此设置表示每达到2048kb或者10分钟执行一次
olcDbCheckpoint: 1024 10
开启扩展schema
openldap自带一些ldif文件 [10],LDIF 是 LDAP Data Interchange Format 的缩写,是作为存储与LDAP中 ” 文本格式 “ 的数据交换格式,每个条目代表的存入LDAP中记录的属性,记录之间用空行分隔,每行都是 “属性:值” 的格式,例如我们存入LDAP中一个记录,其属性有
- dn (distinguished name) 用于标识目录中名称的唯一标识符
- dc (domain component) 表示域组成,例如域名
www.mydomain.com
那么dc 应该配置为DC=www,DC=mydomain,DC=com
- ou (organizational unit) 这是指用户的组织,这里也可以代表用户组,例如
OU=Lawyer,OU=Developer
- cn (common name) 表示查询的个体对象的名称,这里可以代表用户名,服务名等,例如
cn=cylon
具有多个属性条目,在ldap中代表一条记录,例如
dn: cn=The Postmaster,dc=example,dc=com
objectClass: organizationalRole
cn: The Postmaster
而ldif文件就是定义这些属性的文件,下面是openldap安装后默认的ldif文件说明:
-
collective.ldif
:Collective Attribute 组成LDAP条目的共享属性 -
corba.ldif
:Common Object Request Broker Architecture 的缩写,旨在促进部署在不同平台上的系统的通信 [2] -
cosine.ldif
:Cooperation for Open Systems Interconnection Networking in Europe的缩写,用于给cosine
与Internet X.500
模式项目提供LDAP中的属性格式 [3] -
duaconf.ldif
:Directory User Agents 的缩写,DUA是协议客户端,是向ldap或Internet X.500
DSA发起请求的一端,这是为DUA客户端提供了通用配置 [4] -
dyngroup.ldif
:Dynamic Group的缩写,动态组是LDAP中的一种组,与静态组相反,DG是以URL形式为搜索条件来隐式定义一组用户。[5]- 静态组 Static Groups 使用一组DN显式定义一组用户
-
inetorgperson.ldif
:inetOrgPerson类是RFC2798中
定义的类。在LDAP中为 user 的父类,比如说用户密码,登录时间等属性,更多可以参考 [6] -
java.ldif
:用于java的一些属性 -
misc.ldif
:Miscellaneous 的简写,这里主要是一些电子邮件相关属性 -
nis.ldif
:Network Information Service 的缩写,NIS是一种发现机制,这里是一种server-client的目录属性,例如网络中的主机名,用户名之类 [7] -
openldap.ldif
: -
pmi.ldif
:Privilege Management Infrastructure 的缩写,是基于x.509的授权访问控制模型,这里是提供了基于PMI的一些属性 -
ppolicy.ldif
:password policy 的缩写,提供了增强的密码管理功能,例如账户到期时间,锁定等
include: file:///etc/openldap/schema/collective.ldif # OpenLDAP的核心schema必须
include: file:///etc/openldap/schema/corba.ldif #
include: file:///etc/openldap/schema/cosine.ldif
include: file:///etc/openldap/schema/duaconf.ldif
include: file:///etc/openldap/schema/dyngroup.ldif
include: file:///etc/openldap/schema/inetorgperson.ldif
include: file:///etc/openldap/schema/java.ldif
include: file:///etc/openldap/schema/misc.ldif
include: file:///etc/openldap/schema/nis.ldif
include: file:///etc/openldap/schema/openldap.ldif
include: file:///etc/openldap/schema/pmi.ldif
include: file:///etc/openldap/schema/ppolicy.ldif
授权及安全参数配置
access to dn="cn=subschema" by * read
access to
by self write
by dn subtree="ou=sysusers,dc=test,dc=com" read
by anonymous auth
关于更多权限管理的说明,可以参考官方手册第八章 [12]
提示:
参数在文件中的先后位置不能随意动。
空行和以“#”开头的注释行将被忽略。如果一行以空格开头,它将被认为是接着前一行的(即使前一行是注释)。
配置syslog记录ldap服务日志配置syslog
记录ldap服务日志,默认级别为256;
echo 'local4.* /var/log/slapd.log' >> /etc/rsyslog.conf
local4.* /var/log/slapd.log
配置LDAP数据库存放路径
注意:
slapd.conf中设定了LDAP数据库格式为hdb,存储路径
/var/1ib/ldap
cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
chown ldap.ldap /var/lib/ldap/DB_CONFIG
chmod 700 /var/lib/ldap/DB_CONFIG
整合的配置
#
# See slapd-config(5) for details on configuration options.
# This file should NOT be world readable.
#
dn: cn=config
objectClass: olcGlobal
cn: config
olcArgsFile: /var/run/openldap/slapd.args
olcPidFile: /var/run/openldap/slapd.pid
olcLogLevel: stats
olcDisallows: bind_anon
#
# TLS settings
#
olcTLSCACertificatePath: /etc/openldap/certs
olcTLSCertificateFile: "OpenLDAP Server"
olcTLSCertificateKeyFile: /etc/openldap/certs/password
#
# Do not enable referrals until AFTER you have a working directory
# service AND an understanding of referrals.
#
#olcReferral: ldap://root.openldap.org
#
# Sample security restrictions
# Require integrity protection (prevent hijacking)
# Require 112-bit (3DES or better) encryption for updates
# Require 64-bit encryption for simple bind
#
#olcSecurity: ssf=1 update_ssf=112 simple_bind=64
#
# Load dynamic backend modules:
# - modulepath is architecture dependent value (32/64-bit system)
# - back_sql.la backend requires openldap-servers-sql package
# - dyngroup.la and dynlist.la cannot be used at the same time
#
#dn: cn=module,cn=config
#objectClass: olcModuleList
#cn: module
#olcModulepath: /usr/lib/openldap
#olcModulepath: /usr/lib64/openldap
#olcModuleload: accesslog.la
#olcModuleload: auditlog.la
#olcModuleload: back_dnssrv.la
#olcModuleload: back_ldap.la
#olcModuleload: back_mdb.la
#olcModuleload: back_meta.la
#olcModuleload: back_null.la
#olcModuleload: back_passwd.la
#olcModuleload: back_relay.la
#olcModuleload: back_shell.la
#olcModuleload: back_sock.la
#olcModuleload: collect.la
#olcModuleload: constraint.la
#olcModuleload: dds.la
#olcModuleload: deref.la
#olcModuleload: dyngroup.la
#olcModuleload: dynlist.la
#olcModuleload: memberof.la
#olcModuleload: pcache.la
#olcModuleload: ppolicy.la
#olcModuleload: refint.la
#olcModuleload: retcode.la
#olcModuleload: rwm.la
#olcModuleload: seqmod.la
#olcModuleload: smbk5pwd.la
#olcModuleload: sssvlv.la
#olcModuleload: syncprov.la
#olcModuleload: translucent.la
#olcModuleload: unique.la
#olcModuleload: valsort.la
#
# Schema settings
#
dn: cn=schema,cn=config
objectClass: olcSchemaConfig
cn: schema
include: file:///etc/openldap/schema/core.ldif
include: file:///etc/openldap/schema/collective.ldif
include: file:///etc/openldap/schema/corba.ldif
include: file:///etc/openldap/schema/cosine.ldif
include: file:///etc/openldap/schema/duaconf.ldif
include: file:///etc/openldap/schema/dyngroup.ldif
include: file:///etc/openldap/schema/inetorgperson.ldif
include: file:///etc/openldap/schema/java.ldif
include: file:///etc/openldap/schema/misc.ldif
include: file:///etc/openldap/schema/nis.ldif
include: file:///etc/openldap/schema/openldap.ldif
include: file:///etc/openldap/schema/pmi.ldif
include: file:///etc/openldap/schema/ppolicy.ldif
#
# Frontend settings
#
# 这里是对前端权限的配置,通常默认,不添加权限
dn: olcDatabase=frontend,cn=config
objectClass: olcDatabaseConfig
objectClass: olcFrontendConfig
olcDatabase: frontend
#
# Sample global access control policy:
# Root DSE: allow anyone to read it
# Subschema (sub)entry DSE: allow anyone to read it
# Other DSEs:
# Allow self write access
# Allow authenticated users read access
# Allow anonymous users to authenticate
#
#olcAccess: to dn.base="" by * read
#olcAccess: to dn.base="cn=Subschema" by * read
#olcAccess: to *
# by self write
# by users read
# by anonymous auth
#
# if no access controls are present, the default policy
# allows anyone and everyone to read anything but restricts
# updates to rootdn. (e.g., "access to * by * read")
#
# rootdn can always read and write EVERYTHING!
#
#
# Configuration database
#
# 这里是对后端数据库权限的配置
dn: olcDatabase=config,cn=config
objectClass: olcDatabaseConfig
olcDatabase: config
olcAccess: to attrs=userPassword,shadowLastChange
by dn.children="cn=admin,dc=test,dc=com" write
by anonymous auth
by self write
by * none
olcAccess: to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
by group.exact="cn=configadmin,ou=admin,dc=seal,dc=com" write
by * none
#
# Server status monitoring
#
dn: olcDatabase=monitor,cn=config
objectClass: olcDatabaseConfig
olcDatabase: monitor
olcAccess: to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,c
n=auth" read by dn.base="cn=Manager,dc=my-domain,dc=com" read by * none
#
# Backend database definitions
#
# 这里是数据库的参数配置
dn: olcDatabase=mdb,cn=config
objectClass: olcDatabaseConfig
# 使用的数据库引擎是mdb
objectClass: olcMdbConfig
olcDatabase: mdb
# Suffix 为数据库的后缀,每个数据库至少一个,在搜索时-D 后面的域后缀为dc=test,dc=com将被pass到这里
olcSuffix: dc=test,dc=com
# 指不收前面配置的权限控制的管理员账户,拥有最最高权限
olcRootDN: cn=admin,dc=test,dc=com
# 特权账户的登录密码
olcRootPW: {SSHA}xU9xFym/s7rawpmzpsYE+Q1qPsVPOwDw
olcDbDirectory: /var/lib/ldap
# 这是索引属性,下面是默认的属性
# 下列注释行意思为
# olcDbIndex: default pres,eq
# olcDbIndex: uid
# olcDbIndex: cn,sn pres,eq,sub
# olcDbIndex: objectClass eq
# pres,eq 为 present equality
# 第二行意思为,为uid属性类型维护默认索引集
# 第三行意思为,为cn,sn属性维护pres,eq,sub索引集
# 索引集类型有 pres,eq,approx,sub,none
olcDbIndex: objectClass eq,pres
olcDbIndex: uid,ou,cn,mail,surname,givenname eq,pres,sub
# 配置从缓冲区写入磁盘的,两个参数分别为多少kbyte大小的数据自上次(第二个参数)分钟则发生一次写入
olcDbCheckpoint: 1024 10
更多配置文件选项说明可以参考 [14]
生成配置文件
修改配置文件后需要重新生成配置文件
slapadd -n 0 -F /etc/openldap/slapd.d -l /etc/openldap/slapd.ldif
生成配置文件时的错误
$ slapadd -n 0 -F /etc/openldap/slapd.d -l /etc/openldap/slapd.ldif
63678619 str2entry: entry -1 has no dn
slapadd: could not parse entry (line=31)
_######## 43.66% eta none elapsed none spd 7.0 M/s
对于 slapd.ldif
需要注意下列事项
- 行首
#
为注释 - 行尾不能有任何空白,这里也是很难排查的一个点
- 对于不同的属性需要放对位置快否则会报错,例如
olcDbCacheSize: 1000
是hdb配置,mdb添加会报错,有明显提示 - 如果生产配置失败后,修改配置文件后再次生成需要删除
rm -fr slapd.d/*
例如下面就是一个有提示的典型例子
63678513 Entry (cn=config), attribute 'olcDbCacheSize' not allowed
slapadd: dn="cn=config" (line=1): (65) attribute 'olcDbCacheSize' not allowed
下面的报错比较不明显,通常删除 rm -fr slapd.d/*
后重试
slapadd: could not add entry dn="cn=config" (line=1):
_### 17.92% eta none elapsed none spd 6.3 M/s
为LDAP初始化数据
部署完成后就是访问,ldap了,此时向OpenLDAP 搜索会发现没有内容
$ ldapsearch -LLL -x -W -H ldap://10.0.0.4 -D "cn=admin,dc=test,dc=com" -b "dc=test,dc=com" "(uid=*)"
Enter LDAP Password:
No such object (32)
Reference
创建Root条目
在第一次部署好openldap中,实际上是没有任何条目的,此时是无法存入数据,有人说在 database setting中配置了 olcRootDN
,这里是指标识用哪个数据库的(即那个root存入哪里),而不是一个具体的root dn,所以需要手动创建一个
例如下列,是创建一个RootDN
cat << EOF | ldapadd -x -H ldap://10.0.0.3 -D "cn=admin,dc=test,dc=com" -w 111
dn: dc=test,dc=com
objectclass: top
objectClass: organizationalUnit
objectclass: extensibleObject
description: US Organization
ou: people
EOF
这里需要注意几点:
dn: dc=test,dc=com
是指定存储的地方,如果在database配置中为配置olcRootDN
则报错不会被存储- 由于创建的的是root,所以ou的
objectClass
会报错,需要用一个extensibleObject
才可以创建 [15]
创建子域
此时因为有了RootDN,可以指定dn为子域了,并且 objectClass: organizationalUnit
可以单独使用
这里子域其实可以理解为二级域名了,在公司中也可以为子公司
cat << EOF | ldapadd -x -H ldap://10.0.0.3 -D "cn=admin,dc=test,dc=com" -w 111
dn: ou=group,dc=test,dc=com
objectClass: organizationalUnit
ou: group
EOF
创建组
这里使用 posixGroup
Portable Operating System Interface of UNIX 的简写,这里可以理解为Linux用户管理的标准,包含一些标准的属性,类似于 /etc/group
下面创建一个gid为10001的组,组名为tech
cat << EOF | ldapadd -x -H ldap://10.0.0.3 -D "cn=admin,dc=test,dc=com" -w 111
dn: cn=tech,ou=group,dc=test,dc=com
objectClass: posixGroup
gidNumber: 10001
cn: tech
EOF
创建用户
创建用户user01
cat << EOF | ldapadd -x -H ldap://10.0.0.3 -D "cn=admin,dc=test,dc=com" -w 111
dn: uid=user01,ou=Group,dc=test,dc=com
objectClass: posixAccount
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
homeDirectory: /home/user01
loginShell: /bin/bash
uid: user01
cn: user01
uidNumber: 10004
gidNumber: 10001
userPassword: {SSHA}hJpIIVxj1qS9g05qUlgG+o7MO14EXbFQ
sn: user01
givenName: user01
创建用户cylon
cat << EOF | ldapadd -x -H ldap://10.0.0.3 -D "cn=admin,dc=test,dc=com" -w 111
dn: uid=cylon,ou=Group,dc=test,dc=com
objectClass: posixAccount
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
homeDirectory: /home/cylon
loginShell: /bin/bash
uid: cylon
cn: cylon
userPassword: {SSHA}2pvE4C6xy8dkmW2aD/eEocVajg8BujWW
uidNumber: 10005
gidNumber: 10001
sn: cylon
EOF
如上面所示,objectClass
[11] 表示这个ldap条目拥有的属性,可以看到 posixAccount
,inetOrgPerson
等都是导入的schema文件,其中 uidNumber
,userPassword
都是 NIS 定义的,cn
则是 core定义的
提示:
- 以上信息中ldap
- 用户1:user01密码
111
- 用户2:cylon 密码
123456
- 这些原始信息是如何获得的?
检查初始化测试数据。
查询导入的结果,默认查的是所有数据
ldapsearch -LLL -w 111 -x -H ldap://10.0.0.3 -D "cn=admin,dc=test,dc=com" -b "dc=test,dc=com"
备份ldap数据库数据
ldapadd -x -H ldap://cylon.org -D "cn=admin,dc=cylon,dc=org" -W -f base.ldif >base.ldif
ldapadd -x -H ldap://cylon.org -D "cn=admin,dc=cylon,dc=org" -W -f test.ldif >test.ldif
Reference
[1] msg00281
[2] Object Request Broker Architecture
[3] Cooperation for Open Systems Interconnection Networking in Europe
[4] DUA
[5] DynamicGroup
[6] InetOrgPerson
[7] Network Information Service
[8] Privilege Management Infrastructure
[9] Password Policy
[10] LDAP Data Interchange Format
[11] Object Class
[12] 8. Access Control
[13] openldap system requirements for virtualization
[14] slapdconf2
本文发布于Cylon的收藏册,转载请著名原文链接~
链接:https://www.oomkill.com/2019/08/ch2-install/
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」 许可协议进行许可。