Salt维护一个标准系统,用于向非管理员用户开放细粒度的权限控制以执行一些Salt命令。 访问控制系统已应用于所有用于配置Salt中非管理员控制接口的访问权限的系统。
现在,在使用external auth 和 publisher ACLs的情况下,可以对于特定的minions,让特定用户可以打开特定的功能。在peer系统的情况下也适用。
这些接口包括peer
系统,external auth
系统和publisher acl
系统。
ACCESS CONTROL SYSTEM
New in version 0.10.4.
访问控制系统强制要求在所有peer
系统,external auth
系统和publisher acl
系统三个系统中使用标准的配置语法。 虽然这为0.10.4版本的配置增加了功能,但它并没有弃用旧配置。
- Publisher ACL system - Publisher服务访问控制列表
- External Authentication System - 使用外部身份认证系统
- Peer Communication - 对等设备通信
WHEN TO USE EACH AUTHENTICATION SYSTEM
publisher_acl对于允许本地其他系统用户运行Salt命令而不给予它们使用root访问权限时会非常有用。 如果你可以直接登录Salt master,那么publisher_acl允许你在没有root权限的情况下使用Salt。 如果本地系统配置为使用一个远程系统(如LDAP或Active Directory)进行身份验证,则publisher_acl将透明地与远程系统进行交互。
external_auth对于salt-api或者使用Salt的Python API创建自己的脚本时非常有用。 它可以在CLI上使用(带-a标志),但由于涉及更多步骤,因此更麻烦。 在CLI中唯一有用的是本地系统未配置为使用外部服务进行身份验证,但你仍希望Salt通过一个外部服务进行身份验证时。
配置示例
在这些配置中使用了通配符帮助确认需要进行访问控制的资源:
publisher_acl:
fred:
- web\*:
- pkg.list_pkgs
- test.*
- apache.*
在上面的例子中,系统用户fred只能向与指定的glob目标匹配的minions发送命令。 这可以扩展到包括任何基于标准目标的其他minions的其他功能(除了不支持复合使用匹配规则之外,所有其它的匹配器都可以支持)。
external_auth:
pam:
dave:
- test.version
- mongo\*:
- network.*
- log\*:
- network.*
- pkg.*
- 'G@os:RedHat':
- kmod.*
steve:
- .*
上面允许所有minions被用户dave执行test.version,并添加了dave可以在其他minions上执行的一些函数。 它还允许用户steve可以不受限制地访问salt命令。
注意:支持使用正则表达式匹配函数。
PUBLISHER ACL SYSTEM
Salt publisher ACL system是一种允许除root之外的系统用户有权限在master上执行一些select salt命令的方法。
publisher ACL system通过publisher_acl配置选项在master配置文件中配置。 在publisher_acl配置选项下,为指定用户配置其可以使用的minions管理功能函数命令。 用户和函数都可以通过匹配来指定,支持使用shell glob或正则表达式。 此配置与external_auth配置非常相似:
publisher_acl:
# Allow thatch to execute anything.
thatch:
- .*
# Allow fred to use test and pkg, but only on "web*" minions.
fred:
- web*:
- test.*
- pkg.*
# Allow admin and managers to use saltutil module functions
admin|manager_.*:
- saltutil.*
# Allow users to use only my_mod functions on "web*" minions with specific arguments.
user_.*:
- web*:
- 'my_mod.*':
args:
- 'a.*'
- 'b.*'
kwargs:
'kwa': 'kwa.*'
'kwb': 'kwb'
PERMISSION ISSUES
必须修改publisher_acl所需访问的目录,以便指定的用户可以读取:
chmod 755 /var/cache/salt /var/cache/salt/master /var/cache/salt/master/jobs /var/run/salt /var/run/salt/master
注意:除了上面的更改之外,还需要修改/var/log/salt的权限以其它用户有写入的现有日志文件的权限。 如果你不希望这样做,则必须禁用日志记录功能,否则Salt将报错,因为它无法像系统用户一样写入日志。
如果还要涉及到从早期版本的salt升级,则也需要删除任何现有用户密钥并重新启动Salt master:
rm /var/cache/salt/.*key
service salt-master restart
WHITELIST AND BLACKLIST
可以通过使用白名单指定允许的内容,或通过使用黑名单指定不允许的内容来配置Salt的身份验证系统。 如果指定白名单,则仅允许指定的操作。 如果指定黑名单,则允许所有操作,但黑名单除外。详细配置方法参考 publisher_acl 以及 publisher_acl_blacklist。
EXTERNAL AUTHENTICATION SYSTEM
Salt的外部认证系统(eAuth)允许Salt将授权请求的命令传递给任何外部认证系统,例如PAM或LDAP。
注意:使用PAM作为外部auth系统时,执行eAuth认证请求时要求salt-master以root身份运行,因为此系统需要root访问权来检查身份验证。
EXTERNAL AUTHENTICATION SYSTEM CONFIGURATION
外部认证系统允许特定用户被授予访问权限以执行特定minions上的特定管理功能。 在master配置文件中配置以使用访问控制系统的功能:
external_auth:
pam:
thatch:
- 'web*':
- test.*
- network.*
steve|admin.*:
- .*
上述配置允许用户thatch在与web*目标所匹配的minions上使用test和network模块中的功能函数。 用户steve和以admin开头的登录用户则被授予对所有minions不受限制的管理权限。
Salt将遵循当前的PAM配置,并使用“login”服务进行身份验证。
注意:PAM模块不支持对root用户进行身份的验证
注意:遇到请求超时,state.sls 和 state.highstate 将返回 "Failed to authenticate!"的报错。可以使用
-t
标识来增加这个超时时间。
如果需要提供对wheel modules 或者是 runner modules的使用授权,那么需要注意下面的语法中必须要使用 @syntax
:
external_auth:
pam:
thatch:
- '@wheel' # to allow access to all wheel modules
- '@runner' # to allow access to all runner modules
- '@jobs' # to allow access to the jobs runner and/or wheel module
注意:runner与wheel 使用不同的限定标识
注意:在配置wheel 或 runners的使用授权时是不支持通配符匹配规则的!必须只能明确的使用 @wheel or @runner 标识进行定义。
警告:具有外部身份验证权限的用户,将都可以运行saltutil.findjob函数。 请注意,这可能会无意中暴露一些数据,例如minion ID。
MATCHING SYNTAX
external_auth
字典的结构可以采用以下形式。 用户和函数匹配是精确匹配,支持shell glob模式或正则表达式;minion是复合目标匹配。
By user:
external_auth:
<eauth backend>:
<user or group%>:
- <regex to match function>
By user, by minion:
external_auth:
<eauth backend>:
<user or group%>:
<minion compound target>:
- <regex to match function>
By user, by runner/wheel:
external_auth:
<eauth backend>:
<user or group%>:
<@runner or @wheel>:
- <regex to match function>
By user, by runner+wheel module:
external_auth:
<eauth backend>:
<user or group%>:
<@module_name>:
- <regex to match function without module_name>
GROUPS
在需要将权限应用于外部身份验证系统中的一组用户时,请在ID中附加%:
external_auth:
pam:
admins%:
- '*':
- 'pkg.*'
LIMITING BY FUNCTION ARGUMENTS
函数允许使用的位置参数或关键字参数也可以通过白名单对参数名称进行限制。
New in version 2016.3.0.
external_auth:
pam:
my_user:
- '*':
- 'my_mod.*':
args:
- 'a.*'
- 'b.*'
kwargs:
'kwa': 'kwa.*'
'kwb': 'kwb'
- '@runner':
- 'runner_mod.*':
args:
- 'a.*'
- 'b.*'
kwargs:
'kwa': 'kwa.*'
'kwb': 'kwb'
匹配规则:
- 使用正则匹配参数值
- 如果定义了参数匹配规则,则要求可以作到有唯一匹配的参数值
- 如果一个参数没有定义匹配规则,表示任何参数值均是允许的
- 要跳过一个arg参数时,可以为其使用匹配任何字符串的正则表达式
.*
。即 如果arg0和arg2应该被限制但是夹在中间的arg1和其他参数可以使用任何值:
args:
- 'value0'
- '.*'
- 'value2'
USAGE
在master设备上,支持在命令行中通过使用-a
选项调用外部认证系统。
$ salt -a pam web\* test.version
系统将询问用户访问身份验证系统所需的凭据,然后再发布该命令。
TOKENS
仅使用外部身份验证时,每次调用Salt时都需要身份验证凭据。这可以通过使用Salt tokens来缓解。
令牌是一种短期授权,只需在第一次进行身份验证时添加-T
选项即可轻松创建:
$ salt -T -a pam web\* test.version
这样就将创建出一个时效为12小时(默认情况下)的token令牌。 此令牌存储在活动用户的家目录中一个名为salt_token的文件中。
创建令牌后,salt会将其与所有后续通信一起发送。 在令牌过期之前,都不需要再次输入信息进行用户身份验证了。
在Salt master配置文件中可以定义token的失效时间。 in the Salt master config file.
LDAP AND ACTIVE DIRECTORY
注意:LDAP使用要求系统中已安装python-ldap包。
Salt支持LDAP的用户和组身份验证(以及通过其LDAP接口访问的Active Directory)。
OPENLDAP AND SIMILAR SYSTEMS
LDAP配置信息是在Salt主配置文件中定义。
服务器配置项及其默认值是:
# Server to auth against
auth.ldap.server: localhost
# Port to connect via
auth.ldap.port: 389
# Use TLS when connecting
auth.ldap.tls: False
# Use STARTTLS when connecting
auth.ldap.starttls: False
# LDAP scope level, almost always 2
auth.ldap.scope: 2
# Server specified in URI format
auth.ldap.uri: '' # Overrides .ldap.server, .ldap.port, .ldap.tls above
# Verify server's TLS certificate
auth.ldap.no_verify: False
# Bind to LDAP anonymously to determine group membership
# Active Directory does not allow anonymous binds without special configuration
# In addition, if auth.ldap.anonymous is True, empty bind passwords are not permitted.
auth.ldap.anonymous: False
# FOR TESTING ONLY, this is a VERY insecure setting.
# If this is True, the LDAP bind password will be ignored and
# access will be determined by group membership alone with
# the group memberships being retrieved via anonymous bind
auth.ldap.auth_by_group_membership_only: False
# Require authenticating user to be part of this Organizational Unit
# This can be blank if your LDAP schema does not use this kind of OU
auth.ldap.groupou: 'Groups'
# Object Class for groups. An LDAP search will be done to find all groups of this
# class to which the authenticating user belongs.
auth.ldap.groupclass: 'posixGroup'
# Unique ID attribute name for the user
auth.ldap.accountattributename: 'memberUid'
# These are only for Active Directory
auth.ldap.activedirectory: False
auth.ldap.persontype: 'person'
auth.ldap.minion_stripdomains: []
# Redhat Identity Policy Audit
auth.ldap.freeipa: False
AUTHENTICATING TO THE LDAP SERVER
LDAP身份验证有两个阶段。 首先,Salt进行身份验证以搜索用户的专有名称和组成员身份。 在此阶段中对其进行身份验证的用户通常是具有对LDAP目录的只读访问权限的特殊LDAP系统用户。 Salt搜索目录以确定实际用户的DN和组后,它将以实际运行Salt命令的用户重新进行身份验证。
如果您已经了解DNs的结构,并且LDAP存储中的权限已设置为用户可以查找自己的组成员身份,则第一个和第二个用户可以相同。 要告诉Salt这种情况,请省略auth.ldap.bindpw参数。 请注意,这与使用匿名绑定不同。 大多数LDAP服务器都不允许匿名绑定,如上所述,如果auth.ldap.anonymous为False,则不能使用空密码。
你可以像这样定义binddn
的模板:
auth.ldap.basedn: dc=saltstack,dc=com
auth.ldap.binddn: uid={{ username }},cn=users,cn=accounts,dc=saltstack,dc=com
Salt将使用salt命令行上输入的密码代替bindpw。
要使用两个单独的用户,请在binddn指令中指定LDAP查找用户,并包含一个bindpw的定义,类似这样:
auth.ldap.binddn: uid=ldaplookup,cn=sysaccounts,cn=etc,dc=saltstack,dc=com
auth.ldap.bindpw: mypassword
如前所述,Salt使用过滤器来查找与用户关联的DN。 在查询LDAP时,Salt会替换将{{username}}值替换为用户名。
auth.ldap.filter: uid={{ username }}
DETERMINING GROUP MEMBERSHIPS (OPENLDAP/NON-ACTIVE DIRECTORY)
对于OpenLDAP,要确定组成员身份,一种方法是可以指定包含组数据的OU。 这将被附加在basedn前面来创建一个搜索路径。然后根据auth.ldap.groupclass
、默认posixGroup
和帐户的name
属性(默认情况下为memberUid)来过滤结果。
auth.ldap.groupou: Groups
请注意,从2017年7月起,auth.ldap.groupclass可以引用groupclass或objectClass。 对于某些LDAP服务器(特别是未启用memberOf
overlay的OpenLDAP)来确定组成员资格,我们需要知道objectClass
和memberUid
属性。 通常对于这些服务器,你需要一个posixGroup
的auth.ldap.groupclass
和memberUid
的auth.ldap.groupattribute
。
具有memberOf
overlay的LDAP服务器将具有类似于auth.ldap.groupclass:person
和auth.ldap.groupattribute:memberOf
的条目。
当使用ldap('DC=domain,DC=com')
eauth运算符时,有时从LDAP或Active Directory返回的记录附加了完全限定的域名,而minion ID则是简单的主机名。 以下参数允许管理员剥离指定的某组域名,以便在目录服务中查找到的主机名可以准确匹配minion IDs。
auth.ldap.minion_stripdomains: ['.external.bigcorp.com', '.internal.bigcorp.com']
DETERMINING GROUP MEMBERSHIPS (ACTIVE DIRECTORY)
Active Directory以不同方式处理组成员身份,并且也不使用groupou配置变量。 AD在master配置中需要以下选项:
auth.ldap.activedirectory: True
auth.ldap.filter: sAMAccountName={{username}}
auth.ldap.accountattributename: sAMAccountName
auth.ldap.groupclass: group
auth.ldap.persontype: person
要确定AD中的组成员身份,请求LDAP时输入的用户名和密码作为命令行上的eAuth机制用于绑定到AD的LDAP接口。 如果此操作失败,则无论用户属于哪个组都无关紧要,他将被拒绝访问。 接下来,使用以下LDAP搜索查找用户的distinguishedName
:
(&(<value of auth.ldap.accountattributename>={{username}}) (objectClass=<value of auth.ldap.persontype>) )
这应该返回一个distinguishedName,我们可以用它来过滤组成员资格。 然后执行以下LDAP查询:
(&(member=<distinguishedName from search above>) (objectClass=<value of auth.ldap.groupclass>) )
external_auth:
ldap:
test_ldap_user:
- '*':
- test.ping
要配置LDAP组,请在ID中附加%:
external_auth:
ldap:
test_ldap_group%:
- '*':
- test.echo
此外,如果目录服务中有一组计算机应该是eAuth定义的一部分,则可以像下面这样指定它们:
external_auth:
ldap:
test_ldap_group%:
- ldap('DC=corp,DC=example,DC=com'):
- test.echo
上面的ldap()
中的字符串是任何有效的LDAP/AD tree limiter。 OU=
也是允许使用的,只要它返回的是计算机对象列表即可。
PEER COMMUNICATION
Salt 0.9.0引入了Salt minions发布命令的功能。此功能的目的不是让Salt minions作为另一个独立的brokers,而是让Salt minions将命令传递给对方。
在Salt 0.10.0中,添加了从master服务器执行runners程序的功能。这允许master设备通过对等接口将收集自runners的数据返回给minions。
peer对等接口功能是通过master配置文件中的两个选项进行配置。对于minions从master设备发送命令,使用peer
配置参数。希望允许minions从master执行runners,使用peer_run
配置参数。
允许minions访问和使用master设备publisher服务无疑会带来潜在的安全风险,因此默认情况下关闭该功能。支持使用正则表达式,来限定基于每个minion控制是否允许访问master publisher服务。具有特定ID的minions可以被允许访问某些Salt模块和功能。
PEER CONFIGURATION
在Salt master配置文件中的peer
配置项下进行设置,这里有许多配置的可能性。
最简单的方法是为所有minions启用所有通信支持,这仅建议用于非常安全的环境。
peer:
.*:
- .*
此配置将允许那些ID为以example.com结尾的minions访问test、ps和pkg模块函数。
peer:
.*example.com:
- test.*
- ps.*
- pkg.*
配置逻辑很简单,使用正则表达式定义需要匹配的minion id,然后使用一个正则表达式列表定义可以使用的minion函数列表。 例如,下面的配置还允许以foo.org结尾的minions访问master设备的pulisher服务。
peer:
.*example.com:
- test.*
- ps.*
- pkg.*
.*foo.org:
- test.*
- ps.*
- pkg.*
注意:使用正则表达式匹配函数。
PEER RUNNER COMMUNICATION
允许minions从master设备上执行runners的配置是通过master的peer_run
配置项完成的。 peer_run
配置遵循与peer
选项相同的配置逻辑。 唯一的区别是管理对runner模块的访问权限。
为所有minions开放对所有runners的访问权限:
peer_run:
.*:
- .*
下面的配置将允许ID为以example.com结尾的minions访问manage runner和jobs runner功能函数。
peer_run:
.*example.com:
- manage.*
- jobs.*
注意:使用正则表达式匹配函数。
USING PEER COMMUNICATION
publish 模块是专门用于管理peer通信的一个salt模块。 publish 模块具有许多以不同方式执行peer通信的功能。 目前,publish 模块中有以下三个功能函数。 这些示例将说明如何通过salt-call命令测试peer系统。
在所有的minions上执行 test.version :
# salt-call publish.publish \* test.version
执行 manage.up runner:
# salt-call publish.runner manage.up
需要对目标minions进行匹配过滤时,请使用tgt_type:
# salt-call publish.publish 'webserv* and not G@os:Ubuntu' test.version tgt_type='compound'
在 早于2017.7.0 的发行版本中, 请使用expr_form
代替 tgt_type
.