使用 Kerberos 从 Windows 连接到 Unix 上的 Kafka

KaS*_*aSh 2 kerberos apache-kafka kafka-producer-api

我对卡夫卡还很陌生,所以请耐心等待。这是我的设置。我将 kafka 托管在 unix 盒子上。簇状。在域中,假设 B. 客户端位于 Windows 上。我正在尝试使用域 A 连接到 B 上托管的 kafka。我有密钥表。和 krb5。这两个都是在 envt 中设置的。krb5.ini(并设置为环境变量 KRB5_CONFIG)

 [logging]
 default = CONSOLE
 admin_server = CONSOLE
 kdc = CONSOLE

[libdefaults]
 renew_lifetime = 7d
 clockskew = 324000
 forwardable = true
 proxiable = true
 renewable = true
 default_realm = some.something.COM
  dns_lookup_realm = true
  dns_lookup_kdc = false
 default_tgs_enctypes = somethingelse
 default_tkt_enctypes = somethingelse

 [appdefaults]
   renewable = true

  [realms]
   some.something.COM = {
     kdc = some.something.COM
     admin_server = some.something.COM
 }
Run Code Online (Sandbox Code Playgroud)

我还设置了 Jaas.config(在我的情况下为 Kafka.client.ini 并设置为环境变量 KAFKA_CLIENT_KERBEROS_PARAMS),下面是配置

   KafkaClient {
    com.sun.security.auth.module.Krb5LoginModule required
   useKeyTab=true
   keyTab="sample.keytab"
   storeKey=true
   useTicketCache=true
   serviceName="kafka"
   principal="svcacc@some.something.COM";
Run Code Online (Sandbox Code Playgroud)

};

下载了 apache kafka_2.12-0.10.2.1.tgz 并正在执行此命令。

kafka-console-producer.bat --broker-list <broker list> --topic <mytopic>    --security-protocol SASL_PLAINTEXT
Run Code Online (Sandbox Code Playgroud)

无论我做什么,我都会遇到以下错误

“安全协议不是一个公认的选项”

有人可以帮我吗?我还在 Producer.properties 中添加了以下道具。但似乎一切都没有改变。我不确定我错过了什么

security.protocol=SASL_PLAINTEXT
sasl.kerberos.service.name=kafka
Run Code Online (Sandbox Code Playgroud)

我什至尝试在 kafka-console- Producer.bat 中设置此属性,但没有运气

set KAFKA_CLIENT_KERBEROS_PARAMS=- Djava.security.auth.login.config=..\..\config\kafka_Connection.ini
Run Code Online (Sandbox Code Playgroud)

期待您的意见。非常感谢(我现在无法控制 kafka 服务器,也无法解释为什么它托管在域 B 上)

Sam*_*ter 5

免责声明:我对 Kafka 不太熟悉,并且该错误消息并没有明确暗示 Kerberos 问题。
但鉴于这是跨领域的情况,您可能迟早会遇到 Kerberos 障碍......

来自 Kerberos MIT 文档中有关[capaths]krb5.conf部分的内容

为了执行直接(非分层)跨领域身份验证,需要配置来确定领域之间的身份验证路径

客户端将使用此部分来查找其领域和服务器领域之间的身份验证路径。

换句话说,您获得主体的 Kerberos TGT(票证授予票证),wtf@USERS.CORP.DMN但需要 的 Kerberos 服务票证kafka/brokerhost.some.where@SERVERS.CORP.DMN。每个领域都有自己的 KDC 服务器。您的 Kerberos 客户端(本例中为 Java 实现)必须有一种方法从一个域“跳”到其他域


场景1 >> 两个领域都是相互信任的“兄弟”AD 域,并且它们使用默认的层次关系——这意味着到 的CORP.DMN路径中。USERSSERVERS

你的krb5.conf应该看起来像这样......

[libdefaults]
default_realm = USERS.CORP.DMN
kdc_timeout   = 3000
...

...

[realms]
USERS.CORP.DMN = {
  kdc = roundrobin.siteA.users.corp.dmn
  kdc = roundrobin.bcp.users.corp.dmn
}
SERVERS.CORP.DMN = {
  kdc = dc1.servers.corp.dmn
  kdc = dc2.servers.corp.dmn
  kdc = roundrobin.bcp.servers.corp.dmn
}
CORP.DMN = {
  kdc = roundrobin.corp.dmn
  kdc = roundrobin.bcp.corp.dmn
}
Run Code Online (Sandbox Code Playgroud)

...假设每个域中有多个 AD 域控制器,有时在 DNS 别名后面进行循环分配,再加上单独站点上的另一组 DC 用于 BCP/DRP。它可能比这更简单:-)


场景 2 >> 启用了信任,但关系不使用默认的分层路径。

在这种情况下,您必须在一个部分中显式定义该“路径” [capaths],如 Kerberos 文档中所述。


场景 3 >> 领域之间不存在信任。你完了。

或者更确切地说,您必须获得一个可以在与 Kafka 代理相同的域上进行身份验证的不同用户,例如xyz@SERVERS.CORP.DMN
也许可以使用特定的krb5.conf说明default_realm = SERVERS.CORP.DMN (例如,我在 Windows 上看到过某些 JDK 版本的奇怪行为)


底线:您必须需要 AD 管理员的帮助。也许他们不熟悉原始 Kerberos 配置,但他们会了解信任和“路径”;此时,只需遵循正确的krb5.conf语法即可。

或者,也许 Linux 管理员已经完成了该配置;所以你应该需要一个他们的标准的例子krb5.conf来检查那里是否有跨域的东西。

当然,您应该在 Kafka 生产者中启用Kerberos 调试跟踪:

-Dsun.security.krb5.debug=true
-Djava.security.debug=gssloginconfig,configfile,configparser,logincontext

只是为了记录,但在这里没有用...当通过 HTTP (SPNego) 使用 Keberos 时,有一个附加标志-Dsun.security.spnego.debug=true