无法从EC2上的Spring Boot应用连接至RDS Postgres数据库
在同私有VPC环境下,尝试将EC2(RHEL 8)上的Spring Boot应用连接至RDS Postgres数据库时遇到报错:
org.postgresql.util.PSQLException: SSL error: Received fatal alert: handshake_failure
已知信息:
- 本地Spring Boot应用无需SSL即可正常连接RDS,Pgadmin4可带/不带SSL连接
- EC2到RDS的telnet连接正常,且无法修改应用代码
已尝试操作:
- 配置EC2与RDS的安全组入站规则
- 下载RDS区域证书并放置在
/etc/pki/ca-trust/source/anchors/及JVM的cacerts目录 - 从.pem文件生成JKS、CRT文件并放置在JVM目录
- 在
application.properties中尝试两种server.ssl.*相关配置(启用/不启用)
1. 修正数据库连接的SSL配置(核心错误点)
你之前配置的server.ssl.*是Spring Boot应用自身作为HTTPS服务端的配置,和数据库连接的SSL完全无关。需要针对Postgres数据源添加以下配置到application.properties:
# 基础配置,指定SSL模式和证书路径 spring.datasource.url=jdbc:postgresql://<RDS实例端点>:<端口>/<数据库名>?sslmode=verify-full&sslrootcert=/etc/pki/ca-trust/source/anchors/rds-ca-2019-root.pem spring.datasource.username=<数据库用户名> spring.datasource.password=<数据库密码>
若已将证书导入JVM信任库,可简化为:
spring.datasource.url=jdbc:postgresql://<RDS实例端点>:<端口>/<数据库名>?sslmode=verify-full
注:
sslmode=verify-full会验证RDS证书的有效性,是最安全的模式;若临时测试,也可先用sslmode=require跳过证书验证(不推荐生产环境使用)。
2. 确认JVM信任库的证书导入生效
在RHEL 8上,JVM默认cacerts路径通常为/usr/lib/jvm/<你的JDK版本>/jre/lib/security/cacerts,执行以下命令重新导入证书并验证:
# 导入证书(替换证书路径和JDK路径) keytool -import -alias rds-ca -file /etc/pki/ca-trust/source/anchors/rds-ca-2019-root.pem -keystore /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.xxx.x86_64/jre/lib/security/cacerts -storepass changeit # 验证证书是否存在 keytool -list -alias rds-ca -keystore /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.xxx.x86_64/jre/lib/security/cacerts -storepass changeit
若提示“Certificate already exists”,说明已导入,可跳过导入步骤。
3. 通过JVM启动参数强制指定信任库
如果证书导入后仍不生效,可在启动应用时添加JVM参数,强制指定信任库路径:
java -Djavax.net.ssl.trustStore=/usr/lib/jvm/<你的JDK版本>/jre/lib/security/cacerts -Djavax.net.ssl.trustStorePassword=changeit -jar 你的应用.jar
如果用systemd管理应用,修改service文件的ExecStart行:
ExecStart=/usr/bin/java -Djavax.net.ssl.trustStore=/usr/lib/jvm/<你的JDK版本>/jre/lib/security/cacerts -Djavax.net.ssl.trustStorePassword=changeit -jar /path/to/你的应用.jar
4. 检查JDK的SSL协议支持
RDS Postgres默认禁用TLS 1.0/1.1等旧协议,若EC2上的JDK版本较低(如JDK 8早期版本),需强制启用TLS 1.2+,添加以下JVM参数:
java -Djdk.tls.client.protocols=TLSv1.2 -Dhttps.protocols=TLSv1.2 -jar 你的应用.jar
5. 验证RDS的SSL配置
登录AWS控制台,检查RDS实例的:
SSL连接设置为允许或强制- 关联的参数组中,
ssl参数值为on
内容的提问来源于stack exchange,提问作者AAPJ

