0x01 关于 ldap 的一些简单科普
1 2 3 4 5 6 7
| `ldap` 基于tcp/ip的轻量级目录访问协议,属于X.500目录协议族的一个简化版本 你可以暂时把它粗暴的理解成 `一种特殊类型的数据库` ,通常,这种数据库文件后缀都为`.ldif`,并使用特殊的节点查询语句来获取相应数据 实际生产环境中,主要还是用它来做各种查询比较多,既是查询,也就意味着肯定会有大量的读操作 虽然,ldap也支持一些简单的更新功能,即写,但一般都不会用,因为它在写方面的效率并不高 如果真的是写比较多,直接用各种关系型数据库代替就好了,实在没必要用ldap,毕竟,术业有专攻 另外,ldap 跨平台,功能简洁,易管理,配置,读性能也不错,亦可分布式部署`不知道是不是可以把它的分布式理解成windows域的目录树,目录林概念` 用的最多的可能就是进行`集中身份验证`,最后,我们还需要知道的是,默认情况下,ldap的所有数据都是直接以明文传输的,容易被截获,不过好在它支持ssl
|
0x02 其它的一些常用目录服务工具
1 2 3 4
| X.500 过于庞大臃肿 ldap 轻量且配置简单 windows活动目录 有平台限制 NIS 个人暂时还没接触过
|
0x03 了解ldap内部数据的大致存储方式
1 2 3 4 5 6
| 和常规关系型数据库不同的是,ldap并非按照常规的库,表,字段方式来存储数据 而是按照一种特殊的倒树状结构层级来组织管理数据,此处的树指的就是目录信息树,即`DIT` 所谓的目录信息树其实相当于专门用来进行读操作的数据库 在DIT内部则由N个条目`entry`所组成,就相当于我们常规数据库表中每条具体的记录 而条目的内容则是由具有唯一标识名`DN`的属性[Attribute]及属性对应的值[value]所组成的这么一个集合 条目为ldap中最基础的操作单位,通常对ldap的增删改查都是以条目为基本单元进行的
|
如下则是一条完整的条目信息,其实就相当于常规关系型数据库中的一条记录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| dn: cn=aima aima,ou=People,dc=ldapmaster,dc=org objectClass: posixAccount objectClass: inetOrgPerson objectClass: organizationalPerson objectClass: person objectClass: shadowAccount loginShell: /bin/bash uid: aima cn: aima aima uidNumber: 10000 gidNumber: 173 sn: sec givenName: aima homeDirectory: /home/aima shadowLastChange: 17520 userPassword:: e1NTSEF9OExmZ2FyUHQzeGl2K0RscWVOQ09Ma0lxTnkxTWRVeE4=
|
0x04 认识ldap中常见的一些缩写单词含义
1 2 3 4 5 6 7 8
| dn 唯一标示,类似linux文件系统的绝对路径,通过dn我们可以快速查找到目录信息树中的任意一个节点 basedn也就是我们所说的目录信息树的根,rdn 则是相对标示名,即相对路径 dc 一般用于将完整域名划分几部分,如,rootkit.org就会被表示为`dc=rootkit,dc=org` uid 用户id,通常来源于/etc/passwd cn 姓名,通常来源于/etc/group sn 姓 o 组织[公司]名称,像这些只是从逻辑上分开 ou 单位[部门]名称
|
0x05 和很多服务相同,ldap服务同样也是工作在 C / S 架构模型下
1 2
| 服务端负责提供整个目录信息树,客户端只需拿着相应的信息树查询工具,向服务端提交查询请求,而后,服务端要么响应给具体的条目数据,要么直接返回一个指针 如果服务端返回的是指针,客户端还需再拿着该指针到指定的ldap服务器上去查询相应的条目数据
|
此次演示环境
1 2
| CentOS6.8_x86_64 ip: 192.168.3.68 ldapmaster CentOS6.8_x86_64 ip: 192.168.3.69 ldapslave
|
0x06 开始实战部署openldap,关于openldap本身其实并没什么太多好说的,就是ldap协议的一种具体实现而已
部署前环境准备,安装整个基础环境包,统一所有机器时间,机器名...
1 2 3 4 5 6 7 8
| # yum groupinstall "Development Tools" -y # /usr/sbin/ntpdate time.nist.gov # crontab -e */2 * * * * /usr/sbin/ntpdate time.nist.gov 每两分钟同步一下时间 # crontab -l # vi /etc/hosts 192.168.3.68 ldapmaster.org 192.168.3.69 ldapslave.org
|
安装openldap及其必要的依赖库
1 2 3 4 5 6 7
| # yum install openldap openldap-* -y # yum -y install nscd nss-pam-ldapd pcre pcre-* # yum -y update nss-softokn-freebl 此处软件包有冲突,最好分开装 # yum -y install nss-* # rpm -qa | grep openldap # id ldap 安装完成后,会自动创建一个名为ldap的系统伪用户,专用用来跑ldap服务 # slapd -V 此处演示的openldap版本为2.4
|
0x07 以上没问题后,我们开始来配置OpenLdap,此处依然使用兼容2.3版本的配置方式
1 2 3
| # cd /etc/openldap/ # cp /usr/share/openldap-servers/slapd.conf.obsolete slapd.conf # ls -l
|
设置ldap管理员密码,还是那句话,实际生产环境中,这个密码务必要足够的强壮
1 2 3 4 5
| # slappasswd -s klion 生成ldap管理员密码hash,并把它追加到ldap主配置中 # slappasswd -s klion | sed -e "s#{SSHA}#rootpw\t{SSHA}#g" >>/etc/openldap/slapd.conf # tail -n 1 /etc/openldap/slapd.conf rootpw {SSHA}rkmKIPz4B5y6MmGLqSZbMZy0JMVY/gzK # cp slapd.conf slapd.conf_`date +%Y%m%d`.bak
|
修改ldap数据库及日志设置,注意配置文件中的所有配置项必须顶格写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| # vi /etc/openldap/slapd.conf # 先把默认的数据库配置全部注释掉 # database definitions # database bdb # suffix "dc=my-domain,dc=com" # checkpoint 1024 15 # rootdn "cn=Manager,dc=my-domain,dc=com" # 再来新增自己的数据库配置 database bdb # 指定使用的数据库格式 suffix "dc=ldapmaster,dc=org" # 指定域名 rootdn "cn=klion,dc=ldapmaster,dc=org" # 指定ldap管理员的dn rootpw {SSHA}rkmKIPz4B5y6MmGLqSZbMZy0JMVY/gzK # ldap管理员的密码hash,就是我们上面设置的klion # 设置ldap日志 loglevel 296 指定日志级别 cachesize 2000 可以缓存的记录总数 checkpoint 2048 10 每到2048K或者每10分钟把内存中的数据往数据库中写一次 # 修改ldap默认的ACL,此处,支持直接用正则表示,严禁允许直接匿名访问,非常危险,极易造成大量敏感信息泄露 # 建议把默认的access项全部注释掉,换成如下权限,所谓的 `ldap未授权` 的根源也就在这里 # 下面ACL只做简单demo参考,大家可根据自己的实际情况,把to后的*换成更具体的范围,把by 后的权限控制的更精细些 access to * by self write by anonymous auth by user read # egrep -v "^$|#" /etc/openldap/slapd.conf 最后,检查配置
|
详细的ACL编写,可直接参考其官方说明,如下
1
| http://www.openldap.org/doc/admin24/access-control.html
|
0x08 让rsyslog记录ldap日志
1 2 3 4
| # cp /etc/rsyslog.conf /etc/rsyslog.conf_`date +%Y%m%d`.bak # echo "local4.* /var/log/ldap.log" >> /etc/rsyslog.conf # tail -n 1 /etc/rsyslog.conf # /etc/init.d/rsyslog restart
|
0x09 修改ldap数据库的存放路径
1 2 3 4 5 6 7 8
| # grep bdb /etc/openldap/slapd.conf # 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/ # ll /var/lib/ldap/ # egrep -v "#|^$" /var/lib/ldap/DB_CONFIG # slaptest -u 检查slapd.conf配置是否正确 # egrep -v "^#|^$" /etc/openldap/slapd.conf
|
0x10 一切配置就绪后,我们尝试启动openldap服务,默认它工作在tcp的389端口
,如果是加密通信,默认端口则为636
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| # /etc/init.d/slapd start # netstat -tulnp | grep 389 # ps aux | grep slapd 查看ldap默认的服务运行权限 # chkconfig slapd on # chkconfig --list | grep slapd # tail /var/log/ldap.log
# 查询当前ldap数据库中的所有用户信息,默认肯定是空的,因为我们此时还没有导入任何信息 # ldapsearch -LLL -W -x -H ldap://ldapmaster.org -D "cn=klion,dc=ldapmaster,dc=org" -b "dc=ldapmaster,dc=org" "(uid=*)" # 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 # /etc/init.d/slapd restart # netstat -tunlp |grep slapd
|
0x11 到此为止,ldap基本就算搭建好了,接下来,我们开始往ldap数据库中添加用户数据,在添加之前我们需要先把它转成符合ldap数据库的数据格式,如下
安装migrationtools工具,因为我们要它来导出本地用户数据
1 2 3 4
| # yum install migrationtools -y # vi /usr/share/migrationtools/migrate_common.ph 修改为自己的域名和BaseDN $DEFAULT_MAIL_DOMAIN = "ldapmaster.org"; $DEFAULT_BASE = "dc=ldapmaster,dc=org";
|
使用migrationtools内置的脚本来进行导出
1 2 3 4 5
| # export LC_ALL=C # echo "export LC_ALL=C" >> /etc/profile # /usr/share/migrationtools/migrate_base.pl > base.ldif # /usr/share/migrationtools/migrate_passwd.pl /etc/passwd > passwd.ldif # /usr/share/migrationtools/migrate_group.pl /etc/group > group.ldif
|
使用ldapadd的添加条目,即 增
,往ldap数据库中添加刚刚导出的数据
1 2 3
| # ldapadd -x -H ldap://ldapmaster.org -D "cn=klion,dc=ldapmaster,dc=org" -W -f base.ldif # ldapadd -x -H ldap://ldapmaster.org -D "cn=klion,dc=ldapmaster,dc=org" -W -f passwd.ldif # ldapadd -x -H ldap://ldapmaster.org -D "cn=klion,dc=ldapmaster,dc=org" -W -f group.ldif
|
使用ldapdelete删除指定条目,即 删
1
| # ldapdelete -x -H ldap://ldapmaster.org -D "cn=klion,dc=ldapmaster,dc=org" -w klion "cn=test,ou=Group,dc=ldapmaster,dc=org"
|
使用ldapmodify修改指定条目,即 改
1
| # ldapmodify -x -W -H ldap://ldapmaster.org -D "cn=klion,dc=ldapmaster,dc=org" -f fstab.ldif
|
使用ldapsearch查询指定条目,即 查
询指定basedn下的所有条目
1 2
| # ldapsearch -LLL -w klion -x -H ldap://ldapmaster.org -D "cn=klion,dc=ldapmaster,dc=org" -b "dc=ldapmaster,dc=org" # ldapsearch -LLL -w klion -x -H ldap://ldapmaster.org -D "cn=klion,dc=ldapmaster,dc=org" -b "dc=ldapmaster,dc=org" "(uid=aima)"
|
备份ldap数据库
1
| # ldapsearch -LLL -w klion -x -H ldap://ldapmaster.org -D "cn=klion,dc=ldapmaster,dc=org" -b "dc=ldapmaster,dc=org" "(uid=*)" >bak.ldif
|
0x12 使用各种ldap客户端管理工具来操作ldap数据库,此处暂以web端管理接口为例进行演示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| # yum install httpd php php-ldap php-gd -y # cd /var/www/html/ # tar xf ldap-account-manager-4.2.tar.gz # mv ldap-account-manager-4.2 ldap # cd ldap/config # cp config.cfg_sample config.cfg_sample.bak # cp lam.conf_sample lam.conf_sample.bak # mv config.cfg_sample config.cfg # mv lam.conf_sample lam.conf serverURL: ldap: admins: cn=klion,dc=ldapmaster,dc=org treesuffix: dc=ldapmaster,dc=org types: suffix_user: ou=People,dc=ldapmaster,dc=org types: suffix_group: ou=group,dc=ldapmaster,dc=org types: suffix_host: ou=machines,dc=ldapmaster,dc=org types: suffix_smbDomain: dc=ldapmaster,dc=org # chown -R apache.apache /var/www/html/ldap # vi /etc/httpd/conf/httpd.conf <VirtualHost *:80> ServerAdmin ldapmaster.org DocumentRoot /var/www/html/ldap ServerName ldapmaster.org ErrorLog logs/ldapmaster.org-error_log CustomLog logs/ldapmaster.org-access_log common </VirtualHost> # /etc/init.d/httpd start # chkconfig httpd on http:
|
虽然这种纯图形化的工具貌似是很好用,但个人还是不太建议在实际生产环境中用,验证过于简单,比较危险,毕竟只是个web脚本,很容易被入侵者扫目录,扫域名时扫到,另外,也极易被各类搜索引擎抓到,如下
1
| inurl:templates/login.php intitle:LDAP Account Manager
|
0x13 启用sasl,让指定的服务都通过ldap的方式进行集中身份验证
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| # yum install *sasl* -y # rpm -qa | grep sasl # saslauthd -v sasl所支持的所有认证类型 # sed -i 's#MECH=pam#MECH=ldap#g' /etc/sysconfig/saslauthd # grep -i mech /etc/sysconfig/saslauthd MECH=ldap # /etc/init.d/saslauthd start # chkconfig saslauthd on # vi /etc/saslauthd.conf ldap_bind_dn: cn=klion,dc=ldapmaster,dc=org ldap_bind_pw: klion ldap_search_base: ou=People,dc=ldapmaster,dc=org ldap_filter: uid=%U ldap_password_attr: userPassword # ps -ef | grep sasl # testsaslauthd -u super -p admin 此时便会用ldap账户来进行验证
|
0x14 以让svn服务通过ldap进行认证为例,其实非常简单,首先,你需要先在本机快速部署好svn,至于具体的部署方法,请参考之前的相关文章,当然,除了svn,像vsftpd,samba
这类的基础服务也都可以通过ldap进行身份验证,并非重点此处不再赘述
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| # 让svn通过ldap进行验证,不再走svn自己的验证了 # vi /etc/sasl2/snv.conf pwcheck_method: saslauthd mech_list: PLAIN LOGIN
# 编辑svn主配置文件 # vi /svn/svndata/svndoc/conf/svnserve.conf [general] anon-access = none auth-access = write password-db = /svn/svnpasswd/passwd authz-db = /svn/svnpasswd/authz [sasl] use-sasl = true # 开启svn的sasl验证 # 把svn本地用户全部注释掉,因为一旦开启sasl就不再走svn本地验证了 # vi /svn/svnpasswd/passwd [users] # harry = harryssecret # sally = sallyssecret # web = 654321 # webadmin = admin110 # admin = 123456 # bakuser = admin # guest = svn110 # svn = svnadmin
# 另外,还需要把ldap用户加到svn认证文件中,不然,依然是登不上svn的 # 虽然用户密码验证过程不走本地,但权限认证过程还是在本地进行的 # vi /svn/svnpasswd/authz [aliases] [groups] administrator = web sec = webadmin,admin ldap_user = svnnew,super [svndoc:/] svn = rw @administrator = rw @ldap_user = rw [svndoc:/web01] bakuser = rw [svndoc:/web02] guest = rw
|
下面是svn通过ldap进行认证的实际效果
0x15 关于ldap主从同步,后续有机会再说,这次我们先初步入个门 ^_^
0x16 最后,我们再来关注下openldap的一些安全问题,最重要的可能就是允许匿名访问
,对此的利用没什么好说的,直接用各种ldap客户端工具,如,LDAPSoft Ldap Browser或者JXplorer都行
,只需指定正确的ip,端口和dn,然后用匿名的方式连上去即可
后话:
建议实际生产环境中直接使用加密传输,另外,可根据实际业务需求配置更具针对性的ACL,至于针对web层的ldap注入 [ 其实跟sql注入没什么两样,只是查询语言不同而已 ]
,篇幅原因,我们在后续的相关章节中还会再做详细说明,待续……