[英]How to check SSL Kafka topic is authorized using keystore
I have a simple KafkaProducer to produced into SSL Kafka topic using keystore.jks
file我有一个简单的KafkaProducer使用
keystore.jks
文件制作成 SSL Kafka 主题
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("acks", "all");
props.put("retries", 0);
props.put("batch.size", 16384);
props.put("linger.ms", 1);
props.put("buffer.memory", 33554432);
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("security.protocol", "SSL");
props.put("ssl.key.password", "password");
props.put("ssl.keystore.password", "password");
props.put("ssl.keystore.location", "/keystore.jks");
Producer<String, String> producer = new KafkaProducer<>(props);
producer.send(new ProducerRecord<String, String>("my-topic", key, body));
But since KafkaProducer
is a lazy instance and which creates a connection with a Kafka cluster on the arrival of the first message causing failure at runtime if the topic is unauthorized但是由于
KafkaProducer
是一个惰性实例,它会在第一条消息到达时创建与 Kafka 集群的连接,如果主题未经授权,则会导致运行时失败
Error:错误:
org.apache.kafka.common.errors.TopicAuthorizationException: Not authorized to access topics: [my-topic]
org.apache.kafka.common.errors.TopicAuthorizationException:无权访问主题:[my-topic]
Is there a way to check topic authorization either using KafkaAdminClient or writing custom logic before starting KafkaProducer?有没有办法在启动 KafkaProducer 之前使用KafkaAdminClient或编写自定义逻辑来检查主题授权? I do have below code extracting certs & key from
keystore
file but couldn't find any next steps我确实有以下代码从
keystore
文件中提取证书和密钥,但找不到任何后续步骤
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
char[] pwdArray = "password".toCharArray();
keyStore.load(new FileInputStream("/keystore.jks"), pwdArray);
Although you did not configure the necessary properties to trust the Kafka server:尽管您没有配置必要的属性来 信任Kafka 服务器:
ssl.truststore.location=/var/private/ssl/client.truststore.jks
ssl.truststore.password=test1234
probably your SSL setup is fine although, as you indicated, there is some kind of problem related with the authorization of your client:可能您的 SSL 设置很好,但正如您所指出的,存在与您的客户授权相关的某种问题:
org.apache.kafka.common.errors.TopicAuthorizationException: Not authorized to access topics: [my-topic]
org.apache.kafka.common.errors.TopicAuthorizationException:无权访问主题:[my-topic]
Please, consider review the Kafka authorization documentation , especially the part that describes how the user name is derived from the CN
of your client SSL certificate:请考虑查看Kafka 授权文档,尤其是描述用户名如何从客户端 SSL 证书的
CN
派生的部分:
By default, the SSL user name will be of the form "CN=writeuser,OU=Unknown,O=Unknown,L=Unknown,ST=Unknown,C=Unknown".
默认情况下,SSL 用户名的格式为“CN=writeuser,OU=Unknown,O=Unknown,L=Unknown,ST=Unknown,C=Unknown”。 One can change that by setting ssl.principal.mapping.rules to a customized rule in server.properties.
可以通过将 ssl.principal.mapping.rules 设置为 server.properties 中的自定义规则来改变这一点。 This config allows a list of rules for mapping X.500 distinguished name to short name.
此配置允许将 X.500 可分辨名称映射到短名称的规则列表。
Once the user is identified, check that the necessary ACLs are applied for him and the topic my-topic
.识别用户后,检查是否为他和主题
my-topic
应用了必要的 ACL。 Please, see the providedexamples in the documentation.请参阅文档中提供的示例。
For example, to add the above-mentioned user as a producer of the topic my-topic
try something similar to:例如,要将上述用户添加为主题
my-topic
的生产者,请尝试类似以下操作:
bin/kafka-acls.sh --authorizer-properties zookeeper.connect=localhost:2181 --add --allow-principal User:writeuser --producer --topic my-topic
You can verify the ACLs applied to a resource, my-topic
in your use case, with something like:您可以使用以下内容验证应用于资源的 ACL,即用例中的
my-topic
:
bin/kafka-acls.sh --authorizer-properties zookeeper.connect=localhost:2181 --list --topic my-topic
After long research and with the help of answer provided by @jccampanero, I have created a block of java code to list ACLS using AdminClient for a specific topic经过长时间的研究并在@jccampanero 提供的答案的帮助下,我创建了一个 java 代码块,以使用AdminClient针对特定主题列出 ACLS
AdminClient adminClient = KafkaAdminClient.create(configProps);
ResourcePatternFilter resourceFilter = new ResourcePatternFilter(ResourceType.TOPIC,"my-topic", PatternType.ANY);
AclBindingFilter aclBindingFilter = new AclBindingFilter(resourceFilter, AccessControlEntryFilter.ANY);
DescribeAclsResult describe = adminClient.describeAcls(aclBindingFilter);
KafkaFuture<Collection<AclBinding>> values = describe.values();
Collection<AclBinding> aclBindings = values.get();
aclBindings.forEach(acl->{
System.out.println(String.format("%s %s %s",acl.entry().operation().name(),acl.entry().principal(),acl.entry().permissionType().name()));
});
Output: Output:
DESCRIBE User:CN=test-cert.com,O=Corporation,OU=1234567,L=Newyork,ST=NY,C=US ALLOW
WRITE User:CN=CN=test-cert.com,O=Corporation,OU=1234567,L=Newyork,ST=NY,C=US ALLOW
READ User:CN=test-cert.com,O=Corporation,OU=1234567,L=Newyork,ST=NY,C=US ALLOW
Now you can extract the CN
part from AclBinding
and then use it as alias
to get the Certificate
from JSK file现在您可以从
AclBinding
中提取CN
部分,然后将其用作alias
以从 JSK 文件中获取Certificate
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
char[] pwdArray = "password".toCharArray();
keyStore.load(new FileInputStream("/keystore.jks"), pwdArray);
Certificate certificate = keyStore.getCertificate(alias); //alias = test-cert.com
if (certificate instanceof X509Certificate) {
X509Certificate x509cert = (X509Certificate) certificate;
// Get subject
Principal principal = x509cert.getSubjectDN();
String subjectDn = principal.getName();
System.out.println(principal); //test-cert.com
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.