在带有 AFS 文件的 Ubuntu (Linux) 上,我需要先获得带有“kinit”的 Kerberos 票证,然后才能执行“aklog”来访问 AFS 文件。在执行“aklog”之前,我无法访问存储在 AFS 中的“keytab”文件来执行“kinit”。它似乎是 Catch-22。有什么建议么?我目前正在做类似的事情: echo "password" | 启动用户@领域;这在 Mac OSX 上不起作用,但在 Linux 中起作用。我正在运行无人值守的“cron”作业,这些作业在使用“kinit”和“aklog”建立访问权限之前没有 AFS 访问权限。
1 回答
通常,如果您打算使用该 keytab 对 AFS 进行身份验证,则不要将 keytab 放在 /afs 中。这就像将保险箱的钥匙存放在保险箱内一样;就像你说的,这是第 22 条规则。你也不应该跑步echo "password" | kinit
;您只是用在某处存储密码来替换存储密钥表,而密钥表旨在成为替代echo
密码的高级替代品。如果您echo "password" | kinit
在脚本中的任何位置,其他用户可能能够通过查看进程列表来查看该密码,因此这不是很安全。
通常,您为 cron 作业提供经过身份验证的 AFS 访问的方式是将 keytab 放在本地磁盘上,并让脚本访问它。然后,您可以在 keytab 上设置传统的 Unix 权限,以便只有您可以访问它。无法访问本地磁盘使这变得更加困难,但这是可能的。我可以想到几种方法:
让 Cron 为您获取凭证
在为用户运行 cron 作业时,某些环境能够为特殊的 'cron'-y 用户获取凭据。也就是说,您注册您的 cron 作业以在用户“cron.dguertin”下运行,而不仅仅是“dguertin”。然后,cron 系统本身可以访问 keytab 以验证为“cron.dguertin”,并且您可以设置 AFS ACL 以允许 cron.dguertin 访问您想要的任何文件。我不了解这些系统是如何工作的,但我在斯坦福 CS和斯坦福 IT以及其他地方听说过这个。
当然,必须设置系统才能执行此操作。如果您对基础架构没有任何控制权,那么这对您没有帮助。
在 Cron 中嵌入凭证
假设没有其他人可以读取您的 crontab 的内容(传统的 cron 也是如此,所以我认为在您使用的任何 cron 设置中都是如此),您确实可以将凭据嵌入到 crontab 文件本身中。但是,如上所述,只echo
输入密码通常不是一个好主意,因为有人可以查看进程列表并看到密码。
cron 的某些实现允许您在指定要运行的命令之前设置环境变量。例如:
GUERTIN_PASSWORD=donotuse_TuAk9OgVoigg
# m h dom mon dow command
* * * * * /path/to/script
然后,您的脚本可以读入 GUERTIN_PASSWORD 环境变量的值,并将密码通过管道传递给 kinit,或使用它来解密加密的密钥表/密码等。请确保在读入后取消设置 GUARTIN_PASSWORD 环境变量,这样就可以了不泄漏给子进程。
或者,您实际上可以在 cron 条目中直接嵌入一个 keytab 文件。这有点烦人,因为 keytab 是二进制数据,但它们往往很短。例如,如果您的 keytab 具有以下内容:
$ cat /path/to.keytab | base64
BQIAAABFAAEAC0VYQU1QTEUuQ09NAAdleGFtcGxlAAAAAVUmAlwBABIAILdV5P6NXT8RrTvapcMJ
QxDYCjRQiD0BzxhwS9h0VgyM
然后你可以像这样创建一个 cron 条目:
GUERTIN_KEYTAB=BQIAAABFAAEAC0VYQU1QTEUuQ09NAAdleGFtcGxlAAAAAVUmAlwBABIAILdV5P6NXT8RrTvapcMJQxDYCjRQiD0BzxhwS9h0VgyM
# m h dom mon dow command
* * * * * /path/to/script
然后您的脚本可以解码 base64,将内容写入临时文件,然后运行如下内容:
k5start -U -f "$tmp_keytab" -t -- $rest_of_command
(k5startaklog
为您处理运行和设置 AFS PAG)。或者,使用 kinit/aklog:
kinit -k -t "$tmp_keytab" "$principal" && aklog
只需确保在运行任何命令之前清除 GUARTIN_KEYTAB 环境变量,如前所述。
请注意,并非所有 cron 实现都允许您像这样单独设置环境变量。一些 cron 实现要求您执行以下操作:
* * * * * export FOO=bar; /path/to/script
但这在这种情况下没有用,因为这将导致相关环境变量的内容通过进程列表可见。
将密钥表放入 AFS
你其实可以把keytab放到AFS里面,然后通过IP地址限制访问,这样只有集群上运行的主机才能访问,不需要先通过AFS认证。OpenAFS 确实有一些限制通过 IP 访问的设施,但它们有点笨拙。通常也不建议使用这些,但在某些情况下(例如使用 cron 作业或其他批处理作业),您没有太多选择。这些通常称为“IP ACL”或“主机 ACL”。
为此,您需要为所需的 IP 地址创建一个用户:
$ pts createuser 198.51.100.23
然后您可以像往常一样简单地将其添加到 AFS ACL:
$ fs setacl /path/to/dir 198.51.100.23 rl
如果您想限制对一系列 IP 的访问,AFS 主机 ACL 对通配符 IP 具有一些原始功能:
$ fs setacl /path/to/dir 198.51.100.0 rl
这将允许整个 198.51.100.0/24 范围能够读取该目录。IP 地址中的任何“0”段都将被视为通配符。(您仍然需要创建 198.51.100.0 用户。)如果您想允许访问多个范围或多个单独的 IP,只需将它们添加到 ACL 中,就像您授予多个用户访问权限一样。
请注意,主机 ACL 在首次使用后可能需要几个小时才能生效。这是因为单个主机的权限只会在后台定期重新计算。这可能真的很令人困惑,所以如果你想使用这些,如果它看起来不起作用,只需等待几个小时。
但是,如果您无法创建相关 IP 用户,这将没有用。
将密钥表放在其他地方
或者,您当然可以将密钥表放在网络服务器上,就像您提到的那样,并让网络服务器通过 IP 地址限制对密钥表的访问。同样的方法也适用于将 keytab 的内容放入数据库,并通过 IP 或任何其他可以限制通过 IP 访问的机制来限制对数据库的访问。
要通过网络服务器执行此操作,只需将密钥表放在 /afs 的某个目录中,并限制 AFS ACL 以便只有网络服务器可以读取它(假设网络服务器使用 AFS 凭据运行)。然后将网络服务器配置为仅允许某些 IP 获取该文件。
组合
当然,您也可以结合上述任何方法。如果您不信任来自集群计算机 IP 的所有访问,但您对“在 cron 中嵌入密码”方法并不完全有信心,则可以使用上述机制之一通过 IP 地址限制对 keytab 的访问,并且使用您嵌入在具有环境变量的 crontab 条目中的密码来加密 keytab,如上所述。
此外,我认识到其中许多解决方案非常麻烦和/或迂回。这就是为什么几个站点都有自己的机制来为用户获取特定于 cron 的凭据,因此您不必经历所有这些。如果没有只有您的 cronjobs 可以访问的本地密钥表,所有这些其他方法显然都是 hack-y。