Azure Database for PostgreSQL 灵活服务器使用传输层安全性(TLS)强制将客户端应用程序连接到 Azure Database for PostgreSQL 灵活服务器。 TLS 是一种行业标准协议,可确保数据库服务器和客户端应用程序之间的加密网络连接。 TLS 是安全套接字层 (SSL) 的更新协议。 SSL 和 TLS 术语仍可互换使用。
证书链
证书链是包含 TLS/SSL 证书和 CA 证书的证书的有序列表。 它们使接收方能够验证发送方和所有 CA 是否可信。 链或路径以 TLS/SSL 证书开头。 链中的每个证书都由链中下一个证书标识的实体签名。
链以 根 CA 证书终止。 此证书始终由 CA 本身签名。 链中所有证书的签名必须验证到根 CA 证书。
位于 TLS/SSL 证书与链中根 CA 证书之间的任何证书称为中间证书。
TLS 版本
全球多个政府实体维护有关网络安全的 TLS 准则。 TLS 提供的安全级别受 TLS 协议版本和支持的密码套件影响最大。
密码套件是一组算法,其中包括密码、密钥交换算法和哈希算法。 它们一起使用来建立安全的 TLS 连接。 大多数 TLS 客户端和服务器都支持多种替代方法。 他们必须协商建立安全连接以选择通用 TLS 版本和密码套件。
Azure Database for PostgreSQL 支持 TLS 版本 1.2 及更高版本。 在 RFC 8996 中,Internet 工程工作队(IETF)明确指出不得使用 TLS 1.0 和 TLS 1.1。 这两种协议在 2019 年底被弃用。
默认情况下,使用早期版本的 TLS 协议(如 TLS 1.0 和 TLS 1.1)的所有传入连接均被拒绝。
IETF 于 2018 年 8 月在 RFC 8446 中发布了 TLS 1.3 规范,TLS 1.3 现在是最常用的推荐 TLS 版本。 TLS 1.3 比 TLS 1.2 更快、更安全。
注释
SSL 和 TLS 证书验证连接是否使用最先进的加密协议进行保护。 通过在网络上加密连接,可以阻止在传输过程中未经授权访问数据。 强烈建议使用最新版本的 TLS 来加密与 Azure Database for PostgreSQL 灵活服务器的连接。
尽管我们不建议使用,但如果需要,可以禁用 TLS\SSL 以连接到 Azure Database for PostgreSQL 灵活服务器。 可以将服务器参数更新 require_secure_transport
为 OFF
. 还可以通过设置和ssl_min_protocol_version
服务器参数来设置 ssl_max_protocol_version
TLS 版本。
证书身份验证 是使用 SSL 客户端证书进行身份验证执行的。 在此方案中,PostgreSQL 服务器将客户端证书的公用名 (CN) 属性与请求的数据库用户进行比较。
目前,Azure Database for PostgreSQL 灵活服务器不支持:
- 基于 SSL 证书的身份验证。
- 自定义 SSL\TLS 证书。
注释
Microsoft对各种 Azure 服务(包括 Azure Database for PostgreSQL 灵活服务器)进行了根 CA 更改。 有关详细信息,请参阅 Azure TLS 证书更改 和客户端 上的“配置 SSL”部分。
若要确定当前的 TLS\SSL 连接状态,可以加载 sslinfo 扩展 ,然后调用 ssl_is_used()
该函数来确定是否正在使用 SSL。 如果连接使用 SSL,该函数将 t
返回。 否则,它将返回 f
。 还可以使用以下查询收集有关 Azure Database for PostgreSQL 灵活服务器的 SSL 使用情况的所有信息:进程、客户端和应用程序:
SELECT datname as "Database name", usename as "User name", ssl, client_addr, application_name, backend_type
FROM pg_stat_ssl
JOIN pg_stat_activity
ON pg_stat_ssl.pid = pg_stat_activity.pid
ORDER BY ssl;
若要进行测试,还可以直接使用 openssl
以下命令:
openssl s_client -starttls postgres -showcerts -connect <your-postgresql-server-name>:5432
此命令输出低级别协议信息,例如 TLS 版本和密码。 必须使用此选项 -starttls postgres
。 否则,此命令将报告未使用 SSL。 使用此命令至少需要 OpenSSL 1.1.1。
若要强制实施最新的、最安全的 TLS 版本,以便从客户端到 Azure Database for PostgreSQL 灵活服务器的连接保护,请设置为 ssl_min_protocol_version
1.3
。 此设置 要求 连接到 Azure Database for PostgreSQL 灵活服务器的客户端 才能使用此版本的协议 来安全通信。 旧客户端可能无法与服务器通信,因为它们不支持此版本。
在客户端上配置 SSL
默认情况下,PostgreSQL 不会对服务器证书执行任何验证。 因此,可以欺骗服务器标识(例如,修改 DNS 记录或接管服务器 IP 地址),而无需客户端知道。 所有 SSL 选项都以加密和密钥交换的形式传输开销,因此在性能和安全性之间进行权衡。
若要防止欺骗,必须使用客户端上的 SSL 证书验证。
有许多连接参数可用于配置用于 SSL 的客户端。 一些重要事项包括:
ssl
:使用 SSL 进行连接。 此属性不需要与之关联的值。 它仅存在指定 SSL 连接。 为了与将来的版本兼容,首选值true
。 在此模式下,建立 SSL 连接时,客户端驱动程序会验证服务器的标识,以防止中间人攻击。 它会检查服务器证书是否由受信任的颁发机构签名,并且要连接到的主机是否与证书中的主机名相同。sslmode
:如果需要加密,并且希望连接在无法加密的情况下失败,请设置sslmode=require
。 此设置可确保服务器配置为接受此主机/IP 地址的 SSL 连接,并且服务器能够识别客户端证书。 如果服务器不接受 SSL 连接或无法识别客户端证书,则连接将失败。 下表列出了此设置的值:SSL 模式 Explanation disable
不使用加密。 allow
如果服务器设置需要或强制执行加密,则使用加密。 prefer
如果服务器设置允许加密,则使用加密。 require
使用加密。 它确保服务器配置为接受此主机 IP 地址的 SSL 连接,并且服务器能够识别客户端证书。 verify-ca
使用加密。 根据客户端上存储的证书验证服务器证书签名。 verify-full
使用加密。 根据客户端上存储的证书验证服务器证书签名和主机名。
使用的默认 sslmode
模式在基于 libpq 的客户端(如 psql)和 JDBC 之间有所不同。 基于 libpq 的客户端默认为 prefer
。 JDBC 客户端默认为 verify-full
.
-
sslcert
、sslkey
和sslrootcert
:这些参数可以替代客户端证书的默认位置、PKCS-8 客户端密钥和根证书。 它们默认为/defaultdir/postgresql.crt
nix/defaultdir/postgresql.pk8
/defaultdir/root.crt
系统和 Windows 上的位置,以及defaultdir
分别位于何处${user.home}/.postgresql/
%appdata%/postgresql/
。
CA 是负责颁发证书的机构。 受信任的证书颁发机构是有权验证某人是谁的实体。 要使此模型正常工作,所有参与者都必须就一组受信任的 CA 达成一致。 所有作系统和大多数 Web 浏览器都附带了一组受信任的 CA。
使用 verify-ca
和 verify-full
sslmode
配置设置也称为 证书固定。 在这种情况下,PostgreSQL 服务器上的根 CA 证书必须匹配证书签名,甚至与客户端上的证书匹配主机名。
在 PostgreSQL 服务器证书上更改或过期时,可能需要定期更新客户端存储的证书。 若要确定是否固定 CA,请参阅 证书固定和 Azure 服务。
有关客户端上的 SSL\TLS 配置的详细信息,请参阅 PostgreSQL 文档。
对于使用 verify-ca
和 verify-full
sslmode
配置设置(即证书固定)的客户端,必须将 三个 根 CA 证书部署到客户端证书存储:
- DigiCert 全局根 G2 和 Microsoft RSA 根 CA 2017 根 CA 证书,因为服务正在从 Digicert 迁移到 Microsoft CA。
- Digicert 全局根 CA,用于旧版兼容性。
在证书固定方案中下载根 CA 证书并更新应用程序客户端
若要在证书固定方案中更新客户端应用程序,可以下载证书:
若要将证书导入客户端证书存储,可能需要在从上述 URI 下载证书文件后将证书 .crt 文件转换为 .pem 格式。 可以使用 OpenSSL 实用工具执行以下文件转换:
openssl x509 -inform DER -in certificate.crt -out certificate.pem -outform PEM
有关使用新的根 CA 证书更新客户端应用程序证书存储的信息记录在 应用程序客户端的更新客户端 TLS 证书中。
重要
某些 Postgres 客户端库在使用 sslmode=verify-full
此设置时,可能会遇到与中间证书交叉签名的根 CA 证书的连接失败。 结果是备用信任路径。 在这种情况下,我们建议显式指定 sslrootcert
参数。 或者,将 PGSSLROOTCERT
环境变量设置为本地路径,其中将Microsoft RSA 根 CA 2017 根 CA 证书放置在默认值中 %APPDATA%\postgresql\root.crt
。
具有证书固定方案的只读副本
将根 CA 迁移到 Microsoft RSA 根 CA 2017 后,新创建的副本在较新的根 CA 证书上比之前创建的主服务器可行。 对于使用 verify-ca
和 verify-full
sslmode
配置设置(即证书固定)的客户端,必须中断连接才能接受三个根 CA 证书:
目前,Azure Database for PostgreSQL 灵活服务器不支持 基于证书的身份验证。
在证书固定方案中通过 psql 连接来测试客户端证书
可以在证书固定方案中使用 psql
客户端中的命令行测试与服务器的连接:
$ psql "host=hostname.postgres.database.chinacloudapi.cn port=5432 user=myuser dbname=mydatabase sslmode=verify-full sslcert=client.crt sslkey=client.key sslrootcert=ca.crt"
有关 SSL 和证书参数的详细信息,请参阅 psql 文档。
测试 TLS/SSL 连接
在尝试从客户端应用程序访问已启用 SSL 的服务器之前,请确保可以通过 psql 访问它。 如果建立了 SSL 连接,应会看到类似于以下示例的输出:
psql (14.5)SSL 连接(协议:TLSv1.2,密码:ECDHE-RSA-AES256-GCM-SHA384,位:256,压缩:关闭)键入“help”以获取帮助。
还可以加载 sslinfo 扩展 ,然后调用 ssl_is_used()
该函数来确定是否正在使用 SSL。 如果连接使用 SSL,该函数将 t
返回。 否则,它将返回 f
。
密码套件
密码套件是一组加密算法。 TLS/SSL 协议使用密码套件中的算法来创建密钥和加密信息。
密码套件显示为看似随机信息的长字符串,但该字符串的每个段都包含重要信息。 通常,此数据字符串包括几个关键组件:
- 协议(即 TLS 1.2 或 TLS 1.3)
- 密钥交换或协议算法
- 数字签名(身份验证)算法
- 批量加密算法
- 消息身份验证代码算法 (MAC)
TLS/SSL 的不同版本支持不同的密码套件。 TLS 1.2 密码套件无法与 TLS 1.3 连接协商,反之亦然。
目前,Azure Database for PostgreSQL 灵活服务器支持许多密码套件,其中包含属于 HIGH:!aNULL 类别的 TLS 1.2 协议版本。
排查 TLS/SSL 连接错误
- 排查 TLS/SSL 协议版本兼容性问题的第一步是确定在尝试从客户端进行 TLS 加密的情况下访问 Azure Database for PostgreSQL 灵活服务器时看到的错误消息。 根据应用程序和平台的不同,错误消息可能有所不同。 在许多情况下,它们指向根本问题。
- 若要确定 TLS/SSL 协议版本兼容性,请检查数据库服务器和应用程序客户端的 TLS/SSL 配置,确保它们支持兼容的版本和密码套件。
- 分析数据库服务器与客户端 TLS/SSL 版本与密码套件之间的任何差异或差距。 尝试通过启用或禁用某些选项、升级或降级软件或更改证书或密钥来解决它们。 例如,可能需要根据安全性和兼容性要求在服务器或客户端上启用或禁用特定的 TLS/SSL 版本。 例如,可能需要禁用 TLS 1.0 和 TLS 1.1,这些 TLS 被视为不安全和已弃用,并启用 TLS 1.2 和 TLS 1.3(更安全且更新式)。
- Microsoft RSA 根 CA 2017 颁发的最新证书在由 Digicert Global Root G2 CA 交叉签名的链中具有中间。 某些 Postgres 客户端库在使用
sslmode=verify-full
或sslmode=verify-ca
设置时,可能会遇到与中间证书交叉签名的根 CA 证书的连接失败。 结果是备用信任路径。
若要解决这些问题,请将所有三个必需的证书添加到客户端证书存储或显式指定 sslrootcert
参数。 或者,将 PGSSLROOTCERT
环境变量设置为本地路径,其中将Microsoft RSA 根 CA 2017 根 CA 证书放置在默认值中 %APPDATA%\postgresql\root.crt
。