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

Connect to Kafka on Unix from Windows with Kerberos

我对 Kafka 很陌生,所以请多多包涵。这是我的设置。 我在 unix 机器上托管了 kafka。集群。在域中说 B. 客户端在 windows。并尝试使用域 A 连接到托管在 B 上的 kafka。 我有密钥表。和 krb5。这两个都在 envt 中设置。 krb5.ini(并设置为 envt 变量 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
 }

我也设置了 Jaas.config(Kafka.client.ini 在我的例子中设置为 envt 变量 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";

};

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

kafka-console-producer.bat --broker-list <broker list> --topic <mytopic>    --security-protocol SASL_PLAINTEXT

不管我怎么改,我总是报错

"security-protocol is not a recognised option"

有人可以帮我解决这个问题吗? 我还在 producer.properties 中添加了以下道具。但似乎没有任何改变。我不确定我错过了什么

security.protocol=SASL_PLAINTEXT
sasl.kerberos.service.name=kafka

我什至尝试在 kafka-console-producer.bat 中设置这个 属性 但没有成功

set KAFKA_CLIENT_KERBEROS_PARAMS=- Djava.security.auth.login.config=..\..\config\kafka_Connection.ini

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

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

来自 Kerberos MIT 文档关于 krb5.conf 部分 [capaths]

In order to perform direct (non-hierarchical) cross-realm authentication, configuration is needed to determine the authentication paths between realms.

A client will use this section to find the authentication path between its realm and the realm of the server.

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


场景1 >> 两个realm都是"brother"AD域,相互信任,并且使用默认的 hierarchical 关系——这意味着在从 USERS 到 [=16 的路径中有一个名为 CORP.DMN 的 "father" AD 域=].

您的 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
}

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


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

在这种情况下,您必须在 [capaths] 部分明确定义 "path",如 Kerberos 文档中所述。


场景3 >> 领域之间没有信任。你完蛋了。

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


底线:您必须需要 AD 管理员的帮助。也许他们不熟悉原始 Kerberos conf,但他们会了解信任和 "paths";在这一点上,只需遵循正确的 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