我正在尝试为一组具有以下特征的机器设置 Chef 管理的帐户:
- 如果没有本地帐户,则登录被阻止。
- 如果有一个带有 SSH 密钥的本地帐户,则可以使用它们进行身份验证。
- 如果存在具有本地密码的本地帐户,则该密码用于身份验证。
- 如果存在没有本地密码的本地帐户,则使用 Kerberos。
我有那么多工作要做。
但我最不想做的是通过在本地锁定密码(例如使用usermod -L
)来禁用帐户登录。问题是,当本地密码被锁定时,PAM 正在退回到 Kerberos ......并允许访问。
有没有一种方法可以配置 PAM,以便在存在本地密码但被锁定时不会尝试 Kerberos?
到目前为止我能想到的最好的方法是通过用一些不可猜测的东西破坏本地密码来锁定帐户。但这有点粗糙,如果有人不“按程序办事”,那就玩不好了……
我同意 Michael Hampton 的意见——您可以而且应该使用 Kerberos 来做到这一点。但是,如果您确实想通过更改本地计算机上的内容来完成此操作,那么这里有一个应该可行的解决方案。
在您的
sshd_config
中,添加行创建一个名为“blocked”的组。锁定用户的本地密码时,也将其添加到“blocked”组中。
警告!这是一个不应该存在于理智世界中的可怕丑陋的拼凑。然而,它可能对我们生活的地方有用。
这个问题主要是因为
pam_unix.so
检查auth
堆栈中的帐户锁定而不是account
,这对于 PAM 新手来说有点违反直觉。会计决定应该在account
,而不是auth
,但是基于密码字段的影子帐户锁定是执行的。这使它成为一个必要的妥协。在从那里继续并决定如何实施您的修复之前,让我们回顾一下 PAM 定义的管理组:
auth
-- 身份验证问题。将您的调整限制在基于用户提交以进行身份验证的凭据的决策上,特别是因为如果程序实现自己的身份验证方案,它们可能会选择完全绕过此模块。(每个人都忘记的示例:如果启用 SSH 密钥身份验证并成功则sshd
跳过)auth
account
-- 大多数 PAM 新手都忽略了这一点。如果身份验证成功但无论如何都应拒绝用户访问,则应在此处做出决定。(如果 SSH 密钥认证成功sshd
则不会auth
跳过此模块,不像)passwd
- 更改与您在 中定义的服务相关的密码auth
。session
-- 通常与身份验证是否成功无关的杂项任务。记录,安装东西等。根据您的问题描述:
auth
优先考虑本地凭据而不是 krb5 凭据的堆栈,但两者之一必须成功。听起来你已经知道了。account
如果没有定义本地用户,我们需要一个拒绝访问的堆栈。如前所述,pam_unix.so
我们在这方面失败了。passwd
默认值可能适合更改本地密码。session
。根据您提出的自我回答,您似乎知道从哪里开始。
我需要在工作中检查这个,但我想我可以在“pam_krb5”条目之后向堆栈添加一个“pam_exec”条目。这可以运行使用“passwd -S”的脚本来检查用户的密码条目是否未被锁定。
或者我可以通过将用户置于“已阻止”组并使用 pam_succeed_if 来实现,如下所示:
对于一般用途,我不建议混合使用本地帐户和 kerberos 帐户。但是,这个 auth pam 堆栈应该可以满足我们的目的。(您可能还有其他内容,例如
pam_env.so
,您将包括在内。)如果用户的本地密码不正确或被锁定,则身份验证将失败。如果用户没有本地密码,则身份验证使用 kerberos(而非 GSSAPI),如果失败,身份验证将失败。