

# 更新应用程序以使用新的 SSL/TLS 证书连接到 PostgreSQL 数据库实例
<a name="ssl-certificate-rotation-postgresql"></a>

用于安全套接字层或传输层安全 (SSL/TLS) 的证书通常具有设定的生命周期。服务提供商更新其证书颁发机构 (CA) 证书时，客户端必须更新其应用程序才能使用新证书。在下文中，您可以了解有关如何确定客户端应用程序是否使用 SSL/TLS 连接到 Amazon RDS for PostgreSQL 数据库实例的信息。您还可以找到有关如何检查这些应用程序在连接时是否验证服务器证书的信息。

**注意**  
配置为在 SSL/TLS 连接之前验证服务器证书的客户端应用程序必须在客户端的信任存储中具有有效的 CA 证书。必要时更新客户端信任存储以获取新证书。

更新客户端应用程序信任存储中的 CA 证书后，可以在数据库实例上轮换这些证书。强烈建议在生产环境中实现这些过程之前，先在非生产环境中测试它们。

有关证书轮换的更多信息，请参阅[轮换 SSL/TLS 证书](UsingWithRDS.SSL-certificate-rotation.md)。有关下载证书的更多信息，请参阅[使用 SSL/TLS 加密与数据库实例或集群的连接](UsingWithRDS.SSL.md)。有关对 PostgreSQL 数据库实例使用 SSL/TLS 的信息，请参阅[将 SSL 与 PostgreSQL 数据库实例结合使用](PostgreSQL.Concepts.General.SSL.md)。

**Topics**
+ [确定是否有应用程序使用 SSL 连接到 PostgreSQL 数据库实例](#ssl-certificate-rotation-postgresql.determining-server)
+ [确定客户端是否需要证书验证才能连接](#ssl-certificate-rotation-postgresql.determining-client)
+ [更新应用程序信任存储](#ssl-certificate-rotation-postgresql.updating-trust-store)
+ [对不同类型的应用程序使用 SSL/TLS 连接](#ssl-certificate-rotation-postgresql.applications)

## 确定是否有应用程序使用 SSL 连接到 PostgreSQL 数据库实例
<a name="ssl-certificate-rotation-postgresql.determining-server"></a>

检查数据库实例配置中 `rds.force_ssl` 参数的值。默认情况下，对于使用 PostgreSQL 版本 15 之前版本的数据库实例，`rds.force_ssl` 参数设置为 `0`（关闭）。默认情况下，对于使用 PostgreSQL 版本 15 及更高主要版本的数据库实例，`rds.force_ssl` 设置为 `1`（打开）。如果 `rds.force_ssl` 参数设置为 `1`（开），则客户端需要使用 SSL/TLS 进行连接。有关参数组的更多信息，请参阅 [Amazon RDS 的参数组](USER_WorkingWithParamGroups.md)。

如果您使用的是 RDS PostgreSQL 版本 9.5 或更高的主要版本，并且 `rds.force_ssl` 未设置为 `1`（开），请查询 `pg_stat_ssl` 视图来检查使用 SSL 的连接。例如，以下查询仅返回 SSL 连接和有关使用 SSL 的客户端的信息。

```
SELECT datname, usename, ssl, client_addr 
  FROM pg_stat_ssl INNER JOIN pg_stat_activity ON pg_stat_ssl.pid = pg_stat_activity.pid
  WHERE ssl is true and usename<>'rdsadmin';
```

只有使用 SSL/TLS 连接的行才显示有关连接的信息。下面是示例输出。

```
 datname  | usename | ssl | client_addr 
----------+---------+-----+-------------
 benchdb  | pgadmin | t   | 53.95.6.13
 postgres | pgadmin | t   | 53.95.6.13
(2 rows)
```

此查询仅显示进行查询时有效的连接。没有结果并不表示没有应用程序在使用 SSL 连接。其他 SSL 连接可能在不同的时间建立。

## 确定客户端是否需要证书验证才能连接
<a name="ssl-certificate-rotation-postgresql.determining-client"></a>

当客户端（如 psql 或 JDBC）配置有 SSL 支持时，默认情况下，该客户端会首先尝试使用 SSL 连接到数据库。如果该客户端无法使用 SSL 进行连接，它将恢复为不使用 SSL 进行连接。用于基于 libpq 的客户端（例如 psql）和 JDBC 的默认 `sslmode` 模式设置为 `prefer`。仅当提供 `sslrootcert` 且 `sslmode` 设置为 `verify-ca` 或 `verify-full` 时，才会验证服务器上的证书。如果证书无效，则会引发错误。

使用 `PGSSLROOTCERT` 验证具有 `PGSSLMODE` 环境变量的证书，且 `PGSSLMODE` 设置为 `verify-ca` 或 `verify-full`。

```
PGSSLMODE=verify-full PGSSLROOTCERT=/fullpath/ssl-cert.pem psql -h pgdbidentifier.cxxxxxxxx.us-east-2.rds.amazonaws.com -U masteruser -d postgres
```

使用 `sslrootcert` 参数验证 `sslmode` 为连接字符串格式的证书，将 `sslmode` 设置为 `verify-ca` 或 `verify-full` 来验证证书。

```
psql "host=pgdbidentifier.cxxxxxxxx.us-east-2.rds.amazonaws.com sslmode=verify-full sslrootcert=/full/path/ssl-cert.pem user=masteruser dbname=postgres"
```

例如，在上述情况下，如果您使用无效的根证书，则会在客户端上看到类似于以下内容的错误。

```
psql: SSL error: certificate verify failed
```

## 更新应用程序信任存储
<a name="ssl-certificate-rotation-postgresql.updating-trust-store"></a>

有关更新 PostgreSQL 应用程序的信任存储的信息，请参阅 PostgreSQL 文档中的[使用 SSL 保护 TCP/IP 连接](https://www.postgresql.org/docs/current/ssl-tcp.html)。

有关下载根证书的信息，请参阅 [使用 SSL/TLS 加密与数据库实例或集群的连接](UsingWithRDS.SSL.md)。

有关导入证书的示例脚本，请参阅 [将证书导入信任存储的示例脚本](UsingWithRDS.SSL-certificate-rotation.md#UsingWithRDS.SSL-certificate-rotation-sample-script)。

**注意**  
更新信任存储时，除了添加新证书外，还可以保留较旧证书。

## 对不同类型的应用程序使用 SSL/TLS 连接
<a name="ssl-certificate-rotation-postgresql.applications"></a>

下面提供了有关对不同类型应用程序使用 SSL/TLS 连接的信息：
+ **psql**

  通过将选项指定为连接字符串或环境变量，可以从命令行调用客户端。对于 SSL/TLS 连接，相关选项为 `sslmode`（环境变量 `PGSSLMODE`）和 `sslrootcert`（环境变量 `PGSSLROOTCERT`）。

  有关完整的选项列表，请参阅 PostgreSQL 文档中的[参数关键字](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-PARAMKEYWORDS)。有关完整的环境变量列表，请参阅 PostgreSQL 文档中的[环境变量](https://www.postgresql.org/docs/current/libpq-envars.html)。
+ **pgAdmin**

  这个基于浏览器的客户端是一个更加用户友好的界面，用于连接到 PostgreSQL 数据库。

  有关配置连接的信息，请参阅 [pgAdmin 文档](https://www.pgadmin.org/docs/pgadmin4/latest/server_dialog.html)。
+ **JDBC**

  JDBC 支持与 Java 应用程序的数据库连接。

  有关使用 JDBC 连接到 PostgreSQL 数据库的一般信息，请参阅 PostgreSQL JDBC 驱动程序文档中的[连接到数据库](https://jdbc.postgresql.org/documentation/use/#connecting-to-the-database)。有关使用 SSL/TLS 进行连接的信息，请参阅 PostgreSQL JDBC 驱动程序文档中的[配置客户端](https://jdbc.postgresql.org/documentation/ssl/#configuring-the-client)。
+ **Python**

  一个常用的连接到 PostgreSQL 数据库的 Python 库是 `psycopg2`。

  有关如何使用 `psycopg2` 的信息，请参阅 [psycopg2 文档](https://pypi.org/project/psycopg2/)。有关如何连接到 PostgreSQL 数据库的简短教程，请参阅 [Psycopg2 教程](https://wiki.postgresql.org/wiki/Psycopg2_Tutorial)。您可以在 [psycopg2 模块内容](http://initd.org/psycopg/docs/module.html#module-psycopg2)中找到有关连接命令接受的选项的信息。

**重要**  
在确定了数据库连接使用 SSL/TLS 并更新了应用程序信任存储之后，可以更新数据库以使用 rds-ca-rsa2048-g1 证书。有关说明，请参阅[通过修改数据库实例或集群来更新 CA 证书](UsingWithRDS.SSL-certificate-rotation.md#UsingWithRDS.SSL-certificate-rotation-updating)中的步骤 3。