碰巧所在的公司用到了ldap 集中身份认证,全部打算研究下这套架构,可是看遍了网络上的不少教程,要么不完整,要么就是照着根本弄不出来,十月一研究了三天,结合八方资源终于弄出来了,真是不容易,哎,特此记录一把:php
一。实现效果:node
1.实现linux openldap 帐号集中管理linux
2.能够控制帐号是否能够sudo 到rootweb
3.能够实现密码和pubkey 登录redis
4.能够控制用户能够登录到哪些主机数据库
二。系统环境:windows
Red Hat Enterprise Linux Server release 6.7 (Santiago)bash
三。项目拓扑:服务器
采用两节点演示:网络
ldap server端: 192.168.85.137 (既充当server端,也作client端)
ldap client端: 192.168.85.139
四.软件版本:
openldap-servers-2.4.40-16.el6.x86_64
#安装前准备:
1.关闭防火墙及selinux
2.配置hosts解析:
192.168.85.137 node1
192.168.85.139 node2
3.配置ntp时间同步:
ntpdate time.windows.com
# 安装openldap server:
yum install -y openldap-servers-2.4.40-16.el6.x86_64 openldap-clients-2.4.40-16.el6.x86_64 openldap-2.4.40-16.el6.x86_64 openldap-devel-2.4.40-16.el6.x86_64 compat-openldap.x86_64
# 初始化openldap配置:
cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG cp /usr/share/openldap-servers/slapd.conf.obsolete /etc/openldap/slapd.conf chown -R ldap.ldap /etc/openldap chown -R ldap.ldap /var/lib/ldap
suffix "dc=hello,dc=com"
#编辑 /etc/openldap/slapd.conf (修改如下配置,其余能够保持默认,或者根据本身需求修改,我这里只是修改了下面三项)
suffix "dc=hello,dc=com" #配置域名后缀,相似最上次的父域名称 rootdn "cn=admin,dc=hello,dc=com" #新建管理员admin rootpw {SSHA}LoVG+OZ61YG95bbZbVDZnkotGRSchz+Q #管理员的password,可使用明文或密文,密文用 slappasswd 生成
#生成配置文件:
rm /etc/openldap/slapd.d/* -fr #删除老的配置数据库 slaptest -f /etc/openldap/slapd.conf #检测配置文件是否有语法错误
slaptest -f /etc/openldap/slapd.conf -F /etc/openldap/slapd.d #经过slapd.conf生成新的数据库
# 启动ldap server:
/etc/init.d/slapd start
# openldap 默认使用389,端口,查看服务是否启动成功:
############################################# 客户端配置
# 客户端部署,安装openldap client 软件:
yum install -y openldap-clients.x86_64 nss-pam-ldap
# 修改/etc/nslcd.conf ,添加下面内容:
uri ldap://192.168.85.137/ base dc=hello,dc=com ssl no
# 修改/etc/pam_ldap.conf,增长下面内容:
base dc=hello,dc=com uri ldap://192.168.85.137/
# 修改/ /etc/pam.d/system-auth
auth required pam_env.so auth sufficient pam_unix.so nullok try_first_pass auth requisite pam_succeed_if.so uid>=500 quiet auth sufficient pam_ldap.so #增长ldap模块 auth required pam_deny.so account required pam_unix.so account sufficient pam_succeed_if.so uid<500 quiet account required pam_ldap.so #增长ldap模块 account required pam_permit.so password requisite pam_cracklib.so try_first_pass retry=3 password sufficient pam_unix.so md5 shadow nullok try_first_pass use_authtok password sufficient pam_ldap.so use_authtok md5 #增长ldap模块 password required pam_deny.so session optional pam_keyinit.so revoke session required pam_limits.so session [success=1 default=ignore]pam_succeed_if.so service in crond quiet session required pam_unix.so session required pam_mkhomedir.so skel=/etc/skel/ umask=0022 session optional pam_ldap.so #增长ldap模块
# 修改/etc/pam.d/sshd (ssh登录的话须要用到这个文件,若是只修改/etc/pam.d/system-auth的话控制台登录没问题,可是若是远程ssh 链接就会出现问题)
auth required pam_env.so auth sufficient pam_unix.so nullok try_first_pass auth requisite pam_succeed_if.so uid>=500 quiet auth sufficient pam_ldap.so use_first_pass #加载ldap auth required pam_deny.so account required pam_unix.so account sufficient pam_succeed_if.so uid<500 quiet account [default=bad success=ok user_unknown=ignore] pam_ldap.so #加载ldap account required pam_permit.so password requisite pam_cracklib.so try_first_pass retry=3 password sufficient pam_unix.so md5 shadow nullok try_first_pass use_authtok password sufficient pam_ldap.so use_authtok #加载ldap password required pam_deny.so session optional pam_keyinit.so revoke session required pam_limits.so session [success=1 default=ignore]pam_succeed_if.so service in crond quiet session required pam_unix.so session required pam_mkhomedir.so skel=/etc/skel/ umask=0022 #自动建立用户家目录 session optional pam_ldap.so #加载ldap模块
# 修改/etc/nsswitch.conf,指定查找顺序:
passwd: files ldap shadow: files ldap group: files ldap
# 修改 /etc/sysconfig/authconfig
USESHADOW=yes USELDAPAUTH=yes USELOCAUTHORIZE=yes USELDAP=yes
# 新建ou,用来存放用户:
dn: ou=People,dc=hello,dc=com ou: People objectClass: top objectClass: organizationalUnit
# 新建ou,用来存放组:
dn: ou=Group,dc=hello,dc=com ou: Group objectClass: top objectClass: organizationalUnit
# 新建用户 user200
dn: uid=user200,ou=People,dc=hello,dc=com uid: user200 cn: user200 sn: user200 objectClass: posixAccount objectClass: person objectClass: inetOrgPerson objectClass: shadowAccount userPassword: {CRYPT}-s2a6QekMTXp6 #这里填的是密文密码,用slappasswd -c -s 命令生成 shadowLastChange: 18171 shadowMin: 0 shadowMax: 99999 shadowWarning: 7 loginShell: /bin/bash uidNumber: 5204 gidNumber: 5204 homeDirectory: /home/user200
NOTE:虽然能够填明文密码,也能够填密文密码,可是若是想要结果linux 登录,就必须填slappasswd -c -s 生成的密码,这个命令生成crypt(3) 加密的格式,linux 能够识别,网上虽说能够用明文,可是我反正没有尝试成功。
# 启动ldap 客户端
/etc/init.d/nslcd start
配置完成,能够进行ssh 远程链接了
############################## 配置用户sudo
##### 服务器配置
1.能够经过本地sudo文件,也能够经过ldap server 端配置sudo,这里利用ldap server端来配置
# 拷贝sudo schema
cp /usr/share/doc/sudo-1.8.6p3/schema.OpenLDAP /etc/openldap/schema/sudo.schema
# 编辑/etc/slapd.conf ,增长下面配置:
include /etc/openldap/schema/sudo.schema
# 生成新的数据库配置:
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/ #赋权,否则启动sladp 会报错
/etc/init.d/sladp restart #重启服务让配置生效
# 最好装好phpldapadmin,这个web界面可让咱们图形化操做ldap,具体安装过程能够google,这里省略,还有须要注意的一点是若是用yum 安装的 phpldapadmin可能始终会提示密码错误,具体缘由没有去研究,到网上下载源码本身安装下就行了,没必要去纠结
# 新建 sudoers Ou:
dn: ou=sudoers,dc=hello,dc=com ou: sudoers objectClass: top objectClass: organizationalUnit
# 新建组admin:
dn: cn=admin,ou=group,dc=hello,dc=com
cn: admin
gidNumber: 505
objectClass: posixGroup
objectClass: top
# 新建sudo 规则:
dn: cn=%admin,ou=sudoers,dc=hello,dc=com objectClass: sudoRole cn: %admin sudoUser: %admin sudoHost: ALL sudoRunAsUser: root sudoOption: !authenticate sudoCommand: /bin/bash EOF
# 将用户加入admin组,这个这个用户就有了sudo 到root 的权限
cat >> modify_gid.ldif << EOF dn: uid=user200,ou=People,dc=hello,dc=com changetype: modify replace: gidNumber gidNumber: 505 EOF ldapmodify -x -W -D "cn=admin,dc=hello,dc=com" -f modify_gid.ldif
### 客户端配置:
cat >> /etc/nsswitch.conf << EOF
sudoers: ldap files
EOF
########################################## 配置ssh 秘钥登录
# 拷贝 schema
cp /usr/share/doc/openssh-ldap-5.3p1/openssh-lpk-openldap.schema /etc/openldap/schema/
# /etc/openldap/sladp.conf 增长ssh schema
include /etc/openldap/schema/openssh-lpk-openldap.schema
# 从新生成新的配置文件:
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/ #赋权,否则启动sladp 会报错
/etc/init.d/sladp restart #重启服务让配置生效
# 配置sshldap 配置文件 (个人环境没有配置设个配置文件也没有出问题,还不知道何时会用这个配置,可是仍是配上吧,保险起见)
cp /usr/share/doc/openssh-ldap-5.3p1/ldap.conf /etc/ssh/
# 增长下面配置文件到/etc/ssh/ldap.conf
uri ldap://192.168.85.137/ base dc=hello,dc=com ssl no
# 配置 /etc/ssh/sshd_config
RSAAuthentication yes PubkeyAuthentication yes AuthorizedKeysCommand /usr/bin/get_pubkey #这个命令能够本身实现,只要最终能获取pubkey就好了,切结配置末尾不要有空格,不然会报错。 AuthorizedKeysCommandRunAs nobody
# get_pubkey 内容(其实就是链接ldap 服务器而后把key 取回来):
#!/bin/sh -e ldapsearch -x -D 'cn=admin,dc=hello,dc=com' -w 123qaz\! \ -b 'ou=People,dc=hello,dc=com' -H ldap://192.168.85.137 '(&(objectClass=posixAccount)(uid='"$1"'))' \ 'sshPublicKey' \ | sed -n '/^ /{H;d};/sshPublicKey:/x;$g;s/\n *//g;s/sshPublicKey: //gp'
# user200增长新的属性以支持pubkey:
cat >> add_objectclass.ldif << EOF
dn: uid=user200,ou=People,dc=hello,dc=com changetype: modify add: objectclass objectClass: ldapPublicKey - add: sshPublicKey sshPublicKey: ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAxKFoN4eC4bkKYDjK7YoivzGz2tpHbL2Gu4fyEIHrVDuxFwBHt2sKNG/Y56xDIwaMczeLgJkymjzfq7bZTJxZHAKN4x3qvzBA0UYSjnbr3YM9yMKqCllEWMjhVCchDI7vclO/VhsZRB/rSsGivIQjPEzwnn7qcnPhkqte6pa5i5C71NlcFf2Bz3HIE6zpcRFKEYrQgEcJa2fNFDUuY9PN5O1KRahSIPmg2mvWrr7DgTzI+TjCtlxrZuWXJPmJUuV2CWl9J4xcq5KV8Pf8LwlTvIuLx1hnYhojelM7LE4jh2mXweWl4My8xoeOw5hhJ9ekGTQgi1EeooVexguDHo/pnQ== root@node
EOF
# 向ldap server提交user200属性的的修改
ldapadd -x -w 123qaz\! -D "cn=admin,dc=hello,dc=com" -f add_objectclass.ldif
########################################### 限制用户只能登录指定的主机
默认状况下用户能够登录全部的主机,此时咱们能够限制用户能够登录哪些指定的主机,能够在客户端上配置 /etc/security/access.conf ,也能够在openldap中限制,这里在openldap server端控制:
1.能够基于host 限制一个用户登录哪些主机
2.也能够基于主机限制一个主机容许哪些用户登录
########## 限制用户能够登录哪些主机:
# 导入新的schema
cat > /etc/openldap/schema/ldapns.schema << EOF
attributetype ( 1.3.6.1.4.1.5322.17.2.1 NAME 'authorizedService'
DESC 'IANA GSS-API authorized service name'
EQUALITY caseIgnoreMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
attributetype ( 1.3.6.1.4.1.5322.17.2.2 NAME 'loginStatus'
DESC 'Currently logged in sessions for a user'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
ORDERING caseIgnoreOrderingMatch
SYNTAX OMsDirectoryString )
objectclass ( 1.3.6.1.4.1.5322.17.1.1 NAME 'authorizedServiceObject'
DESC 'Auxiliary object class for adding authorizedService attribute'
SUP top
AUXILIARY
MAY authorizedService )
objectclass ( 1.3.6.1.4.1.5322.17.1.2 NAME 'hostObject'
DESC 'Auxiliary object class for adding host attribute'
SUP top
AUXILIARY
MAY host )
objectclass ( 1.3.6.1.4.1.5322.17.1.3 NAME 'loginStatusObject'
DESC 'Auxiliary object class for login status attribute'
SUP top
AUXILIARY
MAY loginStatus )
EOF
# 配置/etc/slapd.conf,加入下面内容:
include /etc/openldap/schema/ldapns.schema modulepath /usr/lib64/openldap moduleload dynlist.la overlay dynlist dynlist-attrset inetOrgPerson labeledURI
# 从新生成数据库配置:
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/ #赋权,否则启动sladp 会报错 /etc/init.d/sladp restart #重启服务让配置生效
# 定义主机组redis和webserver,两个组里包含不一样的主机:
cat << EOF | ldapadd -x -W -H ldaps:/// -D cn=admin,dc=hello,dc=com dn: ou=servers,dc=hello,dc=com objectClass: organizationalUnit ou: servers dn: ou=redis,ou=servers,dc=hello,dc=com objectClass: organizationalUnit objectClass: hostObject ou: redis host: node1 host: node2 dn: ou=webserver,ou=servers,dc=hello,dc=com objectClass: organizationalUnit objectClass: hostObject ou: webserver host: node1 EOF
# 用户增长新的属性,用来支持自动读取主机组里主机
dn: uid=user200,ou=People,dc=hello,dc=com changetype: modify add: objectClass objectClass: hostObject - add: labeledURI labeledURI: ldap:///ou=webserver,ou=servers,dc=hello,dc=com?host
#客户端/etc/pam_ldap.conf 增长配置:
pam_check_host_attr yes
# 经过上面的配置客户端已经能够自动获取主机组里配置的主机,可是如今是以组为单位,若是这是要单独加一台不属于任何组的主机,能够直接给用户添加host 属性,而后单独加入要登陆的hostname:
cat >> add_objectclass.ldif << EOF
dn: uid=user200,ou=People,dc=hello,dc=com changetype: modify add: host host: node3
EOF
ldapadd -x -w 123qaz\! -D "cn=admin,dc=hello,dc=com" -f add_objectclass.ldif
ok!,如今新增了一台主机Nod3
NOTE: 这样只能基于客户端的主机名来限制用户登录,当用户登陆时客户端会从ldap 查询用户属性里的host 字段是否和要登陆的host 的hostname一致,若是一致就能够登录,或则拒绝,全部必定要保证hostname 和属性利配置一致,并且若是要经过ssh登录,必须保证/etc/pam.d/sshd 文件配置正确,不然检查host不会生效(具体配置本文开头已给出)
## 下面是第二种方式:指定主机容许哪些用户登录:
# 添加hosts 设备
dn: cn=node2,ou=servers,dc=hello,dc=com objectClass: ipHost objectClass: device objectClass: extensibleObject ipHostNumber: 192.168.85.139 cn: node2 uniquemember: uid=user200,ou=people,dc=hello,dc=com #指定容许登录用户
# 客户端配置:
/etc/pam_ldap.conf 增长配置:
pam_groupdn cn=node2,ou=servers,dc=hello,dc=com
pam_member_attribute uniquemember
NOTE: 也能够借助下面两种方法实现(具体没去研究):
1./etc/pam_ldap.conf :
pam_filter memberOf=cn=IP,ou=Hosts,dc=hello,dc=com
2./etc/nslcd.conf:
filter shadow (&(objectClass=posixAccount)(memberOf=cn=IP,ou=Hosts,dc=hello,dc=com))
filter passwd (&(objectClass=posixAccount)(memberOf=cn=IP,ou=Hosts,dc=hello,dc=com))
到这里已经完成了基本功能了,还有不少没有作,例如 访问控制,拒绝匿名用户访问,密码保护,密码字段禁止随便读,TLS,主从同步等,总之若是生成环境用的话这些都是不可避免的。ldap 网上能用的资料太少了,不多看了一篇教程就能彻底搭出来,只是说若是在搭建过程当中卡住了,这时候能够找下教程,说不定正好解决了你的问题,我一开始网上研究了下ldap,感受云里雾里,理论太多,并且都比较抽象,后来买了本书叫 openldap实战指南,是某大勇写的,哎,看完一万个草泥马,不少地方按照他的文档根本搞不定,并且节奏太快,若是没有点linux 工做经验可能根本就看不懂,更抽的是那本书居然没有提供书里的代码下载地址,全靠手敲。最后结合那本书和百度,谷歌各类鼓捣,花了三天,终于所有搞完了。总之ldap 这玩意儿,功能感受仍是挺强大的,建议仍是静下心来研究下基础,不然网上的教程文档可能你根本就看不懂,这也情有可原,没人有义务或者有时间免费写一个小白教程,都只是以文档形式记录下本身的过程拿来本身备忘的。
搭建有几个点卡了很长时间:
1.AuthorizedKeysCommand /usr/bin/get_pubkey.sh #这里是配置sshd 去ldap获取公钥的程序,配置的时候不当心在最后面多敲了空格,致使用户登录的时候 cat /var/log/secure 始终找不到这个脚本。
2.配置了限制用户主机登录后未生效,用户依然能够ssh登录全部主机 ,可是经过控制台登录却生效 #由于用户ssh登录时 检查的是/etc/pam.d/sshd ,最后从新配置了这个文件问题解决
3.新建用户是指定了明文密码,可是ssh 登录却失败,始终提示密码不正确 #最后看官网,linxu 支持crypt(3) 格式加密,后来用 slappasswd -c -s 从新生成密码后问题解决。