This is an automated email from the ASF dual-hosted git repository.
haonan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/master by this push:
new e03560fa653 Fix ratis TLS not working (#16510)
e03560fa653 is described below
commit e03560fa653950fee43714c0a177ed33059859cf
Author: Haonan <[email protected]>
AuthorDate: Mon Sep 29 09:31:23 2025 +0800
Fix ratis TLS not working (#16510)
---
.../tests/integration/sqlalchemy/test_dialect.py | 2 +-
.../apache/iotdb/consensus/ratis/RatisClient.java | 13 +++-
.../iotdb/consensus/ratis/RatisConsensus.java | 9 ++-
.../utils/NoHostnameVerificationTrustManager.java | 88 ++++++++++++++++++++++
.../apache/iotdb/consensus/ratis/utils/Utils.java | 9 ++-
pom.xml | 1 +
6 files changed, 115 insertions(+), 7 deletions(-)
diff --git
a/iotdb-client/client-py/tests/integration/sqlalchemy/test_dialect.py
b/iotdb-client/client-py/tests/integration/sqlalchemy/test_dialect.py
index c0ff1ddced6..9ed0c808917 100644
--- a/iotdb-client/client-py/tests/integration/sqlalchemy/test_dialect.py
+++ b/iotdb-client/client-py/tests/integration/sqlalchemy/test_dialect.py
@@ -77,7 +77,7 @@ def test_dialect():
# test get_schema_names
schema_names = insp.get_schema_names()
if not operator.ge(
- schema_names, ["root.__system", "root.cursor", "root.cursor_s1"]
+ schema_names, ["root.__audit", "root.cursor", "root.cursor_s1"]
):
test_fail()
print_message("Actual result " + str(schema_names))
diff --git
a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/RatisClient.java
b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/RatisClient.java
index 43f0a82561c..7b674493e1b 100644
---
a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/RatisClient.java
+++
b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/RatisClient.java
@@ -27,6 +27,7 @@ import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.ratis.client.RaftClient;
import org.apache.ratis.client.RaftClientRpc;
+import org.apache.ratis.conf.Parameters;
import org.apache.ratis.conf.RaftProperties;
import org.apache.ratis.protocol.RaftGroup;
import org.apache.ratis.protocol.exceptions.LeaderSteppingDownException;
@@ -89,16 +90,19 @@ class RatisClient implements AutoCloseable {
private final RaftProperties raftProperties;
private final RaftClientRpc clientRpc;
private final RatisConfig.Client config;
+ private final Parameters parameters;
public Factory(
ClientManager<RaftGroup, RatisClient> clientManager,
RaftProperties raftProperties,
RaftClientRpc clientRpc,
- RatisConfig.Client config) {
+ RatisConfig.Client config,
+ Parameters parameters) {
super(clientManager);
this.raftProperties = raftProperties;
this.clientRpc = clientRpc;
this.config = config;
+ this.parameters = parameters;
}
@Override
@@ -116,6 +120,7 @@ class RatisClient implements AutoCloseable {
.setRaftGroup(group)
.setRetryPolicy(new RatisRetryPolicy(config))
.setClientRpc(clientRpc)
+ .setParameters(parameters)
.build(),
clientManager));
}
@@ -131,16 +136,19 @@ class RatisClient implements AutoCloseable {
private final RaftProperties raftProperties;
private final RaftClientRpc clientRpc;
private final RatisConfig.Client config;
+ private final Parameters parameters;
public EndlessRetryFactory(
ClientManager<RaftGroup, RatisClient> clientManager,
RaftProperties raftProperties,
RaftClientRpc clientRpc,
- RatisConfig.Client config) {
+ RatisConfig.Client config,
+ Parameters parameters) {
super(clientManager);
this.raftProperties = raftProperties;
this.clientRpc = clientRpc;
this.config = config;
+ this.parameters = parameters;
}
@Override
@@ -157,6 +165,7 @@ class RatisClient implements AutoCloseable {
.setProperties(raftProperties)
.setRaftGroup(group)
.setRetryPolicy(new RatisEndlessRetryPolicy(config))
+ .setParameters(parameters)
.setClientRpc(clientRpc)
.build(),
clientManager));
diff --git
a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/RatisConsensus.java
b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/RatisConsensus.java
index 434411dd051..045fa779174 100644
---
a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/RatisConsensus.java
+++
b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/RatisConsensus.java
@@ -122,6 +122,7 @@ class RatisConsensus implements IConsensus {
private final RaftProperties properties = new RaftProperties();
private final RaftClientRpc clientRpc;
+ private final Parameters parameters;
private final IClientManager<RaftGroup, RatisClient> clientManager;
private final IClientManager<RaftGroup, RatisClient>
reconfigurationClientManager;
@@ -158,7 +159,7 @@ class RatisConsensus implements IConsensus {
RaftServerConfigKeys.setStorageDir(properties,
Collections.singletonList(storageDir));
GrpcConfigKeys.Server.setPort(properties,
config.getThisNodeEndPoint().getPort());
- Parameters parameters = Utils.initRatisConfig(properties,
config.getRatisConfig());
+ this.parameters = Utils.initRatisConfig(properties,
config.getRatisConfig());
this.config = config.getRatisConfig();
this.readOption = this.config.getRead().getReadOption();
this.canServeStaleRead =
@@ -223,6 +224,7 @@ class RatisConsensus implements IConsensus {
.setServerId(myself.getId())
.setProperties(properties)
.setOption(RaftStorage.StartupOption.RECOVER)
+ .setParameters(parameters)
.setStateMachineRegistry(
raftGroupId ->
new ApplicationStateMachineProxy(
@@ -1034,8 +1036,9 @@ class RatisConsensus implements IConsensus {
new GenericKeyedObjectPool<>(
isReconfiguration
? new RatisClient.EndlessRetryFactory(
- manager, properties, clientRpc, config.getClient())
- : new RatisClient.Factory(manager, properties, clientRpc,
config.getClient()),
+ manager, properties, clientRpc, config.getClient(),
parameters)
+ : new RatisClient.Factory(
+ manager, properties, clientRpc, config.getClient(),
parameters),
new ClientPoolProperty.Builder<RatisClient>()
.setMaxClientNumForEachNode(config.getClient().getMaxClientNumForEachNode())
.build()
diff --git
a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/utils/NoHostnameVerificationTrustManager.java
b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/utils/NoHostnameVerificationTrustManager.java
new file mode 100644
index 00000000000..fb5c9085488
--- /dev/null
+++
b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/utils/NoHostnameVerificationTrustManager.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.consensus.ratis.utils;
+
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.X509ExtendedTrustManager;
+import javax.net.ssl.X509TrustManager;
+
+import java.net.Socket;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+public class NoHostnameVerificationTrustManager extends
X509ExtendedTrustManager {
+
+ private final X509TrustManager delegate;
+
+ public NoHostnameVerificationTrustManager(X509TrustManager delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public X509Certificate[] getAcceptedIssuers() {
+ return delegate.getAcceptedIssuers();
+ }
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] chain, String authType)
+ throws CertificateException {
+ delegate.checkClientTrusted(chain, authType);
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] chain, String authType)
+ throws CertificateException {
+ delegate.checkServerTrusted(chain, authType);
+ }
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] chain, String authType,
Socket socket)
+ throws CertificateException {
+ if (delegate instanceof X509ExtendedTrustManager) {
+ ((X509ExtendedTrustManager) delegate).checkClientTrusted(chain,
authType, socket);
+ } else {
+ delegate.checkClientTrusted(chain, authType);
+ }
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] chain, String authType,
Socket socket)
+ throws CertificateException {
+ // Skip hostname check by calling base method
+ delegate.checkServerTrusted(chain, authType);
+ }
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] chain, String authType,
SSLEngine engine)
+ throws CertificateException {
+ if (delegate instanceof X509ExtendedTrustManager) {
+ ((X509ExtendedTrustManager) delegate).checkClientTrusted(chain,
authType, engine);
+ } else {
+ delegate.checkClientTrusted(chain, authType);
+ }
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] chain, String authType,
SSLEngine engine)
+ throws CertificateException {
+ // Skip hostname check by calling base method
+ delegate.checkServerTrusted(chain, authType);
+ }
+}
diff --git
a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/utils/Utils.java
b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/utils/Utils.java
index ca8f71ddf9e..1a62743d2d7 100644
---
a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/utils/Utils.java
+++
b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/utils/Utils.java
@@ -55,6 +55,7 @@ import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
import java.io.File;
import java.io.InputStream;
@@ -385,7 +386,13 @@ public class Utils {
TrustManagerFactory tmf =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(trustStore);
- TrustManager trustManager = tmf.getTrustManagers()[0];
+ TrustManager originalTrustManager = tmf.getTrustManagers()[0];
+
+ // The self-signed certification may not set Subject Alternative Name
(SAN)
+ // Thrift with ssl didn't check it, but Grpc did.
+ // Wrap to disable the verification
+ TrustManager trustManager =
+ new NoHostnameVerificationTrustManager((X509TrustManager)
originalTrustManager);
GrpcConfigKeys.TLS.setConf(parameters, new GrpcTlsConfig(keyManager,
trustManager, true));
} catch (Exception e) {
LOGGER.error("Failed to read key store or trust store.", e);
diff --git a/pom.xml b/pom.xml
index dd35c7987f0..8f962181a02 100644
--- a/pom.xml
+++ b/pom.xml
@@ -155,6 +155,7 @@
<sonar.coverage.jacoco.xmlReportPaths>target/jacoco-merged-reports/jacoco.xml</sonar.coverage.jacoco.xmlReportPaths>
<!-- Exclude all generated code -->
<sonar.exclusions>**/generated-sources</sonar.exclusions>
+ <sonar.test.exclusions>**/test/**</sonar.test.exclusions>
<!-- URL of the ASF SonarQube server -->
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
<sonar.java.checkstyle.reportPaths>target/checkstyle-report.xml</sonar.java.checkstyle.reportPaths>