通过SSH隧道从Java程序连接启用TLS的AWS DocumentDB问题咨询
Java从AWS外部连接启用TLS的DocumentDB解决方案
错误根因
你收到的javax.net.ssl.SSLHandshakeException: No subject alternative DNS name matching localhost found报错,是因为AWS为DocumentDB签发的SSL证书仅包含集群原生公/内网域名的主题备用名称记录,不包含localhost。你通过SSH隧道将集群端口映射到本地访问时,Java默认的SSL主机名校验机制无法匹配证书信息,因此握手失败。
修复方案
优先采用MongoDB驱动内置的隧道访问适配配置,不需要修改系统设置,仅调整连接参数即可:
- 在MongoDB连接字符串中新增
sslInvalidHostNameAllowed=true参数,关闭SSL主机名匹配校验,该配置仅用于SSH隧道这类可信网络场景,生产公网直连时不要开启。
修改后的测试代码如下:
public class CertsTestMain { public static void main(String[] args) { // 连接字符串新增sslInvalidHostNameAllowed参数 String template = "mongodb://%s:%s@%s/test?ssl=true&replicaSet=rs0&readpreference=%s&sslInvalidHostNameAllowed=true"; String username = "替换为你的DocumentDB用户名"; String password = "替换为你的DocumentDB密码"; String clusterEndpoint = "localhost:27017"; String readPreference = "secondaryPreferred"; String connectionString = String.format(template, username, password, clusterEndpoint, readPreference); String truststore = "C:/Users/eclipse-workspace/certs/certs/rds-truststore.jks"; String truststorePassword = "替换为你的jks信任库密码"; System.setProperty("javax.net.ssl.trustStore", truststore); System.setProperty("javax.net.ssl.trustStorePassword", truststorePassword); MongoClient mongoClient = MongoClients.create(connectionString); MongoDatabase testDB = mongoClient.getDatabase("test"); MongoCollection<Document> bookingCollection = testDB.getCollection("booking"); MongoCursor<Document> cursor = bookingCollection.find().iterator(); try { while (cursor.hasNext()) { System.out.println(cursor.next().toJson()); } } finally { cursor.close(); mongoClient.close(); } } }
额外注意事项
- 确认你的jks信任库是基于AWS官方提供的rds-combined-ca-bundle.pem生成,生成命令参考:
keytool -importcert -file rds-combined-ca-bundle.pem -keystore rds-truststore.jks -alias rds-ca,执行命令时按提示输入密码即可。 - 确认SSH隧道保持正常运行,本地27017端口已正确映射到DocumentDB集群的27017端口,隧道启动命令参考:
ssh -i 你的EC2密钥文件路径 -L 27017:DocumentDB集群域名:27017 ec2-user@EC2公网地址 -N - 代码使用完MongoClient后记得主动关闭,避免连接泄漏。
内容的提问来源于stack exchange,提问作者liz french
相关产品推荐
相关产品推荐

