Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Kafka client SSL setup

My setup:

  • JDK 11.0.6
  • Spring Boot 2.2.4.RELEASE
  • spring-kafka 2.4.1

I have verified my Zookeeper / Kafka / client application in PLAINTEXT, all works fine. I have also verified my keystores / trust stores with the Kafka client tools.

I am using the KafkaAdmin bean to configure my topics, it appears to be failing on the SSL connection:

@Bean
public KafkaAdmin kafkaAdmin() {
    Map<String, Object> configs = new HashMap<>();
    configs.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, getKafkaHost());
    configs.put("security.protocol", "SSL");
    configs.put("ssl.key.password", "xxx");
    configs.put("ssl.keystore.location", "/keystore/client.keystore.jks");
    configs.put("ssl.keystore.password", "xxx");
    configs.put("ssl.truststore.location", "/keystore/kafka.truststore.jks");
    configs.put("ssl.truststore.password", "xxx");
    return new KafkaAdmin(configs);
}

my two JKS files are in src/main/resources/keystore in my Project. /keystore doesn't work... it seems like they are getting picked up if I specify /src/main/resources/keystore/client.keystore.jks... is that going to work in the real world? At runtime in a standalone tomcat, there is going to be a /src/main/resources/keystore?

From my understanding, paths are relative to the target/classes folder, no?

like image 919
SledgeHammer Avatar asked Nov 24 '25 04:11

SledgeHammer


1 Answers

Kafka client or Spring couldn't resolve .jks file provided directly with the path even if you provide an absolute path. Provide a relative path like src/main/resources/keystore is not a good idea because after the build your resources directory content would directly copy into target/classes as you know already.

So, bind the file directly to a org.springframework.core.io.Resource type instance using value annotation from classpath.

@Value("classpath:certs/keystore/kafka.keystore.jks")
private Resource keystore;

@Value("classpath:certs/truststore/kafka.truststore.jks")
private Resource truststore;

Then get the absolute path from that instance like this;

configs.put("ssl.keystore.location", keystore.getFile().getAbsolutePath());
configs.put("ssl.truststore.location", truststore.getFile().getAbsolutePath());

As you can see, Keystore and Truststore file should be in the classpath. In my case, they are in src/resources/certs/keystore and src/resources/certs/truststore directories respectively.

like image 183
Sachith Dickwella Avatar answered Nov 25 '25 17:11

Sachith Dickwella