[转]我花了一个五一终于搞懂了OpenLDAP
轻型目录访问协议(英文:
Lightweight Directory Access Protocol
,缩写:LDAP
)是一个开放的,中立的,工业标准的应用协议,通过IP协议提供访问控制和维护分布式信息的目录信息。
OpenLDAP
是轻型目录访问协议(Lightweight Directory Access Protocol
,LDAP
)的自由和开源的实现,在其OpenLDAP
许可证下发行,并已经被包含在众多流行的Linux
发行版中。可以这样讲:市面上只要你能够想像得到的所有工具软件,全部都支持
LDAP
协议。比如说你公司要安装一个项目管理工具,那么这个工具几乎必然支持LDAP
协议,你公司要安装一个bug
管理工具,这工具必然也支持LDAP
协议,你公司要安装一套软件版本管理工具,这工具也必然支持LDAP
协议。LDAP
协议的好处就是你公司的所有员工在所有这些工具里共享同一套用户名和密码,来人的时候新增一个用户就能自动访问所有系统,走人的时候一键删除就取消了他对所有系统的访问权限,这就是LDAP
。
有些领域并不像前端世界那么潮那么性感,但是缺了这个环节又总觉得很别扭。如果深入到运维的世界,你会发现大部分工具还活在上个世纪,产品设计完全反人类,比如cn
, dc
, dn
, ou
这样的命名方式,如果不钻研个一天两天,鬼知道它在说什么,比如说dns
,dns
是什么鬼?域名吗?不是,它只是某个懒惰的工程师起了dn
这么一个缩写,再加一个复数,就成了dns
,和域名服务器没有任何关系;cn
是什么?中国的缩写?你想多了,这和中国没有任何关系。经过一系列这样疯狂的洗脑之后,你才能逐渐明白LDAP
到底想干什么。抛弃你所有的认知,把自己当成一个什么都不懂的幼儿园孩子,然后我们从头学起LDAP
。
如果你搜索OpenLDAP
的安装指南,很不幸地告诉你,网上不管中文的英文的,90%
都是错的,它们都还活在上个世纪,它们会告诉你要去修改一个叫做slapd.conf
的文件,基本上看到这里,你就不用往下看了,这个文件早就被抛弃,新版的OpenLDAP
里根本就没有这个文件!取而代之的是slapd.d
的文件夹,然后另一部分教程会告诉你,让你修改这个文件夹下的某一个ldif
文件,看到这里,你也不用往下看了,你又看到了伪教程,因为这个文件夹下的所有文件的第一行都明确地写着:『这是一个自动生成的文件,不要修改它!
』你修改了它之后,它的md5
校验值会匹配不上,造成更多的问题。你应该用ldapmodify
来修改这个文件,而关于ldapmodify
的教程,可以说几乎就没有!我一开始不知道面临这样荒谬的处境,很多运维人员是怎么活下来的,不过等我自己配通了以后,真的是累到连写教程的精力都没有了,好吧,我已经配通了,你们各人自求多福吧。
架构
实际上,我的操作步骤很多都是反的,架构这部分是最后才意识到的,但实际上从最一开始就应该先想到。实际上整个OpenLDAP
的架构大致包含3
个部分,而网上没有教材提到这块。
OpenLDAP
首先,是OpenLDAP
的服务器本身,这个东西其实只相当于是一个mysql
数据库,它是没有酷炫的图形界面的,如果你愿意每次都手敲一大堆代码,也可以用它,但这种反人类的设计真的不是给人用的。
phpLDAPadmin
所以,你需要安装一个叫作phpLDAPadmin
的工具,好歹这是一个图形界面,虽然奇丑无比,并且配置起来也并不容易。
PWM
光装管理工具还不够,你总要给用户提供一个修改密码的地方。
客户端
最后,你还需要配置各种工具。
架构图
我画了一个简单的架构图如下:
安装
安装OpenLDAP
安装OpenLDAP
非常简单,直接安装这3
个东西就够了,甚至运气好的话,也许你的操作系统已经自带安装好了:
yum install openldap openldap-clients openldap-servers
安装完了之后可以直接启动OpenLDAP
服务,不需要做任何配置,我一开始还有顾虑,后来发现完全不用多想直接启动即可:
service slapd start
配置OpenLDAP
这一块在最一开始是最麻烦的部分,网上所有教程讲的都不对。因为现在是2018
年了,而很多教程还停留在2008
年甚至1998
年。配置OpenLDAP
最正确的姿势是通过ldapmodify
命令执行一系列自己写好的ldif文件,而不要修改任何OpenLDAP装好的配置文件。
举个例子来说,你要想修改RootDN
,那么你就自己写这么一个ldif
文件,假设给它起名叫a.ldif
,然后执行它就可以了:
dn: olcDatabase={2}bdb,cn=config
changetype: modify
replace: olcRootDN
olcRootDN: cn=admin,dc=qiban,dc=com
-
replace: olcSuffix
olcSuffix: dc=qiban,dc=com
怎么执行呢?
ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f a.ldif
这么长的命令是什么意思?-Q
表示安静执行,-Y
和后面的EXTERNAL
表示,好吧,我也不知道什么意思,总之需要这样配合,然后-H
表示地址,-f
表示文件名。几乎所有的ldapmodify
命令都这么执行就好了。
再来讲解一下上面的ldif
文件的内容,你不要问为什么叫ldif
这么一个破后缀,总之你记住它就是这个后缀就好了。dn
表示你要修改什么东西,在这里我们用的是{2}bdb
,你的系统不一定是{2}bdb
,不管是几,总之你去查一下目录里的内容就好了:
ls /etc/openldap/slapd.d/cn=config/
得到的结果大概如下,不一样也不要害怕:
cn=module{0}.ldif cn=schema/ cn=schema.ldif olcDatabase={0}config.ldif olcDatabase={-1}frontend.ldif olcDatabase={1}monitor.ldif olcDatabase={2}bdb/ olcDatabase={2}bdb.ldif
这里面有一大堆奇奇怪怪的数字,不要担心,其中有一个带什么db.ldif
的就是你最终需要修改的数据库文件,我这里是bdb.ldif
,你的可能是mdb.ldif
,还有人是hdb.ldif
,不管什么db
,总之你要改的是一个叫db
的文件就对了,你可以cat
打开看一看,但是不要用vi
去修改它。
changetype
就是modify
,表示我们要修改这个文件。第3
行是replace
,表示我们要替换里面的某个值,你可以把这个操作理解为mysql
数据库的update
操作,如果你把第3
行改成add
,那就是mysql
的insert
操作了。不过这里我们操作的只是配置文件本身,还牵涉不到添加用户或者更改用户,如果你以为事情就这么简单,那就是你太天真了。
RootDN
在这里就表示你整个OpenLDAP
系统的管理员用户名是什么,不要奇怪,后面这一砣都是用户名cn=admin,dc=qiban,dc=com
,长的有点像email
地址,实际意思也差不多,但总之就不是email
就行了。不要问为什么,总之cn
就是email
前面的那个名字,后面带dc
的都是域名。
真实情况是你还需要给这个用户设置一个密码,具体怎么设自行Google
,但还是那句话:不要修改系统文件,要用ldapmodify来执行。
添加memberOf模块
这个工作应该一开始就做好,要不然后面要做的话,还得把建好的组全删掉再重建。这个模块的作用是当你建一个组的时候,把一些用户添加到这个组里去,它会自动给这些用户添加一个memberOf
属性,有很多应用需要检查这个属性。
添加的时候比较麻烦,需要建3
个ldif
文件,然后1
个执行ldapmodify
,2
个执行ldapadd
,错一点都不行:
memberof_config.ldif
再一次重申:文件名叫做什么根本无所谓,只要后缀名为ldif
即可。
dn: cn=module,cn=config
cn: module
objectClass: olcModuleList
olcModuleLoad: memberof
olcModulePath: /usr/lib64/openldap
dn: olcOverlay={0}memberof,olcDatabase={2}bdb,cn=config
objectClass: olcConfig
objectClass: olcMemberOf
objectClass: olcOverlayConfig
objectClass: top
olcOverlay: memberof
olcMemberOfDangling: ignore
olcMemberOfRefInt: TRUE
olcMemberOfGroupOC: groupOfNames
olcMemberOfMemberAD: member
olcMemberOfMemberOfAD: memberOf
小心第5
行和第7
行,先找到你的模块目录是不是在/usr/lib64
下面,然后看清楚你的数据库类型和数字,不要瞎复制。
对于这个文件,我们需要执行ldapadd
:
ldapadd -Q -Y EXTERNAL -H ldapi:/// -f memberof_config.ldif
执行完之后,检查你的/etc/openldap/slapd.d/cn=config/
,看是不是多了一个模块,这个模块的数字编号直接影响下一步操作。
refint1.ldif
dn: cn=module{0},cn=config
add: olcmoduleload
olcmoduleload: refint
这个文件里我的memberOf
是第一个模块,所以编号是0
,你的不一定,要看清楚到底第几号模块是memberof
,然后就改成几就可以了,对于这个文件,我们要执行ldapmodify
操作:
ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f refint1.ldif
你如果能看懂它的意思的话,它的大意是说要修改我们刚刚添加的那个模块文件的内容。
refint2.ldif
dn: olcOverlay={1}refint,olcDatabase={2}bdb,cn=config
objectClass: olcConfig
objectClass: olcOverlayConfig
objectClass: olcRefintConfig
objectClass: top
olcOverlay: {1}refint
olcRefintAttribute: memberof member manager owner
对这个文件执行ldapadd
操作:
ldapadd -Q -Y EXTERNAL -H ldapi:/// -f refint2.ldif
还是要注意检查db
类型,否则你一定不能成功。
安装phpLDAPadmin
好吧,干完了上面这些啰里巴嗦的事情,你可以先给自己泡杯咖啡,接下来还有很多工作要做,不过难度已经没有刚才那么大了。
我们开始安装phpLDAPadmin
。
yum install phpldapadmin
CentOS
的yum
安装总是这么令人赏心悦目。
配置phpLDAPadmin
接下来让我们在nginx
里配置好它,以便让我们的管理员能够看到它。
location /htdocs {
alias /usr/share/phpldapadmin/htdocs;
index index.php;
location ~ \.php$ {
alias /usr/share/phpldapadmin;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
缺省文件安装在/usr/share/phpldapadmin/htdocs
下,我们必得要在这里配置一个alias
才能访问到它,但在php-fpm
时又要配置另外一个alias
,这也是比较坑人的一个地方。
接下来你需要修改/etc/phpldapadmin/config.php
这个文件,里面有大段大段的注释,看到人头晕,注意这么2
点就够了,其它的都不要改:
- 把
$servers->setValue('login','anon_bind',false);
改成false
,因为我们不想让人匿名访问; - 把
$servers->setValue('login','allowed_dns',array('cn=admin,dc=qiban,dc=com'));
,我们只允许管理员访问,其他任何人不得访问。
使用phpLDAPadmin
你现在可以通过URL
地址访问phpLDAPadmin
了,登录的时候输入你那一坨用户名:cn=admin,dc=qiban,dc=com
,然后输入密码,如果你前面一切都设置对了,那么这里就可以登录进去了。
界面里透出一股浓浓的上世纪九十年代风格,不过好歹我们终于可以脱离纯手写代码管理的窘境了。
这时候你首先要建立两个organizationalUnit
,一个叫作groups
,一个叫作users
。不要问为什么。
然后在users
下面建几个inetOrgPerson
,这些就是你的用户了。注意,在创建新条目时,一定要选择默认
,不要选择什么Posix
或者Generic User Account
,那只会帮你建出一堆没用的Linux
账号出来,我们只想要web
用户,不想建什么Linux
用户。注意:密码这个地方一定要选md5
,否则你后面和其它系统连接会出问题。
然后在groups
下面建几个组吧,比如admins
, users
等等,注意选择objectClass
为groupOfNames
就行了。然后把你刚刚建好的几个用户分门别类的给他们加到组里去。
在这一步上,如果你前面配置memberOf
模块配置正确的话,你会在user
的显示内部属性
里看到它的memberOf
属性,如果看不到,说明你没有配对。
配置第三方应用
到此为止,似乎真没有什么好说的了,Phabricator
, Confluence
, Zabbix
, Grafana
, 禅道
等等,几乎你能想到的任何一个第三方应用都会有说明书教你怎么配置dc
, cn
, ou
这些东西,经过了上面这一番折腾,你怎么着也应该对LDAP
的一些术语有所了解了,如果还是不行,说明你玩它的时间还是不够长,再多玩两天,也就明白了。
配置好之后的好处就是你再也不用东一块西一块地建用户了,而可以在一个统一的地方集中管理你的用户和群组授权。
结语
总之,配置OpenLDAP
不是一个轻松的活,但是考虑到有那么多第三方应用都支持这个鬼东西,花点代价把它配通还是值得的。希望你一切顺利。
[转]我花了一个五一终于搞懂了OpenLDAP的更多相关文章
- 终于搞懂了vue 的 render 函数(一) -_-|||
终于搞懂了vue 的 render 函数(一) -_-|||:https://blog.csdn.net/sansan_7957/article/details/83014838 render: h ...
- 探索JAVA并发 - 终于搞懂了sleep/wait/notify/notifyAll
> sleep/wait/notify/notifyAll分别有什么作用?它们的区别是什么?wait时为什么要放在循环里而不能直接用if? ## 简介 首先对几个相关的方法做个简单解释,Obje ...
- 终于搞懂了PR曲线
PR(Precision Recall)曲线 问题 最近项目中遇到一个比较有意思的问题, 如下所示为: 图中的PR曲线很奇怪, 左边从1突然变到0. PR源码分析 为了搞清楚这个问题, 对源码进行了分 ...
- Java 多态 ——一个案例 彻底搞懂它
最近,发现基础真的hin重要.比如,Java中多态的特性,在学习中就是很难懂,比较抽象的概念.学的时候就犯糊涂,但日后会发现,基础在日常工作的理解中占有重要的角色. 下面,我将用一个代码实例,回忆和巩 ...
- Lua的闭包详解(终于搞懂了)
词法定界:当一个函数内嵌套另一个函数的时候,内函数可以访问外部函数的局部变量,这种特征叫做词法定界 table.sort(names,functin (n1,n2) return grades[n1] ...
- 终于搞懂了shell bash cmd...
问题一:DOS与windows中cmd区别 在windows系统中,“开始-运行-cmd”可以打开“cmd.exe”,进行命令行操作. 操作系统可以分成核心(kernel)和Shell(外壳)两部分, ...
- IntelliJ IDEA 部署 Web 项目,终于搞懂了!
这篇牛逼: IDEA 中最重要的各种设置项,就是这个 Project Structre 了,关乎你的项目运行,缺胳膊少腿都不行. 最近公司正好也是用之前自己比较熟悉的IDEA而不是Eclipse,为了 ...
- 终于搞懂Spring中Scope为Request和Session的Bean了
之前只是很模糊的知道其意思,在request scope中,每个request创建一个新的bean,在session scope中,同一session中的bean都是一样的 但是不知道怎么用代码去验证 ...
- (鸡汤文)这一次我终于搞懂了 JavaScript 定时器的 this 指向!
开篇语 忽然有一种感觉,每次学习一个知识点就像是谈一场恋爱:从初次邂逅,到彼此了解,一切都那么的符合恋爱的过程! 如果这个知识点再有点"调皮"的话,那简直是让人欲仙欲死而又不可自拔 ...
随机推荐
- SQL注入备忘录
备忘录(一) 拿起小本本记下常考知识点. 常用连接词 and && %23%23 且 or || %7c%7c 或 xor 非 Access 数据库: 只能爆破表名.列名获取数据.无法 ...
- eclipse 背景颜色
步骤阅读 3 本例使用的背景色是喜大普奔的豆沙绿,比较柔和 设置为:色调:85.饱和度:120.亮度:208 即可,据说长时间使用可以缓解眼疲劳哦. (吐槽:开什么玩笑,远离编程才能缓解眼疲劳好吗)
- Revit二次开发示例:CancelSave
在Revit程序中注册文件操作事件,保存新建或打开文件的信息.当保存时,如果当前文件内容和之前的一致时,则弹出对话框提示并取消保存.对话框中有一个功能链接,点击可打开插件所在目录. #region N ...
- 2018haoi总结
AM T1 写了40分,有50分的暴力分,只看到n=1能用费马小定理,没看到还有一个mod质数也能用费马小定理的10分. AM T2 写了10分,60分异或方程求自由元. AM T3 现在还没搞清楚题 ...
- KMP 理解
例题 以字符串 ABABACA 为例 a 前缀: 后缀: 结果为0 ab 前缀:a 后缀: b 结果为0 aba 前缀:a ab 后缀: ba a 结果为1,此时 i=2,j=1 abab 前缀:a ...
- FindWindow和FindWindowEx
函数原型:FindWindow(lpszClassName,lpszWindowName) 参数:lpszClassName--窗口类名;lpszWindowName--窗口标题 功能:查找窗口,未找 ...
- MyTalkStuffHomeIcon-2
圆形.高清头像素材专用-2
- .NET面试宝典-高级(一)
1. DateTime.Parse(myString); 这段代码有什么问题? A:区域信息即CultureInfo没有指定.如果不指定的话,它将采用默认的机器级的设置(见:控制面板->区域和语 ...
- Set常用子类特点
HashSet: 重写 hashCode和equals方法 特点:无序,唯一 底层结构是: ...
- JTAG Level Translation
http://www.freelabs.com/~whitis/electronics/jtag/ One of the big issues in making a JTAG pod is leve ...