在 Azure Database for PostgreSQL 灵活服务器中使用 TLS 和 SSL 的安全连接

适用于:Azure Database for PostgreSQL 灵活服务器

Azure Database for PostgreSQL 灵活服务器使用传输层安全性 (TLS) 强制将客户端应用程序连接到 Azure Database for PostgreSQL 灵活服务器。 TLS 是一种行业标准协议,可确保在数据库服务器与客户端应用程序之间实现加密网络连接。 TLS 是安全套接字层 (SSL) 的更新协议。

什么是 TLS?

TLS 基于网景通讯公司。 安全套接字层 (SSL) 协议已经被 TLS 取代,但术语 SSL 或 SSL/TLS 有时仍可互换使用。TLS 由两个层组成:TLS 记录协议和 TLS 握手协议。 记录协议提供关联安全性,而握手协议使服务器和客户能够相互确认,并在交换任何信息之前协调加密评估和加密密钥。

显示典型 TLS 1.2 握手序列的示意图。

上图展示了典型的 TLS 1.2 握手序列,其中包括:

  1. 客户端首先发送一个名为 ClientHello 的消息,该消息实质上表示愿意通过 TLS 1.2 使用一组客户端支持的密码套件进行通信
  2. 服务器收到该消息,并回复一个 ServerHello 消息,表示同意通过 TLS 1.2 使用特定的密码套件与客户端进行通信
  3. 此外,服务器还发送了其密钥共享部分。 此密钥共享部分的具体信息会根据所选的密码套件而更改。 需要注意的重要细节是,要使客户端和服务器就加密密钥达成一致,他们需要接收彼此的部分(也称为共享部分)。
  4. 服务器发送证书(由 CA 签名)以及对 ClientHello 和 ServerHello 的部分的签名,包括密钥共享部分,这样客户端就知道它们是真实的。
  5. 客户端成功接收上述数据后,会生成自己的密钥共享部分,将其与服务器密钥共享部分混合,从而生成会话的加密密钥。
  6. 最后的步骤是,客户端向服务器发送其密钥共享部分,实现加密并发送 Finished 消息(这是到目前为止所发生事件的脚本的哈希)。 服务器会执行相同的操作:混合密钥共享部分以获取密钥并发送自己的 Finished 消息。
  7. 此时,可以在连接上加密发送应用程序数据。

证书链

证书链是一个有序的证书列表,包含 SSL/TLS 证书和证书颁发机构 (CA) 证书,使接收方能够验证发送方和所有 CA 是否可信。 链或路径以 SSL/TLS 证书开头,链中的每个证书都由链中下一个证书所标识的实体签名。 链以根 CA 证书结束。 根 CA 证书总是由证书颁发机构 (CA) 自己签名。 必须验证链中所有证书的签名,直至根 CA 证书。 链中位于 SSL/TLS 证书和根 CA 证书之间的任何证书都称为中间证书。

TLS 版本

全球有几个政府实体维护有关网络安全的 TLS 准则,包括卫生与公众服务部 (HHS) 和美国国家标准与技术研究院 (NIST)。 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)的传入连接会被默认拒绝。

注意

SSL 和 TLS 证书证明连接受到最先进加密协议的保护。 在线加密连接可以防止对传输中的数据进行未经授权的访问。 正因如此,我们强烈建议使用最新版本的 TLS 来加密与 Azure Database for PostgreSQL 灵活服务器的连接。
如果需要,可以选择通过将 require_secure_transport 服务器参数更新为 OFF,来对 Azure Database for PostgreSQL 灵活服务器连接禁用 TLS\SSL,不过我们不建议这样做。 还可以通过设置 ssl_min_protocol_version 和 ssl_max_protocol_version 服务器参数来设置 TLS 版本 。

证书身份验证 使用 SSL 客户端证书 执行身份验证。 在此方案中,PostgreSQL 服务器会将提供的客户端证书的 CN (公用名)属性与请求的数据库用户进行比较。 Azure Database for PostgreSQL 灵活服务器目前不支持基于 SSL 证书的身份验证。

注意

Azure Database for PostgreSQL 灵活服务器目前不支持自定义 SSL\TLS 证书

若要确定当前的 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 -connect localhost:5432 -starttls postgres

此命令会打印出大量低级别协议信息(包括 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 的客户端。 一些重要事项是:

  1. ssl。 使用 SSL 进行连接。 此属性不需要与之关联的值。 它的存在就意味着 SSL 连接。 但是,为了与将来的版本兼容,首选值为“true”。 在此模式下,建立 SSL 连接时,客户端驱动程序会验证服务器的标识,防止“中间人”攻击。 为此,它会检查服务器证书是否由受信任的颁发机构签名,并且你正在连接到的主机是否与证书中的主机名相同。
  2. sslmode。 如果需要加密,并且希望连接在无法加密的情况下失败,请设置 sslmode=require。 这可确保服务器配置为接受此主机/IP 地址的 SSL 连接,并且服务器能够识别客户端证书。 换句话说,如果服务器不接受 SSL 连接,或者无法识别客户端证书,连接将失败。 下表列出了此设置的值:
SSL 模式 说明
disable 没有使用加密
allow 如果 f 服务器设置需要强制加密,则使用加密
prefer 如果 f 服务器设置允许加密,则使用加密
require 使用了加密。 这可确保服务器配置为接受此主机 IP 地址的 SSL 连接,并且服务器能够识别客户端证书。
verify-ca 使用了加密。 此外,根据客户端上存储的证书验证服务器证书签名
verify-full 使用了加密。 此外,根据客户端上存储的证书验证服务器证书签名和主机名
  1. sslcert、**sslkey、sslrootcert. 这些参数可以替代客户端证书、PKCS-8 客户端密钥和根证书的默认位置。 这些默认值分别为 /defaultdir/postgresql.crt、/defaultdir/postgresql.pk8 和 /defaultdir/root.crt,其中 defaultdir 在 *nix 系统中是 ${user.home}/.postgresql/,在 windows 上是 %appdata%/postgresql/。

证书颁发机构 (CA) 是负责颁发证书的机构。 受信任的证书颁发机构是有权验证某人是谁的实体。 为了使此模型正常工作,所有参与者都必须就一组受信任的 CA 达成一致。 所有操作系统和大多数 Web 浏览器都附带了一组受信任的 CA。

注意

使用 verify-ca 和 verify-full sslmode 配置设置也可以称为证书固定 在这种情况下,PostgreSQL 服务器上的根 CA 证书必须与客户端上的证书的证书签名、甚至主机名匹配。 请务必记住,当证书颁发机构在 PostgreSQL 服务器证书上更改或过期时,可能需要定期更新客户端存储的证书。 若要确定你是否正在固定 CA,请参阅证书固定和 Azure 服务

若要详细了解客户端上的 SSL\TLS 配置,请参阅 PostgreSQL 文档

注意

对于使用 verify-caverify-full sslmode 配置设置(即证书固定)的客户端,它们必须接受两个根 CA 证书:

在证书固定方案中下载根 CA 证书和更新应用程序客户端

若要在证书固定场景中更新客户端应用程序,可从以下 URI 下载证书:Microsoft RSA 根证书颁发机构 2017 https://www.microsoft.com/pkiops/certs/Microsoft%20RSA%20Root%20Certificate%20Authority%202017.crt、Digicert 全局根 CA https://cacerts.digicert.com/DigiCertGlobalRootCA.crt

若要将证书导入客户端证书存储,你可能需要在从上述 URI 下载证书文件之后,将证书 .crt 文件转换为 .pem 格式。 可使用 OpenSSL 实用工具执行这些文件转换,如下例所示:

openssl x509 -in certificate.crt -out certificate.pem -outform PEM

操作方法文档介绍了使用新的根 CA 证书更新客户端应用程序证书存储的详细信息

具有证书固定方案的只读副本

将根 CA 迁移到 Microsoft RSA 根证书颁发机构 2017 时,新创建的副本在较新的根 CA 证书上比之前创建的主服务器可行。 因此,对于使用 verify-ca 和 verify-full sslmode 配置设置(即证书固定)的客户端,中断连接必须接受这两个根 CA 证书:Digicert 全局根 CAMicrosoft RSA 根证书颁发机构 2017,因为服务正从 Digicert 迁移到 Microsoft 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 文档。

测试 SSL/TLS 连接

在尝试从客户端应用程序访问已启用 SSL 的服务器之前,请确保可以通过 psql 访问它。 如果建立了 SSL 连接,应会看到如下所示的输出。

psql (14.5)SSL 连接(协议:TLSv1.2,密码:ECDHE-RSA-AES256-GCM-SHA384,位:256,压缩:关闭)键入“help”以获取帮助。

密码套件

密码套件是一组加密算法。 TLS/SSL 协议使用密码套件中的算法来创建密钥并对信息加密。 密码套件显示为看似随机信息的长字符串,但该字符串的每个段都包含重要信息。 通常,此数据字符串由几个关键组件组成:

  • 协议(即 TLS 1.2 或 TLS 1.3)
  • 密钥交换或协议算法
  • 数字签名(身份验证)算法
  • 批量加密算法
  • 消息验证码算法 (MAC)

不同版本的 SSL/TLS 支持不同的密码套件。 TLS 1.2 密码套件无法与 TLS 1.3 连接协商,反之亦然。 截至目前,Azure Database for PostgreSQL 灵活服务器支持采用 TLS 1.2 协议版本并属于 HIGH:!aNULL 类别的许多密码套件。

排查 SSL/TLS 连接错误故障

  1. 排查 SSL/TLS 协议版本兼容性问题的第一步是确定你或你的客户在尝试从客户端访问 TLS 加密的 Azure Database for PostgreSQL - 灵活服务器时看到的错误消息。 错误消息在各应用程序和平台可能有所不同,但在许多情况下都会指向基础问题。
  2. 若要确定 SSL/TLS 协议版本兼容性,应检查数据库服务器和应用程序客户端的 SSL/TLS 配置,确保它们支持兼容的版本和密码套件。
  3. 分析数据库服务器与客户端 SSL/TLS 版本和密码套件之间的任何差异或差距,并尝试通过启用或禁用某些选项、升级或降级软件或更改证书或密钥来解决它们。 例如,可能需要根据安全性和兼容性要求在服务器或客户端上启用或禁用特定的 SSL/TLS 版本(例如禁用不安全且已弃用的 TLS 1.0 和 TLS 1.1),并启用更安全且更新的 TLS 1.2 和 TLS 1.3。
  • 了解如何在 Azure 门户Azure CLI 中使用专用访问(VNet 集成)选项创建 Azure Database for PostgreSQL 灵活服务器实例。
  • 了解如何使用 Azure 门户Azure CLI 中的“公共访问(允许的 IP 地址)”选项创建 Azure Database for PostgreSQL 灵活服务器实例