并行 kinit 调用导致损坏的 Kerberos 缓存

Parallel kinit calls lead to a corrupted Kerberos cache

如果我尝试多次并行使用 Kerberos 密钥表进行身份验证,我会随机收到错误消息,指出凭据缓存已损坏。

我可以使用以下脚本重现此问题。但是,在我的实际用例中,有进程同时调用 kinit 而我无法控制它们:

kdestroy
kinit $USER@$REALM -k -t $HOME/$USER.keytab && echo "OK" &
kinit $USER@$REALM -k -t $HOME/$USER.keytab && echo "OK" &
kinit $USER@$REALM -k -t $HOME/$USER.keytab && echo "OK" &
kinit $USER@$REALM -k -t $HOME/$USER.keytab && echo "OK" &
kinit $USER@$REALM -k -t $HOME/$USER.keytab && echo "OK"

每次我 运行 它都会产生随机输出。此类输出的示例如下:

kinit: Failed to store credentials: Internal credentials cache error (filename: /tmp/krb5cc_1645005342) while getting initial credentials
kinit: Failed to store credentials: No credentials cache found (filename: /tmp/krb5cc_1645005342) while getting initial credentials
kinit: Failed to store credentials: Bad format in credentials cache (filename: /tmp/krb5cc_1645005342) while getting initial credentials
OK
OK

有没有办法让 kinit "wait its turn" 不访问缓存,如果它已经被另一个进程访问了?

如果多个进程独立创建票证,则它们没有理由使用相同 凭据缓存。在最坏的情况下,他们甚至会使用不同的主体,而且副作用会很……有趣。

解决方案:更改每个进程的环境,使 KRB5CCNAME 指向特定文件——最好是在特定于应用程序的目录中。这将防止竞争条件,并清理你的烂摊子。

部分解决方案:维护单个缓存,但不基于文件(因为Linux无法强制对文件进行独占锁定) 例如KEYRING.

无论如何,您有权抱怨 sher,这些应用程序的笨拙开发方式。或者也许它们被设计成 运行 在孤立的容器中?

在我们的例子中,我们必须在同一个进程中执行并发作业。最终,使用外部文件锁来同步并行 kinit 调用。

Begin
…

#Assign unused file descriptor e.g. 99 to a file called “kinit_lock.dat”
exec 99 >”kinit_lock.dat”

#try to acquire exclusive lock for “kinit_lock.dat” with timeout of 5 secs.
flock -x -w 5 99

#Invoke kinit
kinit <parameters>

#unlock the kinit lock file
flock -u 99

…
Job script
…

End