LDAP学习笔记之十:OpenLDAP 主机控制策略

一、主机控制策略实现方式

针对 OpenLDAP 实现主机控制有两种方式。一种通过系统自身的 access 模块实现用户登录主机限制,但配置比较复杂、缺乏灵活性。另一种则通过 OpenLDAP 服务端自身定义的 schema、objectClass 以及添加用户条目属性。并结合客户端的参数配置,从而实现主机登录控制。此方式管理简单、灵活性强。

二、通过 Linux-PAM 模块实现控制

1.Linux-PAM 组织架构

默认登录 UNIX/Linux 机器时,均通过系统自带的 PAM 模块来验证登录者身份的合法性以及密码的正确性来实现系统的登录。Linux-PAM 组织架构图如下 

+----------------+

  | application: X |
  +----------------+       /  +----------+     +================+
  | authentication-[---->--\--] Linux-   |--<--| PAM config file|
  |       +        [----<--/--]   PAM    |     |================|
  |[conversation()][--+    \  |          |     | X auth .. a.so |
  +----------------+  |    /  +-n--n-----+     | X auth .. b.so |
  |                |  |       __|  |           |           _____/
  |  service user  |  A      |     |           |____,-----'
  |                |  |      V     A
  +----------------+  +------|-----|---------+ -----+------+
                         +---u-----u----+    |      |      |
                         |   auth....   |--[ a ]--[ b ]--[ c ]
                         +--------------+
                         |   acct....   |--[ b ]--[ d ]
                         +--------------+
                         |   password   |--[ b ]--[ c ]
                         +--------------+
                         |   session    |--[ e ]--[ c ]
                         +--------------+

2.PAM 配置文件语法讲解

PAM 配置文件路径

$ ls /etc/pam.conf # 旧版
$ ls /etc/pam.d/*  # 新版

PAM 模块路径如下:

$ ls /lib64/security/  # x86_64
$ ls /lib/security/    # x86_32

系统的默认配置文件如下:  

/etc/pam.d/system-auth #https://www.cnblogs.com/kevingrace/p/8671964.html 可以参考这篇文章   

三、通过Access 控制用户实战演练

1.Access 模块功能概要

pam_access 主要用于控制登录访问机器,默认使用 /etc/security/access.conf 配置文件实现各种访问控制限制。但要使用 access.conf 配置文件,必须在 /etc/pam.d/login 文件中加载 pam_access.so 模块,否则修改 access.conf 不会生效

2.Access 配置语法

pam_access.so 验证模块主要根据 access.conf 配置文件中限制的条件进行过滤,access.conf 配置文件格式如下
permission:  user :  origin

各参数的含义如下:
permission:通过 “+” 和 “-” 实现; “+” 代表运行动作,“-” 代表拒绝动作。可以通过 EXCEPT 实现拒绝所有,运行部分登录。
user:代表允许的或拒绝的用户以及用户组;可以通过 “all” 代表所有用户。
origin:代表用户登录的目标,例如 local 代表本地,console 代表控制台,all 代表所有以及定义网络等

3.通过 Access 控制用户实战演练

加载 pam_access.so 模块(需要限制用户登录的客户端机器上)

要加载 pam_access.so 模块,首先编辑 /etc/pam.d/sshd 文件。然后搜索并定位 account,添加如下:(新添加的 account 要设置最前面否则可能会失效)

[root@ldap01 ~]# vim  /etc/pam.d/sshd
#%PAM-1.0
auth       required     pam_sepermit.so
auth       substack     password-auth
auth       include      postlogin
# Used with polkit to reauthorize users in remote sessions
-auth      optional     pam_reauthorize.so prepare
account    required     pam_access.so  #添加pam_access模块,新添加的 account 要设置最前面否则可能会失效
account    required     pam_nologin.so
account    include      password-auth
password   include      password-auth

配置访问规则

[root@client01 ~]# vim /etc/security/access.conf  #限制登录的主机上添加
-:ldap1:ALL         #以ldap1用户为例,禁止ldap1用户登录客户端192.168.1.132机器 

验证

[root@client01 ~]# ssh ldap1@192.168.1.132
ldap1@192.168.1.132's password: 
Permission denied, please try again.

[root@client01 ~]# tail /var/log/secure
Apr 23 00:02:01 client01 sshd[38953]: fatal: Access denied for user ldap5 by PAM account configuration [preauth]
Apr 24 22:27:33 client01 sshd[46999]: Accepted password for root from 192.168.1.1 port 1366 ssh2
Apr 24 22:27:33 client01 sshd[46999]: pam_unix(sshd:session): session opened for user root by (uid=0)
Apr 24 22:37:34 client01 sshd[47514]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=client01.pwb.com  user=ldap1

如果要拒绝或运行多个用户登录系统,可以通过在 OpenLDAP 服务端上将用户加入到指定的组中,然后在 access.conf 配置文件中限制拒绝或运行即可,因为所有验证都通过 OpenLDAP 服务读取信息。

通过 pam_access.so 模块,从 ssh 登录以及 IP 地址方式限制了用户登录主机,但无法限制从控制台登录,所以建议根据当前需求进行选择。

四、OpenLDAP 服务端主机控制规则

提供自定义模块并调整主机配置即可实现 OpenLDAP 用户登录权限限制。

 1.定义 olcModuleList 对象

#通过以下命令定义 olcModuleList 对象。(请查看是否有 /etc/openldap/slapd.d/cn=config/cn=module\{0}.ldif 文件,如果有则忽略定义 olcModuleList 和模块路径的添加 )
$ cat << EOF | ldapadd -Y EXTERNAL -H ldapi:///
dn: cn=module,cn=config
objectClass: olcModuleList
cn: module
EOF

2.添加模块路径

$ cat << EOF | ldapadd -Y EXTERNAL -H ldapi:///
dn: cn=module{0},cn=config
changetype: modify
add: olcModulePath
olcModulePath: /usr/lib64/openldap/  #有则忽略
EOF

3.定义主机控制模块

[root@ldap01 ~]# cat << EOF | ldapmodify -c -Y EXTERNAL -Q -H ldapi:///
dn: cn=module{0},cn=config
add: olcModuleLoad
olcModuleLoad: dynlist.la
EOF
modifying entry "cn=module{0},cn=config"

4.定义主机 objectClass 对象

[root@ldap01 ~]# cat << EOF | ldapadd -Y EXTERNAL -H ldapi:///
dn: olcOverlay=dynlist,olcDatabase={2}hdb,cn=config
objectClass: olcOverlayConfig
objectClass: olcDynamicList
olcOverlay: dynlist
olcDlAttrSet: inetOrgPerson labeledURI
EOF

5.定义 ldapns 的 schema 规范

[root@ldap01 ~]# cat << EOF | ldapadd -Y EXTERNAL -H ldapi:///
dn: cn=ldapns,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: ldapns
olcAttributeTypes: {0}( 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} )
olcAttributeTypes: {1}( 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 )
olcObjectClasses: {0}( 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 )
olcObjectClasses: {1}( 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 )
olcObjectClasses: {2}( 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

6.定义主机列表组

要定义举止列表组(ou),可以添加 ou 为 servers, 并在 servers 下添加子 ou(apphost 和 dbahost),然后将应用系统列表加入到 apphost 组中,将数据库系统加入到 dbahost 组中,从而以组为目录树单位限制不同用户登录不同系统。例如,应用用户只允许登录应用系统(JBOSS、Tomcat、Nginx、openStack 等)以及监控系统(Cacti、Nagios、Zabbix 等),数据库用户只允许登录数据库系统(Oracle、MySQL、MariaDB 等),这样就对用户登录不同系统进行了限制。

为了限制用户登录的系统,使用组进行的形式进行划分。例如,以项目名称为单位划分组,然后将每个项目的机器加入到每个组中,在添加用户时指定 objectClass 对象为 hostObject,并添加 host 和 labeldURI 数据及值即可。具体命令如下:

[root@ldap01 ~]# cat << EOF | ldapadd -x -D "cn=admin,dc=ldap01,dc=pwb,dc=com" -w 123456 -H ldap://ldap01.pwb.com
dn: ou=servers,dc=ldap01,dc=pwb,dc=com
objectClass: organizationalUnit
ou: servers

dn: ou=apphost,ou=servers,dc=ldap01,dc=pwb,dc=com
objectClass: organizationalUnit
objectClass: hostObject
ou: apphost
host: client01.pwb.com
EOF

在添加 ou 时,添加了 objectClass 作为 hostObject 类型,添加了 host 属性,并将client01.pwb.com主机添加至 apphost 组  

7.定义用户组

将用户添加至不同的组中,从而以组为单位限制主机登录。例如用户组:appteam,用户app_user1,具体步骤如下

添加用户组

cat << EOF | ldapadd -x -D "cn=admin,dc=ldap01,dc=pwb,dc=com" -w 123456 -H ldap://ldap01.pwb.com
dn: cn=appteam,ou=Group,dc=ldap01,dc=pwb,dc=com
objectClass: posixGroup
cn: appteam
gidNumber: 10010
EOF 

添加用户,并添加到apphost组中

[root@ldap01 ~]# cat add_user.ldif
dn: uid=app_user1,ou=People,dc=ldap01,dc=pwb,dc=com
uid: app_user1
cn: app_user1
sn: app
objectClass: person
objectClass: posixAccount
objectClass: top
objectClass: shadowAccount
objectClass: inetOrgPerson #labeledURL需要添加inetOrgPerson objectClass
userPassword: 123456
shadowLastChange: 19096
shadowMin: 0
shadowMax: 99999
shadowWarning: 7
loginShell: /bin/bash
uidNumber: 1010
gidNumber: 10010  #注意此处的GID
homeDirectory: /home/app_user1
labeledURI: ldap:///ou=apphost,ou=servers,dc=ldap01,dc=pwb,dc=com?host

[root@ldap01 ~]# ldapadd -x -D "cn=admin,dc=ldap01,dc=pwb,dc=com" -w 123456 -H ldap://ldap01.pwb.com -f add_user.ldif 

检验  

[root@ldap01 ~]# ldapsearch -x -D "cn=admin,dc=ldap01,dc=pwb,dc=com" -w 123456 -H ldap://ldap01.pwb.com -b "uid=app_user1,ou=People,dc=ldap01,dc=pwb,dc=com"
# extended LDIF
#
# LDAPv3
# base <uid=app_user1,ou=People,dc=ldap01,dc=pwb,dc=com> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# app_user1, People, ldap01.pwb.com
dn: uid=app_user1,ou=People,dc=ldap01,dc=pwb,dc=com
uid: app_user1
cn: app_user1
sn: app
objectClass: person
objectClass: posixAccount
objectClass: top
objectClass: shadowAccount
objectClass: inetOrgPerson
userPassword:: e1NTSEF9STZZcjZhV0FOdTh6UkpUNEV5eVB2Y3dGUzNmeCtRMnU=
shadowLastChange: 19096
shadowMin: 0
shadowMax: 99999
shadowWarning: 7
loginShell: /bin/bash
uidNumber: 1010
gidNumber: 10010
homeDirectory: /home/app_user1
labeledURI: ldap:///ou=apphost,ou=servers,dc=ldap01,dc=pwb,dc=com?host
host: client01.pwb.com 
[root@ldap01 ~]# ldapsearch -x -D "cn=admin,dc=ldap01,dc=pwb,dc=com" -w 123456 -H ldap://ldap01.pwb.com "host=client01.pwb.com"
# extended LDIF
#
# LDAPv3
# base <dc=ldap01,dc=pwb,dc=com> (default) with scope subtree
# filter: host=client01.pwb.com
# requesting: ALL
#

# jboss, People, ldap01.pwb.com
dn: uid=jboss,ou=People,dc=ldap01,dc=pwb,dc=com
objectClass: account
objectClass: posixAccount
objectClass: shadowAccount
cn: jboss
uid: jboss
uidNumber: 20006
gidNumber: 10005
userPassword:: amJvc3M=
homeDirectory: /home/jboss
loginShell: /bin/bash
host: client01.pwb.com

# apphost, servers, ldap01.pwb.com
dn: ou=apphost,ou=servers,dc=ldap01,dc=pwb,dc=com
objectClass: organizationalUnit
objectClass: hostObject
ou: apphost
host: client01.pwb.com

# search result
search: 2
result: 0 Success

# numResponses: 3
# numEntries: 2
添加索引
[root@ldap01 ~]# grep olcDbIndex /etc/openldap/slapd.d/cn\=config/olcDatabase\=\{2\}hdb.ldif
[root@ldap01 ~]#  cat << EOF | ldapadd -Y EXTERNAL -H ldapi:///
# Add indexes
dn: olcDatabase={2}hdb,cn=config
changetype:  modify
add: olcDbIndex
olcDbIndex: host eq
EOF

客户端验证:

加载 LDAP 主机控制规则

centos6:
$ cat >> /etc/pam_ldap.conf << EOF
pam_check_host_attr yes
EOF

centos7:
cat >> /etc/nslcd.conf << EOF
pam_authz_search (&(objectClass=posixAccount)(uid=\$username)(|(host=\$hostname)(host=\$fqdn)(host=\\\*)))
EOF

$ systemctl restart nslcd  #重启nslcd服务

  

posted @ 2022-05-06 22:29  百衲本  阅读(1044)  评论(0编辑  收藏  举报
cnblogs_post_body { color: black; font: 0.875em/1.5em "微软雅黑" , "PTSans" , "Arial" ,sans-serif; font-size: 15px; } cnblogs_post_body h1 { text-align:center; background: #333366; border-radius: 6px 6px 6px 6px; box-shadow: 0 0 0 1px #5F5A4B, 1px 1px 6px 1px rgba(10, 10, 0, 0.5); color: #FFFFFF; font-family: "微软雅黑" , "宋体" , "黑体" ,Arial; font-size: 23px; font-weight: bold; height: 25px; line-height: 25px; margin: 18px 0 !important; padding: 8px 0 5px 5px; text-shadow: 2px 2px 3px #222222; } cnblogs_post_body h2 { text-align:center; background: #006699; border-radius: 6px 6px 6px 6px; box-shadow: 0 0 0 1px #5F5A4B, 1px 1px 6px 1px rgba(10, 10, 0, 0.5); color: #FFFFFF; font-family: "微软雅黑" , "宋体" , "黑体" ,Arial; font-size: 20px; font-weight: bold; height: 25px; line-height: 25px; margin: 18px 0 !important; padding: 8px 0 5px 5px; text-shadow: 2px 2px 3px #222222; } cnblogs_post_body h3 { background: #2B6695; border-radius: 6px 6px 6px 6px; box-shadow: 0 0 0 1px #5F5A4B, 1px 1px 6px 1px rgba(10, 10, 0, 0.5); color: #FFFFFF; font-family: "微软雅黑" , "宋体" , "黑体" ,Arial; font-size: 18px; font-weight: bold; height: 25px; line-height: 25px; margin: 18px 0 !important; padding: 8px 0 5px 5px; text-shadow: 2px 2px 3px #222222; } 回到顶部 博客侧边栏 回到顶部 页首代码 回到顶部 页脚代码