有哪些方法可以验证kerberos keytab文件的有效性?

简介: 有哪些方法可以验证kerberos keytab文件的有效性?

1 Keytab 文件概述

  • 在开启了kerberos安全认证的环境中,任何用户进行任何操作之前,都要首先通过 AS_REQ 请求向 KDC 的 AS 进行认证以获得总票据 tgt,然后才能通过 TGS_REQ 请求向 KDC 的 TGS申请具体的服务票据 ticket;
  • 而在进行 AS_REQ 请求时,可以通过命令行交互式手动输入密码的方式(比如执行命令 kinit dap),也可以通过keytab文件的方式(比如JAVA代码中的org.apache.hadoop.security.UserGroupInformation#loginUserFromKeytab(String user,String path),或命令行的 kinit dap -kt dap.keytab);
  • keytab 文件包含了单个或多个principal(用户/组/服务/服务器)的身份认证信息(即key),在功能上等同于密码,且有些管理员倾向于定期为 principal 生成符合密码策略 password policy 的随机密码以增强其安全性,所以 keytab 文件的安全性和重要性不言而喻。

image.png


2 keytab文件的有效性概述

管理员经常会在kdc服务端更改某个 principal 的密码,常见的更改密码的场景有:

  • 比如通过命令显示更改密码:kpasswd;
  • 比如通过脚本定期显示更改密码 (password rotation);
  • 比如通过命令kadmin.local -q "xst -k dap.keytab dap",在生成新的keytab文件时隐式同步更改密码。

无论哪种场景,一旦服务端更改密码后,原有的已经分发给客户端的keytab文件都将失效,所有客户端需要验证其keytab的有效性。 由于 keytab 文件是加密的二进制格式,我们并不能通过 less/cat等命令直接查看其内容,那么怎么验证keytab文件的有效性呢?

3 使用 klist 命令查看对比新老 keytab 文件以验证其有效性

  • 每个keytab文件可以包括多个principa的认证信息,也可以包括同一个principal的多个版本的认证信息;
  • 可以通过 klist -ekt xxx.keytab 查看keytab文件内容,在输出内容中的 KVNO 列代表 key version number,较新版本对应列的KVNO值会更大,klist/kinit等命令或程序使用该keytab文件进行认证时,会自动选择并使用KVNO值最大的列;
  • 可以通过以下命令在不更改某个principal原有密码的情况下,将其认证信息写入当前路径下的某个keytab文件中(如果当前路径不存在该keytab文件,则会新建该文件;如果当前路径存在该Keytab文件,则会将该principal认证信息追加到该keytab文件中):kadmin.local -q "xst -norandkey -k spark2.keytab dap2";
  • 可以通过以下命令,更改某个principal的旧密码并生成随机新密码,然后将其新认证信息写入当前路径下的某个keytab文件中(如果当前路径不存在该keytab文件,则会新建该文件;如果当前路径存在该Keytab文件,则会将该principal认证信息追加到该keytab文件中):kadmin.local -q "xst -k spark2.keytab dap2";
  • Multiple keys can be present in a keytab file,the version of the key is shown in its key version number (KVNO).,Refreshing (also called rotating) the principal's key increments the KVNO in the keytab entry.
  • When a key is refreshed, a new entry is added to the keytab with a higher KVNO. The original key remains in the keytab but is no longer used to issue tickets.

image.png


4 使用keytab文件进行认证并查看相关日志

可以通过kinit命令或JAVA代码使用keytab文件进行认证,以验证其有效性。 为进一步细致排查问题,也可以通过以下方式调整kerberos日志级别:

  • 通用配置 OS-level Kerberos Debugging: export KRB5_TRACE=/tmp/kinit.log (技术背景:User can set an environment variable called KRB5_TRACE to a filename or to /dev/stdout, Kerberos programs like kinit, klist and kvno etc., as well as Kerberos libraries libkrb5*, will start printing more interesting details.This is a very powerfull feature and can be used to debug any program which uses Kerberos libraries);
  • JAVA程序,可以配置 JVM Kerberos Library logging:-Dsun.security.krb5.debug=true
  • JAVA程序,可以配置 JVM SPNEGO Logging:-Dsun.security.spnego.debug=true
  • HADOOP可以配置 Hadoop-side JAAS debugging:export HADOOP_JAAS_DEBUG=true
  • HADOOP可以配置 HADOOP_OPTS environment variable:export HADOOP_OPTS="-Djava.net.preferIPv4Stack=true -Dsun.security.krb5.debug=true ${HADOOP_OPTS}“
  • if the env variable HADOOP_JAAS_DEBUG is set to true,then hadoop UGI will set the "debug" flag on any JAAS files it creates;
  • 针对HADOOP配置环境变量时,可以通过以下命令查看环境变量:echo $HADOOP_OPTS(不是 export $HADOOP_OPTS!!!!);

因为 keytab 文件失效而认证失败时,常见的两个错误如下:

## 错误1:javax.security.auth.login.LoginException: Checksum failed,完整信息如下:
Caused by: org.apache.hadoop.security.KerberosAuthException: failure to login: for principal: dap2@CDH.COM from keytab ./dap2.keytab javax.security.auth.login.LoginException: Checksum failed
        at org.apache.hadoop.security.UserGroupInformation.doSubjectLogin(UserGroupInformation.java:1846) ~[hadoop-common-3.1.4.jar:?]
        at org.apache.hadoop.security.UserGroupInformation.loginUserFromKeytabAndReturnUGI(UserGroupInformation.java:1214) ~[hadoop-common-3.1.4.jar:?]
        at org.apache.hadoop.security.UserGroupInformation.loginUserFromKeytab(UserGroupInformation.java:1007) ~[hadoop-common-3.1.4.jar:?]
        at com.hundsun.broker.dsc.biz.pub.util.JdbcEntityUtils.getHiveJdbcEntity(JdbcEntityUtils.java:867) ~[dsc-biz-pub.jar:?]
        at com.hundsun.broker.dsc.biz.pub.util.JdbcEntityUtils.loadPropConfig(JdbcEntityUtils.java:678) ~[dsc-biz-pub.jar:?]
        at com.hundsun.broker.dsc.biz.pub.util.JdbcEntityUtils.<clinit>(JdbcEntityUtils.java:93) ~[dsc-biz-pub.jar:?]
        ... 2 more
Caused by: javax.security.auth.login.LoginException: Checksum failed
        at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:804) ~[?:1.8.0_201]
        at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:617) ~[?:1.8.0_201]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_201]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_201]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_201]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_201]
        at javax.security.auth.login.LoginContext.invoke(LoginContext.java:755) ~[?:1.8.0_201]
        at javax.security.auth.login.LoginContext.access$000(LoginContext.java:195) ~[?:1.8.0_201]
        at javax.security.auth.login.LoginContext$4.run(LoginContext.java:682) ~[?:1.8.0_201]
        at javax.security.auth.login.LoginContext$4.run(LoginContext.java:680) ~[?:1.8.0_201]
        at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_201]
        at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680) ~[?:1.8.0_201]
        at javax.security.auth.login.LoginContext.login(LoginContext.java:587) ~[?:1.8.0_201]
        at org.apache.hadoop.security.UserGroupInformation$HadoopLoginContext.login(UserGroupInformation.java:1924) ~[hadoop-common-3.1.4.jar:?]
        at org.apache.hadoop.security.UserGroupInformation.doSubjectLogin(UserGroupInformation.java:1836) ~[hadoop-common-3.1.4.jar:?]
        at org.apache.hadoop.security.UserGroupInformation.loginUserFromKeytabAndReturnUGI(UserGroupInformation.java:1214) ~[hadoop-common-3.1.4.jar:?]
        at org.apache.hadoop.security.UserGroupInformation.loginUserFromKeytab(UserGroupInformation.java:1007) ~[hadoop-common-3.1.4.jar:?]
Caused by: sun.security.krb5.KrbCryptoException: Checksum failed
        at sun.security.krb5.internal.crypto.Aes128CtsHmacSha1EType.decrypt(Aes128CtsHmacSha1EType.java:102) ~[?:1.8.0_201]
        at sun.security.krb5.internal.crypto.Aes128CtsHmacSha1EType.decrypt(Aes128CtsHmacSha1EType.java:94) ~[?:1.8.0_201]
        at sun.security.krb5.EncryptedData.decrypt(EncryptedData.java:175) ~[?:1.8.0_201]
        at sun.security.krb5.KrbAsRep.decrypt(KrbAsRep.java:149) ~[?:1.8.0_201]
        at sun.security.krb5.KrbAsRep.decryptUsingKeyTab(KrbAsRep.java:121) ~[?:1.8.0_201]
        at sun.security.krb5.KrbAsReqBuilder.resolve(KrbAsReqBuilder.java:285) ~[?:1.8.0_201]
        at sun.security.krb5.KrbAsReqBuilder.action(KrbAsReqBuilder.java:361) ~[?:1.8.0_201]
        at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:776) ~[?:1.8.0_201]
        at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:617) ~[?:1.8.0_201]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_201]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_201]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_201]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_201]
        at javax.security.auth.login.LoginContext.invoke(LoginContext.java:755) ~[?:1.8.0_201]
        at javax.security.auth.login.LoginContext.access$000(LoginContext.java:195) ~[?:1.8.0_201]
        at javax.security.auth.login.LoginContext$4.run(LoginContext.java:682) ~[?:1.8.0_201]
        at javax.security.auth.login.LoginContext$4.run(LoginContext.java:680) ~[?:1.8.0_201]
        at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_201]
        at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680) ~[?:1.8.0_201]
        at javax.security.auth.login.LoginContext.login(LoginContext.java:587) ~[?:1.8.0_201]
        at org.apache.hadoop.security.UserGroupInformation$HadoopLoginContext.login(UserGroupInformation.java:1924) ~[hadoop-common-3.1.4.jar:?]
        at org.apache.hadoop.security.UserGroupInformation.doSubjectLogin(UserGroupInformation.java:1836) ~[hadoop-common-3.1.4.jar:?]
        at org.apache.hadoop.security.UserGroupInformation.loginUserFromKeytabAndReturnUGI(UserGroupInformation.java:1214) ~[hadoop-common-3.1.4.jar:?]
        at org.apache.hadoop.security.UserGroupInformation.loginUserFromKeytab(UserGroupInformation.java:1007) ~[hadoop-common-3.1.4.jar:?]
Caused by: java.security.GeneralSecurityException: Checksum failed
        at sun.security.krb5.internal.crypto.dk.AesDkCrypto.decryptCTS(AesDkCrypto.java:451) ~[?:1.8.0_201]
        at sun.security.krb5.internal.crypto.dk.AesDkCrypto.decrypt(AesDkCrypto.java:272) ~[?:1.8.0_201]
        at sun.security.krb5.internal.crypto.Aes128.decrypt(Aes128.java:76) ~[?:1.8.0_201]
        at sun.security.krb5.internal.crypto.Aes128CtsHmacSha1EType.decrypt(Aes128CtsHmacSha1EType.java:100) ~[?:1.8.0_201]
        at sun.security.krb5.internal.crypto.Aes128CtsHmacSha1EType.decrypt(Aes128CtsHmacSha1EType.java:94) ~[?:1.8.0_201]
        at sun.security.krb5.EncryptedData.decrypt(EncryptedData.java:175) ~[?:1.8.0_201]
        at sun.security.krb5.KrbAsRep.decrypt(KrbAsRep.java:149) ~[?:1.8.0_201]
        at sun.security.krb5.KrbAsRep.decryptUsingKeyTab(KrbAsRep.java:121) ~[?:1.8.0_201]
        at sun.security.krb5.KrbAsReqBuilder.resolve(KrbAsReqBuilder.java:285) ~[?:1.8.0_201]
        at sun.security.krb5.KrbAsReqBuilder.action(KrbAsReqBuilder.java:361) ~[?:1.8.0_201]
        at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:776) ~[?:1.8.0_201]
        at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:617) ~[?:1.8.0_201]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_201]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_201]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_201]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_201]
        at javax.security.auth.login.LoginContext.invoke(LoginContext.java:755) ~[?:1.8.0_201]
        at javax.security.auth.login.LoginContext.access$000(LoginContext.java:195) ~[?:1.8.0_201]
        at javax.security.auth.login.LoginContext$4.run(LoginContext.java:682) ~[?:1.8.0_201]
        at javax.security.auth.login.LoginContext$4.run(LoginContext.java:680) ~[?:1.8.0_201]
        at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_201]
        at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680) ~[?:1.8.0_201]
        at javax.security.auth.login.LoginContext.login(LoginContext.java:587) ~[?:1.8.0_201]
        at org.apache.hadoop.security.UserGroupInformation$HadoopLoginContext.login(UserGroupInformation.java:1924) ~[hadoop-common-3.1.4.jar:?]
        at org.apache.hadoop.security.UserGroupInformation.doSubjectLogin(UserGroupInformation.java:1836) ~[hadoop-common-3.1.4.jar:?]
        at org.apache.hadoop.security.UserGroupInformation.loginUserFromKeytabAndReturnUGI(UserGroupInformation.java:1214) ~[hadoop-common-3.1.4.jar:?]
        at org.apache.hadoop.security.UserGroupInformation.loginUserFromKeytab(UserGroupInformation.java:1007) ~[hadoop-common-3.1.4.jar:?]
##错误2:javax.security.auth.login.LoginException: Unable to obtain password from user,完整信息如下:
Caused by: org.apache.hadoop.security.KerberosAuthException: failure to login: for principal: hundsun@FZCN.ORG from keytab ./spark2.keytab javax.security.auth.login.LoginException: Unable to obtain password from user
        at org.apache.hadoop.security.UserGroupInformation.doSubjectLogin(UserGroupInformation.java:1846) ~[hadoop-common-3.1.4.jar:?]
        at org.apache.hadoop.security.UserGroupInformation.loginUserFromKeytabAndReturnUGI(UserGroupInformation.java:1214) ~[hadoop-common-3.1.4.jar:?]
        at org.apache.hadoop.security.UserGroupInformation.loginUserFromKeytab(UserGroupInformation.java:1007) ~[hadoop-common-3.1.4.jar:?]
Caused by: javax.security.auth.login.LoginException: Unable to obtain password from user
        at com.sun.security.auth.module.Krb5LoginModule.promptForPass(Krb5LoginModule.java:897) ~[?:1.8.0_221]
        at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:760) ~[?:1.8.0_221]
        at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:617) ~[?:1.8.0_221]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_221]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_221]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_221]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_221]
        at javax.security.auth.login.LoginContext.invoke(LoginContext.java:755) ~[?:1.8.0_221]
        at javax.security.auth.login.LoginContext.access$000(LoginContext.java:195) ~[?:1.8.0_221]
        at javax.security.auth.login.LoginContext$4.run(LoginContext.java:682) ~[?:1.8.0_221]
        at javax.security.auth.login.LoginContext$4.run(LoginContext.java:680) ~[?:1.8.0_221]
        at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_221]
        at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680) ~[?:1.8.0_221]
        at javax.security.auth.login.LoginContext.login(LoginContext.java:587) ~[?:1.8.0_221]
        at org.apache.hadoop.security.UserGroupInformation$HadoopLoginContext.login(UserGroupInformation.java:1924) ~[hadoop-common-3.1.4.jar:?]
        at org.apache.hadoop.security.UserGroupInformation.doSubjectLogin(UserGroupInformation.java:1836) ~[hadoop-common-3.1.4.jar:?]
        at org.apache.hadoop.security.UserGroupInformation.loginUserFromKeytabAndReturnUGI(UserGroupInformation.java:1214) ~[hadoop-common-3.1.4.jar:?]
        at org.apache.hadoop.security.UserGroupInformation.loginUserFromKeytab(UserGroupInformation.java:1007) ~[hadoop-common-3.1.4.jar:?]


相关文章
|
SQL 安全 Java
一篇文章彻底理解 HIVE 常见的三种 AUTHENTICATION 认证机制的配置与使用
一篇文章彻底理解 HIVE 常见的三种 AUTHENTICATION 认证机制的配置与使用
|
安全 网络安全 数据安全/隐私保护
网站为何会显示“不安全”?又该怎么办呢?
这篇文章概述了导致网站显示为“不安全”的常见原因,并提供了相应的解释和建议。了解这些信息对于网站管理员和普通用户都是重要的,因为它有助于提高网络安全意识和保护个人信息不被泄露。
3681 0
|
3月前
|
消息中间件 Java Kafka
搭建ELK日志收集,保姆级教程
本文介绍了分布式日志采集的背景及ELK与Kafka的整合应用。传统多服务器环境下,日志查询效率低下,因此需要集中化日志管理。ELK(Elasticsearch、Logstash、Kibana)应运而生,但单独使用ELK在性能上存在瓶颈,故结合Kafka实现高效的日志采集与处理。文章还详细讲解了基于Docker Compose构建ELK+Kafka环境的方法、验证步骤,以及如何在Spring Boot项目中整合ELK+Kafka,并通过Logback配置实现日志的采集与展示。
777 64
搭建ELK日志收集,保姆级教程
|
存储 安全 Java
javax.security.auth.login.LoginException: Unable to obtain password from user
假设我们公司有自己的门户网站,现在我们收购了一家公司,他们数据库采用ldap存储用户数据,那么为了他们账户能登陆我们公司项目所以需要集成,而不是再把他们的账户重新在mysql再创建一遍,万一人家有1W个账户呢,不累死了且也不现实啊。我之所以选这么旧的版本,是因为我最后要在自己项目集成,我们项目就是上面版本附近的,所以不能选太高版本,这点请注意各版本之间的兼容性问题。:如果里面的某些配置不知道在哪或者不知道干啥的,可以看我的前面的博客,详细介绍了安装配置等,可以大致了解参数。
357 9
|
SQL 存储 关系型数据库
|
存储 缓存 大数据
Starrocks执行查询报错:Memory of process exceed limit. Used: XXX, Limit: XXX. Mem usage has exceed the limit of BE
Starrocks执行查询报错:Memory of process exceed limit. Used: XXX, Limit: XXX. Mem usage has exceed the limit of BE
|
消息中间件 分布式计算 资源调度
|
SQL 大数据 调度
大数据线上问题排查系列 - HIVE 踩坑记- hive.metastore.dml.events
大数据线上问题排查系列 - HIVE 踩坑记- hive.metastore.dml.events
|
SQL 存储 Java
Hive教程(06)- Hive SerDe序列化与反序列化
Hive教程(06)- Hive SerDe序列化与反序列化
604 0
|
SQL 分布式计算 资源调度
大数据问题排查系列-大数据集群开启 kerberos 认证后 HIVE 作业执行失败
大数据问题排查系列-大数据集群开启 kerberos 认证后 HIVE 作业执行失败

热门文章

最新文章