使用 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
我对 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