AWS的RDS证书升级 & 应用通过SSL访问RDS该文档主要讲述了AWS的RDS证书升级的问题及解决方法。因证书超期导
问题&解法
早上起床,发现系统大量报错,故快速登录服务器查看,发现大量的数据库连接报错,如下所示。
可见是我们应用的IP由于大量的访问RDS报错,导致RDS将这台机器的IP blocked. 我的第一反应就是可能数据库证书出现了问题,因为之前在AWS的控制台浏览的时候看到了一个即将8月到期的证书提示,当时没有太过于关注。
我打开AWS的控制台查看,果然看到一条CA证书超期的提醒,如下图所示。
继续点击here的链接,如下图所示。发现rds-ca-2019的证书与2024.8.23号过期,也就是今天凌晨过期失效。这里要科普下AWS定期更新CA证书,以确保AWS RDS服务与当前的安全标准保持一致。rds-ca-2019
证书是 AWS 提供的过渡期证书,不支持自动服务器证书轮换,最初用于替代更早的 rds-ca-2015
证书。随着 rds-ca-2019
的到期,AWS 发布了新的证书(例如 rds-ca-rsa2048-g1
)来继续保障安全通信。此CA支持自动服务器证书轮换。所以有效期会长很多。
既然已经知道原因,则直接点击立即升级,将证书升级到rds-ca-rsa2048-g1
,这里提示证书更新无需重启DB,这句话误导我了,我以为只要升级证书完成之后就可以立即使用客户端访问DB了。
但随后我立即使用客户端访问DB,发现还是报如下错误:
Caused by: java.sql.SQLException: null, message from server: "Host '172.31.2.53' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'"
当时没有仔细想,以为还是由于证书问题导致访问不上,思路就迁移到如何让客户端使用证书访问数据库,后面折腾了一大堆,搞定了在客户端测使用证书访问DB,以及Spring应用通过证书访问DB。
后来回想下,其实不需要那么复杂,只需要做将RDS重启这步操作,擦除RDS对于服务器IP的block访问即可。
下面还是记录下如何让客户端使用证书访问RDS。
如何让客户端使用证书访问RDS
按照AWS的指南步骤,可以让应用使用SSL或者TLS加密和数据库间的连接。
首先我们可以在AWS控制台上查看,使用的CA类型即为rds-ca-rsa2048-g1,到期日为2061年
随后,我们就要下载使用SSL或者TLS连接到数据库时候的信任证书,选择所在地域的证书下载。
注意该下载的证书捆绑包中包含了多个证书:包括rds-ca-2019
,rds-ca-rsa2048-g1
, rds-ca-rsa4096-g1
, and rds-ca-ecc384-g1
可以通过如下命令,在本地查看下载的证书捆绑包中的内容
keytool -printcert -v -file eu-central-1-bundle.pem
返回结果如下:
Certificate[1]:
Owner: CN=Amazon RDS Root 2019 CA, OU=Amazon RDS, O="Amazon Web Services, Inc.", ST=Washington, L=Seattle, C=US
Issuer: CN=Amazon RDS Root 2019 CA, OU=Amazon RDS, O="Amazon Web Services, Inc.", ST=Washington, L=Seattle, C=US
Serial number: c73467369250ae75
Valid from: Fri Aug 23 01:08:50 CST 2019 until: Fri Aug 23 01:08:50 CST 2024
Certificate fingerprints:
SHA1: D4:0D:DB:29:E3:75:0D:FF:A6:71:C3:14:0B:BF:5F:47:8D:1C:80:96
SHA256: F2:54:C7:D5:E9:23:B5:B7:51:0C:D7:9E:F7:77:7C:1C:A7:E6:4A:3C:97:22:E4:0D:64:54:78:FC:70:AA:D0:08
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3
Extensions:
#1: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 73 5F 60 D8 BC CB 03 98 F4 2B 17 34 2E 36 5A A6 s_`......+.4.6Z.
0010: 60 FF BC 1F `...
]
]
#2: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
CA:true
PathLen: no limit
]
#3: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
Key_CertSign
Crl_Sign
]
#4: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 73 5F 60 D8 BC CB 03 98 F4 2B 17 34 2E 36 5A A6 s_`......+.4.6Z.
0010: 60 FF BC 1F `...
]
]
Certificate[2]:
Owner: CN=Amazon RDS eu-central-1 2019 CA, OU=Amazon RDS, O="Amazon Web Services, Inc.", L=Seattle, ST=Washington, C=US
Issuer: CN=Amazon RDS Root 2019 CA, OU=Amazon RDS, O="Amazon Web Services, Inc.", ST=Washington, L=Seattle, C=US
Serial number: 5766
Valid from: Thu Sep 12 03:36:20 CST 2019 until: Fri Aug 23 01:08:50 CST 2024
Certificate fingerprints:
SHA1: 53:46:18:4A:42:65:A2:8C:5F:5B:0A:AD:E2:2C:80:E5:E6:8A:6D:2F
SHA256: 0A:7D:2F:10:8E:F8:FA:AE:86:CF:9A:55:3D:B0:95:B6:52:35:B9:A3:94:D0:18:99:C1:A6:4F:85:8E:10:80:95
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3
Extensions:
#1: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 73 5F 60 D8 BC CB 03 98 F4 2B 17 34 2E 36 5A A6 s_`......+.4.6Z.
0010: 60 FF BC 1F `...
]
]
#2: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
CA:true
PathLen:0
]
#3: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
Key_CertSign
Crl_Sign
]
#4: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: E7 00 4E 80 1C EA C9 16 7D F2 5A 4E 7A DE 6A CC ..N.......ZNz.j.
0010: 00 7E B6 DC ....
]
]
Certificate[3]:
Owner: L=Seattle, CN=Amazon RDS eu-central-1 Root CA ECC384 G1, ST=WA, OU=Amazon RDS, O="Amazon Web Services, Inc.", C=US
Issuer: L=Seattle, CN=Amazon RDS eu-central-1 Root CA ECC384 G1, ST=WA, OU=Amazon RDS, O="Amazon Web Services, Inc.", C=US
Serial number: 7a741b70ffd96e3f49c6f67e8d76d19d
Valid from: Sat May 22 06:33:24 CST 2021 until: Thu May 22 07:33:24 CST 2121
Certificate fingerprints:
SHA1: D2:EB:0B:A8:7C:0B:45:9C:89:BA:A4:62:C1:5C:BF:58:E2:67:98:DC
SHA256: AE:69:7D:08:2E:E1:86:2F:71:1E:CA:E3:89:3C:3C:61:3B:73:15:D0:20:F7:46:74:05:15:34:A5:B1:66:D4:7B
Signature algorithm name: SHA384withECDSA
Subject Public Key Algorithm: 384-bit EC (secp384r1) key
Version: 3
Extensions:
#1: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
CA:true
PathLen: no limit
]
#2: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
DigitalSignature
Key_CertSign
Crl_Sign
]
#3: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 34 FF 4E 18 D0 66 5E 36 36 FF F8 67 FE C9 61 A3 4.N..f^66..g..a.
0010: CD 32 5C B6 .2\.
]
]
Certificate[4]:
Owner: L=Seattle, CN=Amazon RDS eu-central-1 Root CA RSA2048 G1, ST=WA, OU=Amazon RDS, O="Amazon Web Services, Inc.", C=US
Issuer: L=Seattle, CN=Amazon RDS eu-central-1 Root CA RSA2048 G1, ST=WA, OU=Amazon RDS, O="Amazon Web Services, Inc.", C=US
Serial number: ef1b7a437bad445eb8d3c6f294932ad1
Valid from: Sat May 22 06:23:47 CST 2021 until: Sun May 22 07:23:47 CST 2061
Certificate fingerprints:
SHA1: 94:E6:F1:A2:7C:F2:30:F8:69:EC:32:B4:61:1C:A1:0A:82:80:AD:05
SHA256: 3D:8B:08:A7:39:0C:9B:10:D1:90:A6:B3:49:D7:03:AE:00:BA:E4:65:83:64:33:19:C7:FA:CC:F3:E5:DC:4A:8B
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3
Extensions:
#1: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
CA:true
PathLen: no limit
]
#2: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
DigitalSignature
Key_CertSign
Crl_Sign
]
#3: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 10 C0 88 9E CF CB DF C0 F5 EB 4D 6B F7 9B 3A 7C ..........Mk..:.
0010: 79 97 93 06 y...
]
]
Certificate[5]:
Owner: L=Seattle, CN=Amazon RDS eu-central-1 Root CA RSA4096 G1, ST=WA, OU=Amazon RDS, O="Amazon Web Services, Inc.", C=US
Issuer: L=Seattle, CN=Amazon RDS eu-central-1 Root CA RSA4096 G1, ST=WA, OU=Amazon RDS, O="Amazon Web Services, Inc.", C=US
Serial number: 3380bc83988546e71259d0bc11da8778
Valid from: Sat May 22 06:28:26 CST 2021 until: Thu May 22 07:28:26 CST 2121
Certificate fingerprints:
SHA1: D6:87:8C:CE:33:C9:63:C3:D2:5B:FD:75:BE:DE:E0:46:15:87:A8:DF
SHA256: 31:11:F3:22:E4:48:C2:6E:A2:72:2C:02:E2:97:14:DA:CE:16:D5:C3:93:36:CD:F6:DF:BF:FB:C0:36:8D:53:32
Signature algorithm name: SHA384withRSA
Subject Public Key Algorithm: 4096-bit RSA key
Version: 3
Extensions:
#1: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
CA:true
PathLen: no limit
]
#2: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
DigitalSignature
Key_CertSign
Crl_Sign
]
#3: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 8A 80 F1 09 0E B3 67 12 8A B3 A9 0A E2 AE 3A 1F ......g.......:.
0010: 55 0D F2 5F U.._
]
]
可以看到里面总共5个证书,第一个为Amazon RDS Root 2019 CA根证书,第二个为Amazon RDS eu-central-1 2019 CA中间证书(欧洲区域),第三个为Amazon RDS eu-central-1 Root CA ECC384 G1根证书,第四个为Amazon RDS eu-central-1 Root CA RSA2048 G1根证书(就是我们这次需要的证书),第五个为Amazon RDS eu-central-1 Root CA RSA4096 G1。
所以可以看到这个证书捆绑包中的第四个证书才是我们需要的证书。
这里就需要有个证书剪裁的过程,暂且不表。
这样我们的证书捆绑包就拿到了,即为eu-central-1-bundle.pem
客户端通过SSL访问RDS
我使用的客户端为MySQL Workbench,切换到SSL的tab,如下图所示配置:
Use SSL选项选择:Require and Verify CA 用于访问需要验证CA
SSL CA File只需要将刚刚下载到本地的eu-central-1-bundle.pem证书上传
然后点击「Test Connection」测试连接连通性,可以看到连接数据库已经使用SSL的方式
这样就完成了客户端通过SSL连接RDS的设置
应用通过SSL访问RDS
由于我们的应用是Springboot + Docker,那么就需要在application.properties
或application.yml
中配置SSL参数。
1、将PEM证书转化为JKS格式
由于MySQL驱动程序没法识别PEM的证书文件格式,期望是一个Java KeyStore(JKS)格式的文件。
当然在将eu-central-1-bundle.pem证书转化为JKS文件之前,需要先把其中rds-ca-rsa2048-g1
截取出来,即里面的第四个证书。
在终端中运行如下命令,提取文件中的第四个证书,并将其保存到cert4.pem文件中
awk 'BEGIN {c=0; in_cert=0;}
/BEGIN CERTIFICATE/ {c++; in_cert=(c==4);}
in_cert {print > "cert4.pem"}
/END CERTIFICATE/ {if (in_cert) exit;}' eu-central-1-bundle.pem
生成好文件后,再打印输出确认下:
keytool -printcert -v -file cert4.pem
如上图确认无误后,既可以将该PEM文件格式转成JKS格式的文件。
如下命令:
keytool -import -file cert4.pem -alias rds-root -keystore truststore.jks -storepass changeit
这将创建一个名为truststore.jks
的文件,并将PEM证书导入其中。changeit
是JKS文件的密码,你可以根据需要更改它
2、将JKS文件放置在Spring Boot项目中
将生成的truststore.jks
文件放置在src/main/resources
目录下,例如src/main/resources/aws/prod/rds/truststore.jks
3、配置Spring Boot应用程序
在application.properties
或application.yml
文件中配置数据库连接信息,并指定JKS文件路径。由于我将证书文件放置在src/main/resources
目录下,那么在运行时这些资源会被打包到JAR文件中。你需要使用classpath
前缀来引用这些资源。
application.properties 示例
spring.datasource.url=jdbc:mysql://your-rds-endpoint:3306/your-database-name?useSSL=true&requireSSL=true&verifyServerCertificate=true&trustCertificateKeyStoreUrl=classpath:aws/prod/rds/truststore.jks&trustCertificateKeyStorePassword=changeit
spring.datasource.username=your-username
spring.datasource.password=your-password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
这样就完成了应用通过SSL访问RDS的配置设置
转载自:https://juejin.cn/post/7406148257787478027