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

本文涉及的产品
运维安全中心(堡垒机),免费版 6个月
运维安全中心(堡垒机),企业双擎版|50资产|一周时长
简介: 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 配置文件路径

1

2

$ ls /etc/pam.conf # 旧版

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

PAM 模块路径如下:

1

2

$ ls /lib64/security/  # x86_64

$ ls /lib/security/    # x86_32

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

1

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

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

1.Access 模块功能概要

1

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

2.Access 配置语法

1

2

3

4

5

6

7

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 要设置最前面否则可能会失效)

1

2

3

4

5

6

7

8

9

10

11

[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

配置访问规则

1

2

[root@client01 ~]# vim /etc/security/access.conf  #限制登录的主机上添加

-:ldap1:ALL         #以ldap1用户为例,禁止ldap1用户登录客户端192.168.1.132机器 

验证

1

2

3

4

5

6

7

8

9

[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 对象

1

2

3

4

5

6

#通过以下命令定义 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.添加模块路径

1

2

3

4

5

6

$ cat << EOF | ldapadd -Y EXTERNAL -H ldapi:///

dn: cn=module{0},cn=config

changetype: modify

add: olcModulePath

olcModulePath: /usr/lib64/openldap/  #有则忽略

EOF

3.定义主机控制模块

1

2

3

4

5

6

[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 对象

1

2

3

4

5

6

7

[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 规范

1

2

3

4

5

6

7

8

9

10

[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 数据及值即可。具体命令如下:

1

2

3

4

5

6

7

8

9

10

11

[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,具体步骤如下

添加用户组

1

2

3

4

5

6

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组中

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

[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

检验  

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

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

[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

添加索引

1

2

3

4

5

6

7

8

[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 主机控制规则

1

2

3

4

5

6

7

8

9

10

11

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服务


相关文章
|
3月前
|
安全 Linux 网络安全
LDAP学习笔记之九:OpenLDAP 密码策略、审计控制
LDAP学习笔记之九:OpenLDAP 密码策略、审计控制
|
3月前
|
Linux 网络安全 开发工具
LDAP学习笔记之五:LDAP客户端实现系统帐号验证
LDAP学习笔记之五:LDAP客户端实现系统帐号验证
|
3月前
|
Unix Linux 数据库
LDAP学习笔记之四:NIS简解
LDAP学习笔记之四:NIS简解
|
3月前
|
Shell 应用服务中间件 开发工具
LDAP学习笔记之八:openLDAP sudo权限
LDAP学习笔记之八:openLDAP sudo权限
|
3月前
ASA对接 LDAP ,少不了这些关键配置。
ASA对接 LDAP ,少不了这些关键配置。
|
11月前
|
Kubernetes 容器
006_部署ldap
006_部署ldap
95 0
|
安全 Linux 网络安全
OpenLDAP+freeradius+samba+802.1x实现无线和有线网络认证+动态vlan下发——openLDAP篇(一)
OpenLDAP+freeradius+samba+802.1x实现无线和有线网络认证+动态vlan下发——openLDAP篇
OpenLDAP+freeradius+samba+802.1x实现无线和有线网络认证+动态vlan下发——openLDAP篇(一)
|
网络虚拟化 数据安全/隐私保护
OpenLDAP+freeradius+samba+802.1x实现无线和有线网络认证+动态vlan下发——openLDAP篇(三)
OpenLDAP+freeradius+samba+802.1x实现无线和有线网络认证+动态vlan下发——openLDAP篇
OpenLDAP+freeradius+samba+802.1x实现无线和有线网络认证+动态vlan下发——openLDAP篇(三)
|
网络虚拟化
OpenLDAP+freeradius+samba+802.1x实现无线和有线网络认证+动态vlan下发——openLDAP篇(二)
OpenLDAP+freeradius+samba+802.1x实现无线和有线网络认证+动态vlan下发——openLDAP篇
OpenLDAP+freeradius+samba+802.1x实现无线和有线网络认证+动态vlan下发——openLDAP篇(二)
|
存储 Oracle NoSQL
LDAP协议入门
## 背景 IDaaS产品中非常重要的一个能力,就是支持LDAP Server的对接,完成账号同步和账号登录委托认证能力,主要解决以下三个问题: 1. 基于用户提供LDAP Server配置和凭据信息,作为LDAP Client从LDAP Server中同步用户企业的组织架构和人员账号信息; 1. 支持同步的人员账号能够通过LDAP委托认证流程,完成企业员工的SSO登录(基于LDAP SSO登录
3246 0
LDAP协议入门