Я пытался подключить сервер mongodb с TLS 1.2 через драйвер java, однако получал сбой при рукопожатии, который я не могу понять, почему. Вот мои настройки
- Сервер MongoDB 4.2.1
- mongod.conf:
net:
bindIp: 127.0.0.1
port: 27017
tls:
mode: requireTLS
CAFile: <location-to-ca.crt>
certificateKeyFile: <location-to-server.pem>
disabledProtocols: TLS1_0,TLS1_1
- JDK: 1.8.0_202
- пн go - java -драйвер: 3.12.3
private static void Tls1_2Test() throws Exception {
SSLContext sslContext = createSSLContext();
MongoClientSettings settings = MongoClientSettings.builder()
.applyToSslSettings(builder -> {
builder.enabled(true);
builder.context(sslContext);
builder.invalidHostNameAllowed(true);
})
.build();
try (MongoClient client = MongoClients.create(settings)) {
for (String s : client.listDatabaseNames()) {
System.out.println(s);
}
}
catch (Exception e) {
e.printStackTrace();
}
}
public static SSLContext createSSLContext() throws Exception {
// root CA
TrustManagerFactory tmf;
try (InputStream is = new FileInputStream("<location-to-ca.crt>")) {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate caCert = (X509Certificate) cf.generateCertificate(is);
tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null); // You don't need the KeyStore instance to come from a file.
ks.setCertificateEntry("caCert", caCert);
tmf.init(ks);
}
// client key
KeyManagerFactory keyFac;
try (InputStream is = Test.class.getResourceAsStream("<location-to-client.pem>")) {
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
keystore.load(is, null);
keyFac = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyFac.init(keystore, null);
}
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(keyFac.getKeyManagers(), tmf.getTrustManagers(), null);
return sslContext;
}
Если Я не использую CAFile и не использую allowConnectionsWithoutCertificates: true
в конфигурации, я могу подключиться, так как сервер не заботится о доверенных правах для рукопожатия. Однако я не могу найти, что не так с кодом java, так что сервер не получает сертификат CA для использования при рукопожатии.
Обратите внимание, что net .tls.CAFile в конфигурации mongod и root CA на java код, указывающий на тот же файл. Я также пытался использовать файл .pem в net .tls.CAFile, но получил тот же результат.
Вот консоль java, когда я пытаюсь подключиться:
14:39:55.501 [main] INFO org.mongodb.driver.cluster - Cluster created with settings {hosts=[127.0.0.1:27017], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms', maxWaitQueueSize=500}
14:39:55.524 [main] DEBUG org.mongodb.driver.cluster - Updating cluster description to {type=UNKNOWN, servers=[{address=127.0.0.1:27017, type=UNKNOWN, state=CONNECTING}]
14:39:55.536 [main] INFO org.mongodb.driver.cluster - Cluster description not yet available. Waiting for 30000 ms before timing out
14:39:55.641 [cluster-ClusterId{value='5e98521b6091fb316cd91fbe', description='null'}-127.0.0.1:27017] DEBUG org.mongodb.driver.connection - Closing connection connectionId{localValue:1}
14:39:55.643 [cluster-ClusterId{value='5e98521b6091fb316cd91fbe', description='null'}-127.0.0.1:27017] INFO org.mongodb.driver.cluster - Exception in monitor thread while connecting to server 127.0.0.1:27017
com.mongodb.MongoSocketReadException: Exception receiving message
at com.mongodb.internal.connection.InternalStreamConnection.translateReadException(InternalStreamConnection.java:569)
at com.mongodb.internal.connection.InternalStreamConnection.receiveMessage(InternalStreamConnection.java:448)
at com.mongodb.internal.connection.InternalStreamConnection.receiveCommandMessageResponse(InternalStreamConnection.java:299)
at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:259)
at com.mongodb.internal.connection.CommandHelper.sendAndReceive(CommandHelper.java:83)
at com.mongodb.internal.connection.CommandHelper.executeCommand(CommandHelper.java:33)
at com.mongodb.internal.connection.InternalStreamConnectionInitializer.initializeConnectionDescription(InternalStreamConnectionInitializer.java:105)
at com.mongodb.internal.connection.InternalStreamConnectionInitializer.initialize(InternalStreamConnectionInitializer.java:62)
at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:129)
at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:117)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:210)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
at sun.security.ssl.InputRecord.read(InputRecord.java:503)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:975)
at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:933)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:105)
at com.mongodb.internal.connection.SocketStream.read(SocketStream.java:109)
at com.mongodb.internal.connection.InternalStreamConnection.receiveResponseBuffers(InternalStreamConnection.java:580)
at com.mongodb.internal.connection.InternalStreamConnection.receiveMessage(InternalStreamConnection.java:445)
... 9 common frames omitted
14:39:55.644 [cluster-ClusterId{value='5e98521b6091fb316cd91fbe', description='null'}-127.0.0.1:27017] DEBUG org.mongodb.driver.cluster - Updating cluster description to {type=UNKNOWN, servers=[{address=127.0.0.1:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketReadException: Exception receiving message}, caused by {java.net.SocketException: Connection reset}}]
14:39:56.174 [cluster-ClusterId{value='5e98521b6091fb316cd91fbe', description='null'}-127.0.0.1:27017] DEBUG org.mongodb.driver.connection - Closing connection connectionId{localValue:2}
14:39:56.174 [cluster-ClusterId{value='5e98521b6091fb316cd91fbe', description='null'}-127.0.0.1:27017] DEBUG org.mongodb.driver.cluster - Updating cluster description to {type=UNKNOWN, servers=[{address=127.0.0.1:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketReadException: Exception receiving message}, caused by {java.net.SocketException: Connection reset}}]
14:39:56.699 [cluster-ClusterId{value='5e98521b6091fb316cd91fbe', description='null'}-127.0.0.1:27017] DEBUG org.mongodb.driver.connection - Closing connection connectionId{localValue:3}
14:39:56.700 [cluster-ClusterId{value='5e98521b6091fb316cd91fbe', description='null'}-127.0.0.1:27017] DEBUG org.mongodb.driver.cluster - Updating cluster description to {type=UNKNOWN, servers=[{address=127.0.0.1:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketReadException: Exception receiving message}, caused by {java.net.SocketException: Connection reset}}]
14:39:57.228 [cluster-ClusterId{value='5e98521b6091fb316cd91fbe', description='null'}-127.0.0.1:27017] DEBUG org.mongodb.driver.connection - Closing connection connectionId{localValue:4}
14:39:57.228 [cluster-ClusterId{value='5e98521b6091fb316cd91fbe', description='null'}-127.0.0.1:27017] DEBUG org.mongodb.driver.cluster - Updating cluster description to {type=UNKNOWN, servers=[{address=127.0.0.1:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketReadException: Exception receiving message}, caused by {java.net.SocketException: Connection reset}}]
Process finished with exit code 130 (interrupted by signal 2: SIGINT)
Здесь это журнал сервера, когда я пытаюсь подключиться:
2020-04-16T14:39:57.227+0200 I NETWORK [conn4] Error receiving request from client: SSLHandshakeFailed: SSL peer certificate validation failed: no SSL certificate provided by peer: No error.; connection rejected. Ending connection from 127.0.0.1:52955 (connection id: 4)
Заранее спасибо