加密与 Linux 上的 SQL Server 的连接

适用于:SQL Server - Linux

Linux 上的 SQL Server 可以使用传输层安全性 (TLS) 对通过网络在客户端应用程序与 SQL Server 实例之间传输的数据进行加密。 SQL Server 在 Windows 和 Linux 上支持相同的 TLS 协议:TLS 1.2、1.1 和 1.0。 但是,配置 TLS 的步骤特定于运行 SQL Server 的操作系统。

证书要求

在开始之前,需要确保证书符合以下要求:

  • 当前系统时间必须晚于证书的 Valid from 属性,并早于证书的 Valid to 属性。

  • 该证书必须用于服务器身份验证。 这需要 Enhanced Key Usage 证书的属性才能指定 Server Authentication (1.3.6.1.5.5.7.3.1)

  • 必须使用 AT_KEYEXCHANGEKeySpec 选项创建该证书。 通常,证书的密钥使用属性 (KEY_USAGE) 还包括密钥加密 (CERT_KEY_ENCIPHERMENT_KEY_USAGE)。

  • 证书的 Subject 属性必须指明,证书公用名称 (CN) 与服务器计算机的主机名或完全限定的域名 (FQDN) 相同。

    注意

    支持通配符证书。

配置要使用的 OpenSSL 库(可选)

可以在 /opt/mssql/lib/ 目录中创建符号链接,以引用应当用于加密的 libcrypto.solibssl.so 库。 若要强制 SQL Server 使用特定的 OpenSSL 版本,而不是系统提供的默认版本,此方法非常有用。 如果未提供这些符号链接,SQL Server 将在系统上加载默认配置的 OpenSSL 库。

这些符号链接应命名为 libcrypto.solibssl.so,并放在 /opt/mssql/lib/ 目录中。

概述

TLS 用于加密从客户端应用程序到 SQL Server 的连接。 正确配置后,TLS 可为客户端和服务器之间的通信提供隐私和数据完整性。 TLS 连接可以是客户端启动的或服务器启动的。

以下部分将介绍如何设置客户端启动的加密。

生成证书

/CN 应与 SQL Server 主机的完全限定的域名匹配。

注意

本例使用自签名证书。 自签名证书不应该用于生产方案。 你应该使用 CA 证书。

确保你保存证书和私钥的文件夹可供 mssql 用户/组访问,并且权限设置为 700 (drwx-----)。 你可手动创建文件夹,将该文件夹的权限设置为 700 (drwx------),归 mssql 用户/组所有,或者将该文件夹的权限设置为 755 (drwxr-xr-x),归其他用户所有,但仍可供 mssql 用户组访问。 例如,可在路径 /var/opt/mssql/ 下创建名称为 sslcert 的文件夹,并保存证书和私钥,对文件集的权限设置为 600,如以下示例所示。

openssl req -x509 -nodes -newkey rsa:2048 -subj '/CN=mssql.contoso.com' -keyout mssql.key -out mssql.pem -days 365
sudo chown mssql:mssql mssql.pem mssql.key
sudo chmod 600 mssql.pem mssql.key
#Saving the certificate to the certs folder under /etc/ssl/ which has the following permission 755(drwxr-xr-x)
sudo mv mssql.pem /etc/ssl/certs/ drwxr-xr-x
#Saving the private key to the private folder under /etc/ssl/ with permissions set to 755(drwxr-xr-x)
sudo mv mssql.key /etc/ssl/private/

配置 SQL Server

systemctl stop mssql-server
sudo cat /var/opt/mssql/mssql.conf
sudo /opt/mssql/bin/mssql-conf set network.tlscert /etc/ssl/certs/mssql.pem
sudo /opt/mssql/bin/mssql-conf set network.tlskey /etc/ssl/private/mssql.key
sudo /opt/mssql/bin/mssql-conf set network.tlsprotocols 1.2
sudo /opt/mssql/bin/mssql-conf set network.forceencryption 0
systemctl restart mssql-server

在客户端计算机(Windows、Linux 或 macOS)上注册证书

  • 如果使用 CA 签名证书,则必须将证书颁发机构 (CA) 证书而不是用户证书复制到客户端计算机。
  • 如果使用自签名证书,只需根据分发版将 .pem 文件复制到以下文件夹中,然后执行命令启用它们:
  • Ubuntu:将证书复制到 /usr/share/ca-certificates/,将其扩展名重命名为 .crt,并使用 dpkg-reconfigure ca-certificates 将其作为系统 CA 证书启用。
  • RHEL:将证书复制到 /etc/pki/ca-trust/source/anchors/,并使用 update-ca-trust 将其作为系统 CA 证书启用。
  • SUSE:将证书复制到 /usr/share/pki/trust/anchors/,并使用 update-ca-certificates 将其作为系统 CA 证书启用。
  • Windows:将 .pem 文件作为证书导入(在当前用户 > 受信任的根证书颁发机构 > 证书下。
  • macOS
    • 将证书复制到 /usr/local/etc/openssl/certs

    • 运行以下命令获取哈希值:

      /usr/local/Cellar/openssl/1.0.2l/openssl x509 -hash -in mssql.pem -noout
      
    • 将证书重命名为该值。 例如:mv mssql.pem dc2dd900.0。 确保 dc2dd900.0 位于 /usr/local/etc/openssl/certs

连接字符串示例

  • SQL Server Management Studio

    Screenshot of SQL Server Management Studio connection dialog.

  • SQLCMD

    sqlcmd -S <sqlhostname> -N -U sa -P '<YourPassword>'

  • ADO.NET

    "Encrypt=True; TrustServerCertificate=False;"

  • ODBC

    "Encrypt=Yes; TrustServerCertificate=no;"

  • JDBC

    "encrypt=true; trustServerCertificate=false;"

常见的连接错误

错误消息 Fix
The certificate chain was issued by an authority that is not trusted. 如果客户端在 TLS 握手期间无法验证 SQL Server 提供的证书上的签名,则会发生此错误。 请确保客户端直接信任 SQL Server 证书,或者信任签署 SQL Server 证书的 CA。
The target principal name is incorrect. 确保 SQL Server 证书上的“公用名”字段与客户端连接字符串中指定的服务器名称匹配。
An existing connection was forcibly closed by the remote host. 如果客户端不支持 SQL Server 所需的 TLS 协议版本,则会发生此错误。 例如,如果 SQL Server 配置为需要 TLS 1.2,请确保客户端也支持 TLS 1.2 协议。

Ubuntu 20.04 及其他最新的 Linux 发行版

症状

当 Linux 实例上的 SQL Server 加载由未达到 112 位安全性的签名算法(例如 MD5、SHA-1)创建的证书时,可能会看到连接失败错误,如下例所示:

已成功与服务器建立连接,但在登录过程中发生错误。 (提供程序:SSL 提供程序,错误:0 - 远程主机强行关闭现有连接。)(Microsoft SQL Server,错误:10054)

发生此错误的原因是 Ubuntu 20.04 及更高版本上默认启用了 OpenSSL 安全级别 2。 安全级别 2 禁止建立未达到 112 位安全性的 TLS 连接。

解决方案

安装采用至少达到 112 位安全性的签名算法的证书。 满足此要求的签名算法包括 SHA-224、SHA-256、SHA-384 和 SHA-512。