并行 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
如果我尝试多次并行使用 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