在OpenLdap安装成功后,已经可以使用OpenLdap进行认证,但是所有用户在所有机器都是同一个普通用户权限,为了实际使用,还需要引入权限差异功能。sudo可以满足该需求,通过读取存储在OpenLDAP中的配置,允许不同的用户在不同的机器使用不同的(特权)命令。

OpenLDAP Sudo权限讲解

Sudo常见的属性介绍

sudoCommand:可执行的二进制命令,如 useradd、userdel、mount、umount 等。
sudoHost:可在哪些机器上执行 sudoCommand 定义的 BASH 命令。
sudoNotAfter:起始时间 sudo 规则匹配。
sudoNotBefore:结束时间 sudo 规则匹配。
sudoOption:定义超过自身权限及切换至其他用户时,是否需要输入当前用户密码。
sudoOrder:sudo 规则执行顺序,其属性是一个整数。
sudoRole:定义的规则。
sudoRunAs:可切换到定义的用户身份下执行 BASH 命令。
sudoRunAsGroup:可切换到定义所属组并具有该组的权限。
sudoRunAsUser:定义可切换至哪些用户下执行命令。
sudoUser:限制哪些用户或哪些组内的成员具有 sudo 相关规则。

通过OpenLDAP服务实现用户权限控制

导入sudo schema配置

通过rpm -ql sudo来获取sudo管理schema的存放路径,将schema文件复制到 /etc/openldap/schema目录

$ rpm -ql sudo | grep OpenLDAP
/usr/share/doc/sudo-1.8.23/schema.OpenLDAP
$ rpm -ql openssh-ldap | grep openssh-lpk-openldap
/us/share/doc/openssh-ldap-7.4p1/openssh-lpk-openldap.ldif
/usr/share/doc/openssh-ldap-7.4p1/openssh-lpk-openldap.schema
$ /usr/share/doc/openssh-ldap-7.4p1/openssh-lpk-openldap.ldif /etc/openldap/schema/openssh-lpk-openldap.openssh-lpk-openldap.ldif
$ cp /usr/share/doc/openssh-ldap-7.4p1/openssh-lpk-openldap.schema /etc/openldap/schema/openssh-lpk-openldap.schema
$ cp /usr/share/doc/sudo-1.8.23/schema.OpenLDAP /etc/openldap/schema/sudo.schema

通过include在slapd.conf中引用此schema文件,然后转换为ldif格式,通过OpenLDAP相关指令进行转换并导入后方可使用。

$ restorecon /etc/openldap/schema/sudo.schema
$ mkdir ~/sudo
$ echo "include /etc/openldap/schema/sudo.schema" > ~/sudo/sudoSchema.conf
$ slapcat -f ~/sudo/sudoSchema.conf -F /tmp/ -n0 -s "cn={13}sudo,cn=schema,cn=config" > ~/sudo/sudo.ldif
$ head -n-8 ~/sudo/sudo.ldif > ~/sudo/sudo-config.ldif
$ ldapadd -Y EXTERNAL -H ldapi:/// -f ~/sudo/sudo-config.ldif
$ ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/openssh-lpk-openldap.openssh-lpk-openldap.ldif

在OpenLDAP目录树中创建suers条目

sudoers的配置信息存放在ou=suders的子树中,默认OpenLDAP用户没有指定sudo规则,OpenLDAP首先在目录树中寻找条目 cn=default,如果找到,那么所有sudoOption属性都会被解析为全局默认值,这类似于服务端中查询一个sudo用户权限时一般有两到三次查询。第一次查询解析全局配置,第二次查询匹配用户名或者用户所在的组(特殊标签ALL也在此次查询中匹配),如果没有找到相关匹配项,则发出第三次查询,此次查询返回所有包含用户组的条目并检查该用户是否存在于这些组中。

$ cat > sudoers.ldif << EOF
dn: ou=SUDOers,dc=example,dc=com
objectCLass: top
objectClass: organizationalUnit
ou: sudoers
dn: cn=defaults,ou=SUDOers,dc=example,dc=com
objectClass: sudoRole
objectCLass: top
cn: defaults
description: Default sudoOption go here
sudoOption: requiretty
sudoOption: !visiblepw
sudoOption: always_set_home
sudoOption: env_reset
sudoOption: env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS"
sudoOption: env_keep="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
sudoOption: env_keep="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
sudoOption: env_keep="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
sudoOption: env_keep="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"
sudoOption: secure_path=/sbin:/bin:/usr/sbin:/usr/bin
dn: cn=%manager,ou=SUDOers,dc=example,dc=com
objectClass: sudoRole
objectClass: top
cn: %manager
sudoUser: %manager
sudoHost: ALL
sudoRunAsUser: ALL
sudoCommand: /bin/bash
sudoOption: !authenticate
EOF
$ ldapadd -x -D "cn=Manager,dc=example,dc=com" -f sudoers.ldif -w 11111111
adding new entry "cn=default,ou=SUDOers,dc=example,dc=com"
adding new entry "cn=%manager,ou=SUDOers,dc=example,dc=com"

添加OpenLDAP用户到defaults和manager组

$ cat > users.ldif << EOF
dn: cn=manager,ou=Group,dc=example,dc=com
cn: manager
gidnumber: 10001
objectclass: posixGroup
dn: cn=default,ou=Group,dc=example,dc=com
cn: default
gidnumber: 10002
objectclass: posixGroup
dn: uid=manager,ou=People,dc=example,dc=com
cn: manager
sn: manager
homedirectory: /home/manager
loginshell: /bin/bash
objectclass: inetOrgPerson
objectclass: posixAccount
objectclass: shadowAccount
objectclass: organizationalPerson
objectclass: person
shadowlastchange: 17407
uid: manager
gidnumber: 10001
uidnumber: 10005
userpassword: {SSHA}E5jwX4yg26x1uBVUfWzkW8lF5rsHqlE5
dn: uid=defaults,ou=People,dc=example,dc=com
cn: defaults
homedirectory: /home/defaults
loginshell: /bin/bash
objectclass: inetOrgPerson
objectclass: posixAccount
objectclass: shadowAccount
objectclass: organizationalPerson
objectclass: person
shadowlastchange: 17407
sn: defaults
uid: defaults
gidnumber: 10002
uidnumber: 10006
userpassword: {SSHA}E5jwX4yg26x1uBVUfWzkW8lF5rsHqlE5
EOF
$ ldapadd -x -D "cn=Manager,dc=example,dc=com" -f sudoers.ldif -w 11111111
adding new entry "cn=manager,ou=Group,dc=example,dc=com"
adding new entry "cn=defaults,ou=Group,dc=example,dc=com"
adding new entry "uid=manager,ou=People,dc=example,dc=com"
adding new entry "uid=defaults,ou=People,dc=example,dc=com"

客户端配置

修改nsswitch.conf配置文件,添加sudo查找顺序

$ vim /etc/nsswitch.conf
sudoers: files ldap

修改sudo-ldap.conf配置文件,添加支持后端OpenLDAP验证sudo的参数

$ vim /etc/sudo-ldap.conf
sudoers_base ou=SUDOers,dc=example,dc=com
uri ldap://172.16.143.243

验证测试

使用defaults用户执行sudo命令时,输入正确的密码后,会提示权限被拒绝,这是因为defaults用户不在manager组,没有超级权限。

$ sudo -i
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:
#1) Respect the privacy of others.
#2) Think before you type.
#3) With great power comes great responsibility.
[sudo] password for defaults:

使用manager用户执行sudo命令时,会成功切换至root用户目录,这是因为manager用户在manager组,拥有超级权限,可以执行sudo命令。

$ sudo -i