java - 具有 Kerberos 身份验证的 PCF Kafka - 在本地运行但在 PCF 中失败

标签 java spring-boot apache-kafka kerberos cloud-foundry

我在使用 Kerberos 身份验证通过 SpringBoot 连接到 Kafka 时遇到问题。我正在使用自定义 Kafka 连接管理器,详细信息如下 -

          bootstrap-servers-sasl: node1:9094, node2:9094, node3:9094
          protocol: SASL_SSL
          mechanism: GSSAPI
          kerberos:
            service:
              name: kfkusr
          jaas: 
            config: "com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true storeKey=true keyTab=\"#keytab-name#\" principal=\"abc/node2@domain.NET\";"

其中 #keytab-name# 将在运行时替换为以下值 -

我的本​​地电脑 - C:/Users/MyPC/AppData/Local/Temp/abc.node2_d2254866264751402128.keytab

PCF - /home/vcap/tmp/abc.node2_d2215947326380395062.keytab

本地应用程序运行良好,消息将发送到 Kafka。但是当在 PCF 上运行时失败并出现以下异常 -

2019-08-09T14:40:46.481-05:00 [APP/PROC/WEB/0] [OUT] WARN [9f-3868cbe47d81] org.apache.kafka.clients.NetworkClient o.a.k.c.NetworkClient.processDisconnection(NetworkClient.java:585) - ||||||||||||||Connection to node -1 terminated during authentication. This may indicate that authentication failed due to invalid credentials.
...
...
Failed to send; nested exception is org.apache.kafka.common.errors.TimeoutException: Failed to update metadata after 60000 ms.: org.springframework.kafka.core.KafkaProducerException: Failed to send; nested exception is org.apache.kafka.common.errors.TimeoutException: Failed to update metadata after 60000 ms
...
...
Exception thrown when sending a message with key='null' and payload='<my payload>' to topic <test_topic> :: org.apache.kafka.common.errors.TimeoutException: Failed to update metadata after 60000 ms.

更新 1 -

添加 krb5.conf 文件后,它具有默认领域

[libdefaults]
  default_realm = mydomain.NET

身份验证错误消失,但仍然出现以下错误

Failed to send; nested exception is org.apache.kafka.common.errors.TimeoutException: Failed to update metadata after 60000 ms.: org.springframework.kafka.core.KafkaProducerException: Failed to send; nested exception is org.apache.kafka.common.errors.TimeoutException: Failed to update metadata after 60000 ms

一旦为 org.apache.kafka 启用调试:DEBUG 将显示新错误 -

2019-08-14T09:49:51.947-05:00 [APP/PROC/WEB/0] [OUT] DEBUG [d3-5b28248c661c] org.apache.kafka.clients.NetworkClient o.a.k.c.NetworkClient$DefaultMetadataUpdater.maybeUpdate(NetworkClient.java:907) - ||||||||||||||Initialize connection to node node1:9094 (id: -1 rack: null) for sending metadata request
2019-08-14T09:49:51.947-05:00 [APP/PROC/WEB/0] [OUT] DEBUG [d3-5b28248c661c] org.apache.kafka.clients.NetworkClient o.a.k.c.NetworkClient.initiateConnect(NetworkClient.java:762) - ||||||||||||||Initiating connection to node node1:9094 (id: -1 rack: null)
2019-08-14T09:49:51.948-05:00 [APP/PROC/WEB/0] [OUT] DEBUG [d3-5b28248c661c] o.a.k.c.s.a.SaslClientAuthenticator o.a.k.c.s.a.SaslClientAuthenticator.setSaslState(SaslClientAuthenticator.java:209) - ||||||||||||||Set SASL client state to SEND_HANDSHAKE_REQUEST
2019-08-14T09:49:51.948-05:00 [APP/PROC/WEB/0] [OUT] DEBUG [d3-5b28248c661c] o.a.k.c.s.a.SaslClientAuthenticator o.a.k.c.s.a.SaslClientAuthenticator$1.run(SaslClientAuthenticator.java:134) - ||||||||||||||Creating SaslClient: client=abc/node1@domain.net;service=kfkusr;serviceHostname=node1;mechs=[GSSAPI]
2019-08-14T09:49:51.949-05:00 [APP/PROC/WEB/0] [OUT] INFO [d3-5b28248c661c] o.a.k.common.network.SaslChannelBuilder o.a.k.c.n.SaslChannelBuilder.buildChannel(SaslChannelBuilder.java:119) - ||||||||||||||Failed to create channel due to : org.apache.kafka.common.KafkaException: Failed to configure SaslClientAuthenticator at org.apache.kafka.common.security.authenticator.SaslClientAuthenticator.configure(SaslClientAuthenticator.java:125) at org.apache.kafka.common.network.SaslChannelBuilder.buildChannel(SaslChannelBuilder.java:116) at org.apache.kafka.common.network.Selector.connect(Selector.java:203) at org.apache.kafka.clients.NetworkClient.initiateConnect(NetworkClient.java:764) at org.apache.kafka.clients.NetworkClient.access$600(NetworkClient.java:60) at org.apache.kafka.clients.NetworkClient$DefaultMetadataUpdater.maybeUpdate(NetworkClient.java:908) at org.apache.kafka.clients.NetworkClient$DefaultMetadataUpdater.maybeUpdate(NetworkClient.java:819) at org.apache.kafka.clients.NetworkClient.poll(NetworkClient.java:431) at org.apache.kafka.clients.producer.internals.Sender.run(Sender.java:224) at org.apache.kafka.clients.producer.internals.Sender.run(Sender.java:162) at java.lang.Thread.run(Thread.java:748)Caused by: org.apache.kafka.common.KafkaException: Failed to create SaslClient with mechanism GSSAPI at org.apache.kafka.common.security.authenticator.SaslClientAuthenticator.createSaslClient(SaslClientAuthenticator.java:140) at org.apache.kafka.common.security.authenticator.SaslClientAuthenticator.configure(SaslClientAuthenticator.java:123) ... 10 common frames omittedCaused by: javax.security.sasl.SaslException: Failure to initialize security context at com.sun.security.sasl.gsskerb.GssKrb5Client.<init>(GssKrb5Client.java:149) at com.sun.security.sasl.gsskerb.FactoryImpl.createSaslClient(FactoryImpl.java:63) at javax.security.sasl.Sasl.createSaslClient(Sasl.java:384) at org.apache.kafka.common.security.authenticator.SaslClientAuthenticator$1.run(SaslClientAuthenticator.java:136) at org.apache.kafka.common.security.authenticator.SaslClientAuthenticator$1.run(SaslClientAuthenticator.java:131) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAs(Subject.java:422) at org.apache.kafka.common.security.authenticator.SaslClientAuthenticator.createSaslClient(SaslClientAuthenticator.java:131) ... 11 common frames omittedCaused by: org.ietf.jgss.GSSException: Invalid name provided (Mechanism level: KrbException: Cannot locate default realm) at sun.security.jgss.krb5.Krb5NameElement.getInstance(Krb5NameElement.java:129) at sun.security.jgss.krb5.Krb5MechFactory.getNameElement(Krb5MechFactory.java:95) at sun.security.jgss.GSSManagerImpl.getNameElement(GSSManagerImpl.java:203) at sun.security.jgss.GSSNameImpl.getElement(GSSNameImpl.java:477) at sun.security.jgss.GSSNameImpl.init(GSSNameImpl.java:201) at sun.security.jgss.GSSNameImpl.<init>(GSSNameImpl.java:170) at sun.security.jgss.GSSManagerImpl.createName(GSSManagerImpl.java:138) at com.sun.security.sasl.gsskerb.GssKrb5Client.<init>(GssKrb5Client.java:107) ... 18 common frames omitted
2019-08-14T09:49:51.949-05:00 [APP/PROC/WEB/0] [OUT] DEBUG [d3-5b28248c661c] org.apache.kafka.clients.NetworkClient o.a.k.c.NetworkClient.initiateConnect(NetworkClient.java:773) - ||||||||||||||Error connecting to node abcNode:9094 (id: -1 rack: null): java.io.IOException: Channel could not be created for socket java.nio.channels.SocketChannel[closed] at org.apache.kafka.common.network.Selector.connect(Selector.java:210) at org.apache.kafka.clients.NetworkClient.initiateConnect(NetworkClient.java:764) at org.apache.kafka.clients.NetworkClient.access$600(NetworkClient.java:60) at org.apache.kafka.clients.NetworkClient$DefaultMetadataUpdater.maybeUpdate(NetworkClient.java:908) at org.apache.kafka.clients.NetworkClient$DefaultMetadataUpdater.maybeUpdate(NetworkClient.java:819) at org.apache.kafka.clients.NetworkClient.poll(NetworkClient.java:431) at org.apache.kafka.clients.producer.internals.Sender.run(Sender.java:224) at org.apache.kafka.clients.producer.internals.Sender.run(Sender.java:162) at java.lang.Thread.run(Thread.java:748)Caused by: org.apache.kafka.common.KafkaException: org.apache.kafka.common.KafkaException: Failed to configure SaslClientAuthenticator at org.apache.kafka.common.network.SaslChannelBuilder.buildChannel(SaslChannelBuilder.java:120) at org.apache.kafka.common.network.Selector.connect(Selector.java:203) ... 8 common frames omittedCaused by: org.apache.kafka.common.KafkaException: Failed to configure SaslClientAuthenticator at org.apache.kafka.common.security.authenticator.SaslClientAuthenticator.configure(SaslClientAuthenticator.java:125) at org.apache.kafka.common.network.SaslChannelBuilder.buildChannel(SaslChannelBuilder.java:116) ... 9 common frames omittedCaused by: org.apache.kafka.common.KafkaException: Failed to create SaslClient with mechanism GSSAPI at org.apache.kafka.common.security.authenticator.SaslClientAuthenticator.createSaslClient(SaslClientAuthenticator.java:140) at org.apache.kafka.common.security.authenticator.SaslClientAuthenticator.configure(SaslClientAuthenticator.java:123) ... 10 common frames omittedCaused by: javax.security.sasl.SaslException: Failure to initialize security context at com.sun.security.sasl.gsskerb.GssKrb5Client.<init>(GssKrb5Client.java:149) at com.sun.security.sasl.gsskerb.FactoryImpl.createSaslClient(FactoryImpl.java:63) at javax.security.sasl.Sasl.createSaslClient(Sasl.java:384) at org.apache.kafka.common.security.authenticator.SaslClientAuthenticator$1.run(SaslClientAuthenticator.java:136) at org.apache.kafka.common.security.authenticator.SaslClientAuthenticator$1.run(SaslClientAuthenticator.java:131) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAs(Subject.java:422) at org.apache.kafka.common.security.authenticator.SaslClientAuthenticator.createSaslClient(SaslClientAuthenticator.java:131) ... 11 common frames omittedCaused by: org.ietf.jgss.GSSException: Invalid name provided (Mechanism level: KrbException: Cannot locate default realm) at sun.security.jgss.krb5.Krb5NameElement.getInstance(Krb5NameElement.java:129) at sun.security.jgss.krb5.Krb5MechFactory.getNameElement(Krb5MechFactory.java:95) at sun.security.jgss.GSSManagerImpl.getNameElement(GSSManagerImpl.java:203) at sun.security.jgss.GSSNameImpl.getElement(GSSNameImpl.java:477) at sun.security.jgss.GSSNameImpl.init(GSSNameImpl.java:201) at sun.security.jgss.GSSNameImpl.<init>(GSSNameImpl.java:170) at sun.security.jgss.GSSManagerImpl.createName(GSSManagerImpl.java:138) at com.sun.security.sasl.gsskerb.GssKrb5Client.<init>(GssKrb5Client.java:107) ... 18 common frames omitted

最佳答案

好吧..我找到了这个问题的解决方案..可能对其他遇到这个问题的人有帮助。

首先,我在 Producer Config 属性中设置 krb5.conf 文件。该文件包含使用 kerberos 发现服务所需的主机、领域和其他详细信息

System.setProperty("java.security.krb5.conf",  <path to conf file>);

我没有直接在属性中设置 jaas 配置,而是创建了 jaas conf 文件并在系统属性中设置它 -

之前的代码是这样的 -

props.put("sasl.jaas.config", jaasConfig);

更改后 -

System.setProperty("java.security.auth.login.config", jaasFile.getPath());

示例 Jaas 配置文件 jaas_client.conf 结构 -

KafkaClient {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
storeKey=true
keyTab="#keytab-name#" 
principal="#principal#";
};

P.S.在 jaas_client.conf 文件中,我在将 #keytab-name# 更新为 keytab 文件的实际路径和 #principal# 值后重写该文件在设置为 SystemProperties

之前使用实际值

当使用以下属性启用调试时,可以设置 Debug模式以查看 JaaS 身份验证和票务日志 -

System.setProperty("sun.security.krb5.debug", ""+<true/false>);

关于java - 具有 Kerberos 身份验证的 PCF Kafka - 在本地运行但在 PCF 中失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57436278/

相关文章:

java - 微服务不从 spring-cloud-config-server 微服务中获取属性

java - JPA 存储库和 Spring Security - 更新对象使密码无效

java - 错误 : Unable to find @SpringBootConfiguration when doing @WebMvcTest for Spring Controller

elasticsearch - GCP/Dataproc 上 Kafka、Spark、Elasticsearch 堆栈的吞吐量

java - 实例化 CommonsHttpSolrServer 时出现异常

java - 在 JavaFX 中调整窗口大小时动态调整图形大小

java - 应用程序引擎网址请求 utf-8 字符变为 '??' 或 '???'

Java:向列表添加新元素<String>

apache-kafka - 配置 Kafka 客户端以连接已发布的 SSL key /证书

java - 卡夫卡控制台消费者。错误 无法建立与节点 0 的连接。代理可能不可用