我有一个全新的 Postgres 11 RDS 实例,无论是否使用 SSL 证书都可以连接到它。但是,我想确保我们永远不会在没有 SSL 的情况下连接到此数据库。因此,我已采取以下步骤来尝试执行此操作:
- 创建一个新的参数组,因为默认参数组不可编辑。
rds.force_ssl
将的值更改为1
。- 将我的数据库参数组更改为新的参数组,并选择“立即应用”
- 等待参数组应用,一旦状态从“(应用)”变为“(待重启)”
- 一旦应用了该组,我就会重新启动该实例。
- 然后,当我使用 cli 连接时:
psql -h aws_hostname -p 5432 "dbname=mydbname user=dbuser"
我预计连接会失败,因为我没有指定 SSL 证书。
输出为:
Password for user postgres:
psql (11.5)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.
mydbname=>
所以我可以看到连接是通过 TLSv1.2 进行的。但是,我不明白为什么 AWS 似乎允许您强制执行 SSL,并提供了一种下载证书来执行此操作的方法,但却不使用它。我原本以为在像这样连接时会强制提供证书:
psql -h aws_hostname -p 5432 "dbname=mydbname user=dbuser sslrootcert=rds-combined-ca-bundle.pem sslmode=verify-full"
答案1
但是,我不明白为什么 AWS 似乎允许您强制使用 SSL,并提供了一种下载证书的方法,但却没有使用它。我原本以为在像这样连接时会强制提供证书
服务器可以强制客户端使用ssl建立连接,但不能强制客户端验证服务器的证书。
如果您的客户端基于 libpq,那么当且仅当它能够找到根证书文件(通常位于 ~/.postgresql/root.crt,如果没有指定其他内容)时,它才会验证证书。如果您在客户端上指定 PGSSLMODE=verify-ca 或更高版本,那么如果找不到根证书文件,客户端将抛出错误。如果 sslmode 低于该级别并且客户端找不到根证书文件,那么它将使用服务器的证书来协商加密,但不会使用它来验证服务器的身份。因此,您可以获得针对被动窃听的保护,但无法获得针对主动 MITM 攻击的保护。
答案2
Postgres 将尝试自动使用 TLS 进行连接。我原以为情况并非如此。如果我包含环境变量,PGSSLMODE=disable
那么可以在不使用该rds.force_ssl
选项时测试 SSL 连接失败。