1. ホーム
  2. java

[解決済み] Kafka java consumer SSL handshake Error : java.security.cert.CertificateException: サブジェクトの代替名が存在しない

2022-02-08 19:01:09

質問

kafka 2.13-2.4.1を使用して、javaで書かれたkafkaクライアント(コンシューマー)とkafkaクラスタ(3ノード、各ノードには1つのブローカーがある)間のSSL接続を構成しています。 私は、以下の公式ドキュメントを使用しました。 Confluentのドキュメント しかし、コンシューマーとプロデューサーのコンソールはSSLでうまく通信できるのですが、私のJavaコンシューマーアプリを使用すると...............。

package kafkaconsumerssl;
import java.time.Duration;
import java.util.Arrays;
import java.util.Properties;

import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.common.KafkaException;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;

public class KafkaConsumerSSLTest {

    public static void main(String[] args) throws KafkaException {
        Properties props = new Properties();
                props.put("security.protocol", "SSL");
                props.put("ssl.endpoint.identification.algorithm=", "");
                props.put("ssl.truststore.location","/var/private/ssl/kafka.client.truststore.jks");
                props.put("ssl.truststore.password","*******");
                props.put("ssl.keystore.location", "/var/private/ssl/kafka.client.keystore.jks");
                props.put("ssl.keystore.password", "********"); 
                props.put("ssl.key.password", "*******");
                props.put("acks", "all");
                props.put("retries", "0");

                props.setProperty("zk.connnect", "172.31.32.219:2181,172.31.41.226:2181,172.31.33.133:2181");
                props.setProperty("group.id", "ConsumersTest");
                props.setProperty("auto.offset.reset","earliest");
                props.setProperty("enable.auto.commit", "true");
                    props.setProperty("auto.commit.interval.ms", "1000");
                props.setProperty("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
                    props.setProperty("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
                props.setProperty("bootstrap.servers","172.31.41.226:9093,172.31.33.133:9093,172.31.32.219:9093");

                KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
                consumer.subscribe(Arrays.asList("testKafka"));
                ConsumerRecords<String,String> messages = consumer.poll(Duration.ofMillis(4000));
                System.out.printf("reading_records...\n");
                for (ConsumerRecord<String, String> record : messages) {
                            System.out.printf("offset= %d, key = %s, value = %s%n", record.offset(), record.key(), record.value());
                }
                consumer.close();
    }}

そして、私のカフカ・ブローカー設定server.propertiesファイルは:

ssl.truststore.location=/var/private/ssl/kafka.server.truststore.jks
ssl.truststore.password=*******
ssl.keystore.location=/var/private/ssl/kafka.server.keystore.jks
ssl.keystore.password=******
ssl.key.password=******
listeners=PLAINTEXT://172.31.41.226:9092,SSL://172.31.41.226:9093
advertised.listeners=SSL://172.31.41.226:9093,PLAINTEXT://172.31.41.226:9092
ssl.client.auth=required
#security.inter.broker.protocol=SSL
ssl.endpoint.identification.algorithm=

を実行すると java -cp .:/opt/kafka/libs/* -Djavax.net.debug=ssl:handshake KafkaConsumerSSLTest2.java 次のようなエラーが発生します。

javax.net.ssl|ERROR|01|main|2020-03-27 22:55:31.527 UTC|TransportContext.java:312|Fatal (CERTIFICATE_UNKNOWN): No subject alternative names present (
"throwable" : {
  java.security.cert.CertificateException: No subject alternative names present
        at java.base/sun.security.util.HostnameChecker.matchIP(HostnameChecker.java:137)
        at java.base/sun.security.util.HostnameChecker.match(HostnameChecker.java:96)
        at java.base/sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:455)
        at java.base/sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:429)
        at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:283)
        at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:141)
        at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:623)
        at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.onCertificate(CertificateMessage.java:464)
        at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.consume(CertificateMessage.java:360)
        at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
        at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:443)
        at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1061)
        at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1048)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:770)
        at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:995)
        at org.apache.kafka.common.network.SslTransportLayer.runDelegatedTasks(SslTransportLayer.java:402)
        at org.apache.kafka.common.network.SslTransportLayer.handshakeUnwrap(SslTransportLayer.java:484)
        at org.apache.kafka.common.network.SslTransportLayer.doHandshake(SslTransportLayer.java:340)
        at org.apache.kafka.common.network.SslTransportLayer.handshake(SslTransportLayer.java:265)
        at org.apache.kafka.common.network.KafkaChannel.prepare(KafkaChannel.java:170)
        at org.apache.kafka.common.network.Selector.pollSelectionKeys(Selector.java:547)
        at org.apache.kafka.common.network.Selector.poll(Selector.java:483)
        at org.apache.kafka.clients.NetworkClient.poll(NetworkClient.java:547)
        at org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient.poll(ConsumerNetworkClient.java:262)
        at org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient.poll(ConsumerNetworkClient.java:233)
        at org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient.poll(ConsumerNetworkClient.java:212)
        at org.apache.kafka.clients.consumer.internals.AbstractCoordinator.joinGroupIfNeeded(AbstractCoordinator.java:400)
        at org.apache.kafka.clients.consumer.internals.AbstractCoordinator.ensureActiveGroup(AbstractCoordinator.java:340)
        at org.apache.kafka.clients.consumer.internals.ConsumerCoordinator.poll(ConsumerCoordinator.java:471)
        at org.apache.kafka.clients.consumer.KafkaConsumer.updateAssignmentMetadataIfNeeded(KafkaConsumer.java:1267)
        at org.apache.kafka.clients.consumer.KafkaConsumer.poll(KafkaConsumer.java:1231)
        at org.apache.kafka.clients.consumer.KafkaConsumer.poll(KafkaConsumer.java:1211)
        at kafkaconsumerssl.KafkaConsumerSSLTest.main(KafkaConsumerSSLTest2.java:40)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at jdk.compiler/com.sun.tools.javac.launcher.Main.execute(Main.java:404)
        at jdk.compiler/com.sun.tools.javac.launcher.Main.run(Main.java:179)
        at jdk.compiler/com.sun.tools.javac.launcher.Main.main(Main.java:119)}

)
javax.net.ssl|WARNING|01|main|2020-03-27 22:55:31.528 UTC|SSLEngineOutputRecord.java:168|outbound has closed, ignore outbound application data
[2020-03-27 22:55:31,529] ERROR [Consumer clientId=consumer-ConsumersTest-1, groupId=ConsumersTest] Connection to node 2147483645 (/172.31.32.219:9093) failed authentication due to: SSL handshake failed (org.apache.kafka.clients.NetworkClient:745)
Exception in thread "main" java.lang.IllegalArgumentException: 0 > -7
        at java.base/java.util.Arrays.copyOfRange(Arrays.java:4021)
        at java.base/java.util.Arrays.copyOfRange(Arrays.java:3981)
        at jdk.compiler/com.sun.tools.javac.launcher.Main.execute(Main.java:416)
        at jdk.compiler/com.sun.tools.javac.launcher.Main.run(Main.java:179)
        at jdk.compiler/com.sun.tools.javac.launcher.Main.main(Main.java:119)

解決方法は?

を設定する必要があります。 ssl.endpoint.identification.algorithm を空の文字列に変換します。 = ):

props.put("ssl.endpoint.identification.algorithm", "");


上記の方法で問題が解決する場合は、証明書がコンシューマを実行するために使用しているマシンのホスト名と一致していないことを意味することに注意してください。