用PHP通过LDAP操作活动目录(AD)的笔记
首先,是安装配置AD本身的这部分工作:
主要包括:装Win2k3(或2008哈),建立域控制器,建DNS服务,把要加入域的几个机器加进域来,然后建设OU(放用户的OU及放计算机的OU),建立安全组(我用它来限制哪些用户可以登录哪些计算机),设立组策略并应用到各OU等。
这部分内容的文章很多,微软给的文档就足够详细了,比如这个Step by Step的教程:http://www.microsoft.com/china/technet/prodtechnol/windowsserver2003/technologies/directory/activedirectory/stepbystep/default.mspx
(ps.这中间在密码策略上浪费了大量时间,后来才弄清一个域中只能在根下设置密码策略,就算把带有密码策略的组策略应用在OU上,也是无效的。2008里已经可以针对安全组甚至用户设置独立的密码策略了,期待~~)
然后是一些为了就乎linux的准备工作:
先去http://www.microsoft.com/windowsserversystem/sfu/downloads/default.mspx下载一套Windows Services for UNIX,这个装上以后AD里用户的属性页里会出现一个UNIX属于页,有uid,gid什么的,这是为了让linux能结合AD验证用户登录的(比如pam),我目前没用上,不过装它没坏处。
还有是要建立一个proxyuser,这个user是ldap客户端连AD时登录用的,想让PHP实现对AD的什么操作,就给这个proxyuser赋予什么权限。
这里推荐一套很好的文档,是微软的Windows Security and Directory Services for UNIX Guide(还是要pf一下m$,文档就是全,这里对linux中安全体系的介绍比专方介绍的文档都详细。。。)
下面就是资料不好找的工作啦,一步一步来:
1.关于AD与ldap的符合性。AD被做成基本符合ldap的模式,每个用户和计算机或是组什么的都有一个DN,形如CN=loudly,OU=bbs,DC=bdwm,DC=net这样子,而用户的每个属性就是这条记录里的一个attribute,所以可以用ldap_search(),ldap_add()这些标准的函数来操作AD。一个特殊但是关键的地方就是用户的密码,很不易地找到这两个文档介绍这个事情:
How To Change a Windows 2000 User's Password Through LDAP
User Management with Active Directory—LDAP Password Modification
文章中的核心内容就是:用户的密码是一个叫unicodePwd的属性表示的,这个属于只能写不能读,写的时候的格式是用一对双引号括起密码原文,再编码为unicode传给它,还有,要想改用户密码,必须是通过SSL方式连接LDAP(636端口,而不是普通的389端口)。因为如上要求,就要有以下步骤的工作了。
2.生成根证书
用SSL的话嘛,就需要证书。可以在域控制器上开启认证服务来创建企业的CA(注意这个服务开启后域的设置就不能改了,包括域名,这个机器的名等,所以要在进行这步之前设置好)。这里要做的就是创建CA,然后验证一下是不是ok的。其实这部分内容我也不懂,主要就是照着下面两篇参考着做的,具体步骤怎么回事(尤其是验证的时候)我也不知道是在做什么。
a.Install an enterprise root certification authority
b.就是上面提到的Windows Security and Directory Services for UNIX Guide第二卷的第Chapter4的Build a Certification Authority那一节
如果不自己建CA,而是从别处获得CA,那就看下面这篇:
c.How to enable LDAP over SSL with a third-party certification authority
下面这篇也可以参考,不过该文的主题是别的
d.如何在 Windows 2000 域控制器中配置数字证书来确保 LDAP 和 SMTP 复制的安全
上面的工作做好后,如果正常,那么域控制器就会开始listen 636端口,也就可以通过SSL连AD了(一般ldap客户端的规矩是:连的时候直接写DC地址就是用非加密方法连,连的时候如果写ldaps://地址,就是用SSL方法连接DC)
3.LDAP客户端的配置
客户端,就是要去连AD的机器,也就是本文中跑着PHP的那个机器,要做的工作主要是把DC上的CA导出成.cer,然后拷到客户端上来,然后转化为.pem(可是我的.cer和.pem文件是一样的)放到某个位置,然后再修改一下/etc/openldap/ldap.conf,这样连DC的时候系统就可以去查相应的证书。主要参考的文档是这篇:
Communicating between OpenLDAP and Active Directory over SSL
下面两篇也可以参考:
Configuring Microsoft Active Directory for SSL access
LDAP over SSL - Modifying Active Directory with PHP
上面的文章里最后都要用linux下的ldapsearch命令来测试连接是否可以进行,不过语法不同,我最后成功地连上DC用的语句是:
ldapsearch -x -H "ldaps://theDC.yourdomain.net" -s base -D "cn=proxyuser,cn=users,dc=yourdomain,dc=net" -W -b "dc=yourdomain,dc=net"(回车后提示输proxyuser的密码)
还有,要强调的是,连DC一定要用它的域名,不要用IP或是NetBIOS名,因为CA里写的是域名,要匹配
另,上面说的是linux的ldap客户端,win下也有啊,比如说win2k和2k3的support-tools里的ldp.exe,可是我还没搞清楚它应该怎么才能以SSL连AD。。。
4.用PHP来操作活动目录
这步算是最轻松的了,就是学一学PHP的相关函数的语法就好了。不过大概是没几个人用到ldap这方面的功能吧,PHP manual中ldap这部分的说明很简略,特别是用TLS的文档里写着这部分没有文档。。。所以最好的办法还是看一些源代码,这里推荐的是我在SourceForge上找到一个的PHP连AD的类:http://adldap.sourceforge.net/
这个类写的并不是特别好,比如添用户时非要求填几个没用的属性,还有至少在一层的OU里的样子,所以推荐它主要是为了看它的原码(30k左右,不是很多)学习用ldap来添加、查询、修改、加组等操作应该怎么写,如果你的应用比较复杂,建议还是自己来写,不直接用它的类。
下面几个地址也列出来考虑吧,它们都是我google到的别人问的问题,本身没有确切解答,不过还是有功劳的,比如我认识到了没有验证一个用户的密码对不对的函数,要做的就是用那个用户名和密码去bind一下,bind上了就是对,否则就是错。
http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_21296510.html?qid=21296510
http://topic.csdn.net/t/20060524/10/4774581.html
http://www.ideawu.net/ideablog/category6/article238.html
http://topic.csdn.net/t/20030520/15/1809327.html#
上面列出的文章链接真的不是那么好挑选出来,真怕他们哪天没了,回头我下载完打包传上来吧