[comment]: # ({5b8f0943-822969ff})
# 15 加密

[comment]: # ({/5b8f0943-822969ff})

[comment]: # ({73039a5b-0b118c23})
#### 概述

Zabbix 支持 Zabbix 各组件之间使用传输层安全（TLS）协议 v.1.2 和 1.3（取决于加密库）进行加密通信。支持基于证书和基于预共享密钥的加密。

可为以下连接配置加密：

-   在 Zabbix 服务器、Zabbix proxy、Zabbix agent、Zabbix Web 服务、zabbix\_sender 和 zabbix\_get 工具之间
-   到 Zabbix 数据库的连接[（从 Zabbix 前端和 server/proxy）](/manual/appendix/install/db_encrypt)
-   在 Zabbix 前端和 Zabbix 服务器之间

加密是可选的，并且可为各个组件单独配置：

-   某些 proxy 和 agent 可配置为与服务器使用基于证书的加密，而其他组件可使用基于预共享密钥的加密，还有一些则可继续使用未加密通信（与之前一样）。
-   服务器（proxy）可针对不同主机使用不同的加密配置。

Zabbix 守护进程使用同一个监听端口同时处理加密和未加密的传入连接。启用加密无需在防火墙上开放新的端口。

[comment]: # ({/73039a5b-0b118c23})

[comment]: # ({8fd79214-bdc6b202})
#### 限制

-   私钥以明文形式存储在文件中，Zabbix 组件在启动期间可读取这些文件。
-   预共享密钥在 Zabbix 前端中输入，并以明文形式存储在 Zabbix 数据库中。
-   内置加密不会保护运行 Zabbix 前端的 Web 服务器与用户 Web 浏览器之间的通信。
-   当前，每个加密连接都会通过完整的 TLS 握手建立，未实现会话缓存和票据机制。
-   启用加密会增加监控项检查和动作所需的时间，具体取决于网络延迟：
    -   例如，如果数据包延迟为 100ms，那么建立 TCP 连接并发送未加密请求大约需要 200ms。
        使用加密时，建立 TLS 连接还会额外增加约 1000ms。
    -   可能需要增加超时时间，否则某些在 agent 上运行远程脚本的监控项和动作在未加密连接下可以正常工作，但在加密连接下可能会因超时而失败。
-   [网络发现](/manual/discovery/network_discovery) 不支持加密。网络发现执行的 Zabbix agent 检查将不会加密；如果 Zabbix agent 被配置为拒绝未加密连接，则此类检查将无法成功。

[comment]: # ({/8fd79214-bdc6b202})

[comment]: # ({e2b185de-ba7ecc58})
#### 编译启用加密支持的 Zabbix

要支持加密，Zabbix 必须使用以下受支持的加密库之一进行编译和链接：

-   GnuTLS - 3.1.18 及以上版本
-   OpenSSL - 1.0.1、1.0.2、1.1.0、1.1.1、3.0.x 版本
-   LibreSSL - 已在 2.7.4、2.8.2 版本上测试：
    -   不支持 LibreSSL 2.6.x
    -   LibreSSL 作为 OpenSSL 的兼容替代品受到支持；
        不会使用新的 `tls_*()` LibreSSL 专用 API 函数。
        使用 LibreSSL 编译的 Zabbix 组件将无法使用
        PSK，只能使用证书。

:::notetip
您可以参考这些[最佳实践](/manual/best_practices/cryptography#setting-up-ssl-for-zabbix-frontend)了解更多关于为 Zabbix 前端配置 SSL 的信息。
:::

通过在 "configure" 脚本中指定相应选项来选择库：

-   `--with-gnutls[=DIR]`
-   `--with-openssl[=DIR]`（也用于 LibreSSL）

例如，要使用 *OpenSSL* 为服务器和 agent 配置源代码，可以使用如下命令：

    ./configure --enable-server --enable-agent --with-mysql --enable-ipv6 --with-net-snmp --with-libcurl --with-libxml2 --with-openssl

不同的 Zabbix 组件可以使用不同的加密库进行编译（例如，服务器使用 *OpenSSL*，agent 使用 *GnuTLS*）。

::: noteimportant
 如果您计划使用预共享密钥（PSK），
建议在使用 PSK 的 Zabbix 组件中使用 *GnuTLS* 或 *OpenSSL 1.1.0*（或更新版本）库。*GnuTLS* 和 *OpenSSL 1.1.0* 库
支持带有 [完全前向保密](https://en.wikipedia.org/wiki/Forward_secrecy#Perfect_forward_secrecy_.28PFS.29) 的 PSK 密码套件。
较旧版本的 *OpenSSL* 库（1.0.1、1.0.2c）也支持 PSK，但可用的 PSK 密码套件不提供完全前向保密。
:::

[comment]: # ({/e2b185de-ba7ecc58})

[comment]: # ({0f96d146-2d0e2b80})
#### 连接加密管理

Zabbix 中的连接可以使用：

-   不加密（默认）
-   [基于 RSA 证书的加密](/manual/encryption/using_certificates)
-   [基于 PSK 的加密](/manual/encryption/using_pre_shared_keys)

有两个重要参数用于指定 Zabbix 组件之间的加密方式：

-   TLSConnect - 指定出站连接使用何种加密方式（不加密、PSK 或证书）
-   TLSAccept - 指定入站连接允许哪些类型的连接（不加密、PSK 或证书）。可以指定一个或多个值。

`TLSConnect` 用于 Zabbix proxy 的配置文件中（在主动模式下，仅指定到服务器的连接）以及 Zabbix agent 的配置文件中（用于主动检查）。在 Zabbix 前端中，与 TLSConnect 对应的是 *数据采集 → 主机 → <某个主机> → 加密* 选项卡中的 *到主机的连接* 字段，以及 *管理 → Proxies → <某个 proxy> → 加密* 选项卡中的 *到 proxy 的连接* 字段。如果已配置的连接加密类型失败，则不会尝试其他加密类型。

`TLSAccept` 用于 Zabbix proxy 的配置文件中（在被动模式下，仅指定来自服务器的连接）以及 Zabbix agent 的配置文件中（用于被动检查）。在 Zabbix 前端中，与 TLSAccept 对应的是 *数据采集 → 主机 → <某个主机> → 加密* 选项卡中的 *来自主机的连接* 字段，以及 *管理 → Proxies → <某个 proxy> → 加密* 选项卡中的 *来自 proxy 的连接* 字段。

通常，你只需为入站连接配置一种加密类型。但你可能希望切换加密类型，例如从不加密切换为基于证书的加密，同时尽量减少停机时间并保留回滚的可能性。为此：

-   在 agent 配置文件中设置 `TLSAccept=unencrypted,cert`，然后重启 Zabbix agent
-   使用 zabbix\_get 通过证书测试到 agent 的连接。如果可行，则可以在 Zabbix 前端的 *数据采集 → 主机 → <某个主机> → 加密* 选项卡中，将 *到主机的连接* 设置为“证书”，从而为该 agent 重新配置加密
-   当服务器配置缓存更新后（如果该主机由 proxy 监控，则 proxy 配置也会更新），到该 agent 的连接将被加密
-   如果一切都按预期工作，则可以在 agent 配置文件中设置 `TLSAccept=cert`，然后重启 Zabbix agent。此时，agent 将只接受基于证书的加密连接。不加密连接和基于 PSK 的连接将被拒绝。

服务器和 proxy 的工作方式类似。如果在 Zabbix 前端的主机配置中，*来自主机的连接* 设置为“证书”，则只会接受来自 agent（主动检查）和 zabbix\_sender（trapper 监控项）的基于证书的加密连接。

在大多数情况下，你会将入站和出站连接配置为使用相同的加密类型，或者完全不加密。但从技术上讲，也可以进行非对称配置，例如入站连接使用基于证书的加密，而出站连接使用基于 PSK 的加密。

每个主机的加密配置都会显示在 Zabbix 前端的 *数据采集 → 主机* 中的 *Agent 加密* 列。例如：

|示例|到主机的连接|允许来自主机的连接|拒绝来自主机的连接|
|-------|-------------------|-----------------------------|------------------------------|
|![none\_none.png](../../assets/en/manual/encryption/none_none.png)|不加密|不加密|加密连接、基于证书的加密连接和基于 PSK 的加密连接|
|![cert\_cert.png](../../assets/en/manual/encryption/cert_cert.png)|加密，基于证书|加密，基于证书|不加密连接和基于 PSK 的加密连接|
|![psk\_psk.png](../../assets/en/manual/encryption/psk_psk.png)|加密，基于 PSK|加密，基于 PSK|不加密连接和基于证书的加密连接|
|![psk\_none\_psk.png](../../assets/en/manual/encryption/psk_none_psk.png)|加密，基于 PSK|不加密连接和基于 PSK 的加密连接|基于证书的加密连接|
|![cert\_all.png](../../assets/en/manual/encryption/cert_all.png)|加密，基于证书|不加密连接、基于 PSK 的加密连接或基于证书的加密连接|\-|

::: noteimportant
默认情况下，连接不加密。必须为每个主机和 proxy 单独配置加密。
:::

[comment]: # ({/0f96d146-2d0e2b80})

[comment]: # ({ad15e6ff-ad15e6ff})

#### zabbix\_get and zabbix\_sender与加密

请参阅[zabbix\_get](/manpages/zabbix_get)和[zabbix\_sender](/manpages/zabbix_sender) 操作说明使用加密。

[comment]: # ({/ad15e6ff-ad15e6ff})

[comment]: # ({6f67a86b-be2996e2})
#### 密码套件

默认情况下，密码套件会在 Zabbix 启动期间于内部进行配置。

同时也支持为 GnuTLS 和 OpenSSL 配置用户自定义的密码套件。用户可以根据其安全策略[配置](#userconfigured-ciphersuites)密码套件。使用此功能是可选的（内置的默认密码套件仍然有效）。

对于使用默认设置编译的加密库，Zabbix 内置规则通常会产生以下密码套件（按优先级从高到低排序）：

|Library|Certificate ciphersuites|PSK ciphersuites|
|-------|------------------------|----------------|
|*GnuTLS 3.1.18*|TLS\_ECDHE\_RSA\_AES\_128\_GCM\_SHA256<br>TLS\_ECDHE\_RSA\_AES\_128\_CBC\_SHA256<br>TLS\_ECDHE\_RSA\_AES\_128\_CBC\_SHA1<br>TLS\_RSA\_AES\_128\_GCM\_SHA256<br>TLS\_RSA\_AES\_128\_CBC\_SHA256<br>TLS\_RSA\_AES\_128\_CBC\_SHA1|TLS\_ECDHE\_PSK\_AES\_128\_CBC\_SHA256<br>TLS\_ECDHE\_PSK\_AES\_128\_CBC\_SHA1<br>TLS\_PSK\_AES\_128\_GCM\_SHA256<br>TLS\_PSK\_AES\_128\_CBC\_SHA256<br>TLS\_PSK\_AES\_128\_CBC\_SHA1|
|*OpenSSL 1.0.2c*|ECDHE-RSA-AES128-GCM-SHA256<br>ECDHE-RSA-AES128-SHA256<br>ECDHE-RSA-AES128-SHA<br>AES128-GCM-SHA256<br>AES128-SHA256<br>AES128-SHA|PSK-AES128-CBC-SHA|
|*OpenSSL 1.1.0*|ECDHE-RSA-AES128-GCM-SHA256<br>ECDHE-RSA-AES128-SHA256<br>ECDHE-RSA-AES128-SHA<br>AES128-GCM-SHA256<br>AES128-CCM8<br>AES128-CCM<br>AES128-SHA256<br>AES128-SHA<br>|ECDHE-PSK-AES128-CBC-SHA256<br>ECDHE-PSK-AES128-CBC-SHA<br>PSK-AES128-GCM-SHA256<br>PSK-AES128-CCM8<br>PSK-AES128-CCM<br>PSK-AES128-CBC-SHA256<br>PSK-AES128-CBC-SHA|
|*OpenSSL 1.1.1d*|TLS\_AES\_256\_GCM\_SHA384<br>TLS\_CHACHA20\_POLY1305\_SHA256<br>TLS\_AES\_128\_GCM\_SHA256<br>ECDHE-RSA-AES128-GCM-SHA256<br>ECDHE-RSA-AES128-SHA256<br>ECDHE-RSA-AES128-SHA<br>AES128-GCM-SHA256<br>AES128-CCM8<br>AES128-CCM<br>AES128-SHA256<br>AES128-SHA|TLS\_CHACHA20\_POLY1305\_SHA256<br>TLS\_AES\_128\_GCM\_SHA256<br>ECDHE-PSK-AES128-CBC-SHA256<br>ECDHE-PSK-AES128-CBC-SHA<br>PSK-AES128-GCM-SHA256<br>PSK-AES128-CCM8<br>PSK-AES128-CCM<br>PSK-AES128-CBC-SHA256<br>PSK-AES128-CBC-SHA|

[comment]: # ({/6f67a86b-be2996e2})

[comment]: # ({8731bb52-b5e04652})
#### 用户配置的密码套件

内置的密码套件选择条件可以通过用户配置的密码套件进行覆盖。

::: noteimportant
用户配置的密码套件是一项面向高级用户的功能，适用于了解 TLS 密码套件、其安全性及配置错误后果，并且能够熟练进行 TLS 故障排查的用户。
:::

内置的密码套件选择条件可以使用以下参数进行覆盖：

|覆盖范围|参数|值|说明|
|--|--|------|------|
|证书的密码套件选择|TLSCipherCert13|适用于 TLS 1.3 协议的有效 OpenSSL 1.1.1 [cipher strings](https://www.openssl.org/docs/man1.1.1/man1/ciphers.html)（其值会传递给 OpenSSL 函数 `SSL_CTX_set_ciphersuites()`）。|TLS 1.3 的基于证书的密码套件选择条件<br><br>仅适用于 OpenSSL 1.1.1 或更高版本。|
|^|TLSCipherCert|适用于 TLS 1.2 的有效 OpenSSL [cipher strings](https://www.openssl.org/docs/man1.1.1/man1/ciphers.html)，或有效的 GnuTLS [priority strings](https://gnutls.org/manual/html_node/Priority-Strings.html)。其值分别传递给 `SSL_CTX_set_cipher_list()` 或 `gnutls_priority_init()` 函数。|TLS 1.2/1.3（GnuTLS）、TLS 1.2（OpenSSL）的基于证书的密码套件选择条件|
|PSK 的密码套件选择|TLSCipherPSK13|适用于 TLS 1.3 协议的有效 OpenSSL 1.1.1 [cipher strings](https://www.openssl.org/docs/man1.1.1/man1/ciphers.html)（其值会传递给 OpenSSL 函数 `SSL_CTX_set_ciphersuites()`）。|TLS 1.3 的基于 PSK 的密码套件选择条件<br><br>仅适用于 OpenSSL 1.1.1 或更高版本。|
|^|TLSCipherPSK|适用于 TLS 1.2 的有效 OpenSSL [cipher strings](https://www.openssl.org/docs/man1.1.1/man1/ciphers.html)，或有效的 GnuTLS [priority strings](https://gnutls.org/manual/html_node/Priority-Strings.html)。其值分别传递给 `SSL_CTX_set_cipher_list()` 或 `gnutls_priority_init()` 函数。|TLS 1.2/1.3（GnuTLS）、TLS 1.2（OpenSSL）的基于 PSK 的密码套件选择条件|
|证书和 PSK 的组合密码套件列表|TLSCipherAll13|适用于 TLS 1.3 协议的有效 OpenSSL 1.1.1 [cipher strings](https://www.openssl.org/docs/man1.1.1/man1/ciphers.html)（其值会传递给 OpenSSL 函数 `SSL_CTX_set_ciphersuites()`）。|TLS 1.3 的密码套件选择条件<br><br>仅适用于 OpenSSL 1.1.1 或更高版本。|
|^|TLSCipherAll|适用于 TLS 1.2 的有效 OpenSSL [cipher strings](https://www.openssl.org/docs/man1.1.1/man1/ciphers.html)，或有效的 GnuTLS [priority strings](https://gnutls.org/manual/html_node/Priority-Strings.html)。其值分别传递给 `SSL_CTX_set_cipher_list()` 或 `gnutls_priority_init()` 函数。|TLS 1.2/1.3（GnuTLS）、TLS 1.2（OpenSSL）的密码套件选择条件|

要覆盖 [zabbix\_get](/manpages/zabbix_get) 和 [zabbix\_sender](/manpages/zabbix_sender) 工具中的密码套件选择，请使用以下命令行参数：

-   `--tls-cipher13`
-   `--tls-cipher`

这些新参数是可选的。如果未指定某个参数，则使用内部默认值。如果定义了某个参数，则其值不能为空。

如果在加密库中设置 TLSCipher\* 值失败，则服务器、proxy 或 agent 将无法启动，并会记录错误日志。

理解每个参数在何种情况下适用非常重要。

[comment]: # ({/8731bb52-b5e04652})

[comment]: # ({ca5e66e4-a74c28c7})
##### 出站连接

最简单的情况是出站连接：

-   对于使用证书的出站连接，请使用 TLSCipherCert13 或
    TLSCipherCert
-   对于使用 PSK 的出站连接，请使用 TLSCipherPSK13 或
    TLSCipherPSK
-   对于 zabbix\_get 和 zabbix\_sender 工具，可以使用命令行
    参数 `--tls-cipher13` 或 `--tls-cipher`
    （加密方式可通过 `--tls-connect`
    参数明确指定）

[comment]: # ({/ca5e66e4-a74c28c7})

[comment]: # ({29364114-3edf3b2b})
##### 入站连接

对于入站连接，情况会稍微复杂一些，因为规则取决于具体组件和配置。

对于 Zabbix **agent**：

|Agent connection setup|Cipher configuration|
|----------------------|--------------------|
|TLSConnect=cert|TLSCipherCert, TLSCipherCert13|
|TLSConnect=psk|TLSCipherPSK, TLSCipherPSK13|
|TLSAccept=cert|TLSCipherCert, TLSCipherCert13|
|TLSAccept=psk|TLSCipherPSK, TLSCipherPSK13|
|TLSAccept=cert,psk|TLSCipherAll, TLSCipherAll13|

对于 Zabbix **服务器** 和 **proxy**：

|Connection setup|Cipher configuration|
|----------------|--------------------|
|使用 PSK 的出站连接|TLSCipherPSK, TLSCipherPSK13|
|使用证书的入站连接|TLSCipherAll, TLSCipherAll13|
|如果服务器没有证书，则使用 PSK 的入站连接|TLSCipherPSK, TLSCipherPSK13|
|如果服务器有证书，则使用 PSK 的入站连接|TLSCipherAll, TLSCipherAll13|

从上面的两个表中可以看出一些规律：

-   只有在使用基于证书 **和** 基于 PSK 的密码套件组合列表时，才能指定 TLSCipherAll 和 TLSCipherAll13。出现这种情况有两种场景：配置了证书的服务器（proxy）（如果加密库支持 PSK，则服务器、proxy 始终会配置 PSK 密码套件）；配置为同时接受基于证书和基于 PSK 的入站连接的 agent
-   在其他情况下，使用 TLSCipherCert\* 和/或 TLSCipherPSK\* 即可

下表显示了 `TLSCipher*` 的内置默认值。它们可以作为设置自定义值时的良好起点。

|Parameter|GnuTLS 3.6.12|
|--|--------|
|TLSCipherCert|NONE:+VERS-TLS1.2:+ECDHE-RSA:+RSA:+AES-128-GCM:+AES-128-CBC:+AEAD:+SHA256:+SHA1:+CURVE-ALL:+COMP-NULL:+SIGN-ALL:+CTYPE-X.509|
|TLSCipherPSK|NONE:+VERS-TLS1.2:+ECDHE-PSK:+PSK:+AES-128-GCM:+AES-128-CBC:+AEAD:+SHA256:+SHA1:+CURVE-ALL:+COMP-NULL:+SIGN-ALL|
|TLSCipherAll|NONE:+VERS-TLS1.2:+ECDHE-RSA:+RSA:+ECDHE-PSK:+PSK:+AES-128-GCM:+AES-128-CBC:+AEAD:+SHA256:+SHA1:+CURVE-ALL:+COMP-NULL:+SIGN-ALL:+CTYPE-X.509|

|Parameter|OpenSSL 1.1.1d ^**1**^|
|--|--------|
|TLSCipherCert13|<|
|TLSCipherCert|EECDH+aRSA+AES128:RSA+aRSA+AES128|
|TLSCipherPSK13|TLS\_CHACHA20\_POLY1305\_SHA256:TLS\_AES\_128\_GCM\_SHA256|
|TLSCipherPSK|kECDHEPSK+AES128:kPSK+AES128|
|TLSCipherAll13|<|
|TLSCipherAll|EECDH+aRSA+AES128:RSA+aRSA+AES128:kECDHEPSK+AES128:kPSK+AES128|

^**1**^ 对于较旧版本的 OpenSSL（1.0.1、1.0.2、1.1.0）、LibreSSL，以及在编译 OpenSSL 时未启用 PSK 支持的情况，默认值会有所不同。

**用户配置的密码套件示例**

请参见以下用户配置密码套件的示例：

-   [测试密码字符串并仅允许 PFS 密码套件](#testing-cipher-strings-and-allowing-only-pfs-ciphersuites)
-   [从 AES128 切换到 AES256](#switching-from-aes128-to-aes256)

[comment]: # ({/29364114-3edf3b2b})

[comment]: # ({52b821c4-bfb4ef88})
##### 测试密码套件字符串并仅允许 PFS 密码套件

要查看已选择了哪些密码套件，您需要在配置文件中设置
`DebugLevel=4`，或者对 zabbix\_sender 使用 `-vv` 选项。

在获得所需的密码套件之前，可能需要对 `TLSCipher*` 参数进行一些
试验。仅仅为了微调 `TLSCipher*` 参数而多次重启 Zabbix 服务器、proxy 或 agent
会很不方便。更方便的选项是使用 zabbix\_sender 或 `openssl` 命令。下面我们两种方法都演示。

**1.** 使用 zabbix\_sender。

让我们创建一个测试配置文件，例如
`/home/zabbix/test.conf`，其语法与 `zabbix_agentd.conf` 文件相同：

      Hostname=nonexisting
      ServerActive=nonexisting
      
      TLSConnect=cert
      TLSCAFile=/home/zabbix/ca.crt
      TLSCertFile=/home/zabbix/agent.crt
      TLSKeyFile=/home/zabbix/agent.key
      TLSPSKIdentity=nonexisting
      TLSPSKFile=/home/zabbix/agent.psk

此示例需要有效的 CA 和 agent 证书以及 PSK。
请根据您的环境调整证书和 PSK 文件的路径及名称。

如果您不使用证书，而只使用 PSK，则可以创建一个更简单的
测试文件：

      Hostname=nonexisting
      ServerActive=nonexisting
      
      TLSConnect=psk
      TLSPSKIdentity=nonexisting
      TLSPSKFile=/home/zabbix/agentd.psk

通过运行 zabbix\_sender 可以看到所选的密码套件（示例
使用 OpenSSL 1.1.d 编译）：

      $ zabbix_sender -vv -c /home/zabbix/test.conf -k nonexisting_item -o 1 2>&1 | grep ciphersuites
      zabbix_sender [41271]: DEBUG: zbx_tls_init_child() certificate ciphersuites: TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 TLS_AES_128_GCM_SHA256 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-RSA-AES128-SHA AES128-GCM-SHA256 AES128-CCM8 AES128-CCM AES128-SHA256 AES128-SHA
      zabbix_sender [41271]: DEBUG: zbx_tls_init_child() PSK ciphersuites: TLS_CHACHA20_POLY1305_SHA256 TLS_AES_128_GCM_SHA256 ECDHE-PSK-AES128-CBC-SHA256 ECDHE-PSK-AES128-CBC-SHA PSK-AES128-GCM-SHA256 PSK-AES128-CCM8 PSK-AES128-CCM PSK-AES128-CBC-SHA256 PSK-AES128-CBC-SHA
      zabbix_sender [41271]: DEBUG: zbx_tls_init_child() certificate and PSK ciphersuites: TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 TLS_AES_128_GCM_SHA256 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-RSA-AES128-SHA AES128-GCM-SHA256 AES128-CCM8 AES128-CCM AES128-SHA256 AES128-SHA ECDHE-PSK-AES128-CBC-SHA256 ECDHE-PSK-AES128-CBC-SHA PSK-AES128-GCM-SHA256 PSK-AES128-CCM8 PSK-AES128-CCM PSK-AES128-CBC-SHA256 PSK-AES128-CBC-SHA

这里您看到的是默认选择的密码套件。这些默认值
是为了确保与运行在较旧 OpenSSL 版本（从 1.0.1 起）的系统上的
Zabbix agent 之间的互操作性而选择的。

在较新的系统上，您可以选择通过仅允许少量密码套件来加强安全性，
例如仅允许具有 PFS（Perfect Forward
Secrecy，完全前向保密）的密码套件。下面我们尝试使用
`TLSCipher*` 参数仅允许具有 PFS 的密码套件。

::: noteimportant
如果使用 PSK，则结果将无法与使用
OpenSSL 1.0.1 和 1.0.2 的系统互操作。基于证书的
加密应当可以正常工作。
:::

向 `test.conf` 配置文件中添加两行：

      TLSCipherCert=EECDH+aRSA+AES128
      TLSCipherPSK=kECDHEPSK+AES128

然后再次测试：

      $ zabbix_sender -vv -c /home/zabbix/test.conf -k nonexisting_item -o 1 2>&1 | grep ciphersuites            
      zabbix_sender [42892]: DEBUG: zbx_tls_init_child() certificate ciphersuites: TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 TLS_AES_128_GCM_SHA256 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-RSA-AES128-SHA        
      zabbix_sender [42892]: DEBUG: zbx_tls_init_child() PSK ciphersuites: TLS_CHACHA20_POLY1305_SHA256 TLS_AES_128_GCM_SHA256 ECDHE-PSK-AES128-CBC-SHA256 ECDHE-PSK-AES128-CBC-SHA        
      zabbix_sender [42892]: DEBUG: zbx_tls_init_child() certificate and PSK ciphersuites: TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 TLS_AES_128_GCM_SHA256 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-RSA-AES128-SHA AES128-GCM-SHA256 AES128-CCM8 AES128-CCM AES128-SHA256 AES128-SHA ECDHE-PSK-AES128-CBC-SHA256 ECDHE-PSK-AES128-CBC-SHA PSK-AES128-GCM-SHA256 PSK-AES128-CCM8 PSK-AES128-CCM PSK-AES128-CBC-SHA256 PSK-AES128-CBC-SHA        

“certificate ciphersuites”和“PSK ciphersuites”列表已经发生变化
—— 它们比之前更短，正如预期的那样，只包含 TLS 1.3 密码套件以及
TLS 1.2 ECDHE-\* 密码套件。

**2.** 无法使用 zabbix\_sender 测试 TLSCipherAll 和 TLSCipherAll13；
它们不会影响上面示例中显示的 “certificate and PSK ciphersuites”
值。要调整 TLSCipherAll 和
TLSCipherAll13，您需要使用 agent、proxy 或服务器进行试验。

因此，要仅允许 PFS 密码套件，您可能需要将最多三个
参数

      TLSCipherCert=EECDH+aRSA+AES128
      TLSCipherPSK=kECDHEPSK+AES128
      TLSCipherAll=EECDH+aRSA+AES128:kECDHEPSK+AES128

添加到 zabbix\_agentd.conf、zabbix\_proxy.conf 和 zabbix\_server\_conf 中，如果
它们各自都配置了证书，并且 agent 还配置了 PSK。

如果您的 Zabbix 环境仅使用基于 PSK 的加密而不使用
证书，那么只需要这一个：

      TLSCipherPSK=kECDHEPSK+AES128

现在您已经了解其工作方式，甚至可以在 Zabbix 之外
使用 `openssl` 命令测试密码套件选择。下面测试全部三个 `TLSCipher*`
参数值：

      $ openssl ciphers EECDH+aRSA+AES128 | sed 's/:/ /g'
      TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 TLS_AES_128_GCM_SHA256 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-RSA-AES128-SHA
      $ openssl ciphers kECDHEPSK+AES128 | sed 's/:/ /g'
      TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 TLS_AES_128_GCM_SHA256 ECDHE-PSK-AES128-CBC-SHA256 ECDHE-PSK-AES128-CBC-SHA
      $ openssl ciphers EECDH+aRSA+AES128:kECDHEPSK+AES128 | sed 's/:/ /g'
      TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 TLS_AES_128_GCM_SHA256 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-RSA-AES128-SHA ECDHE-PSK-AES128-CBC-SHA256 ECDHE-PSK-AES128-CBC-SHA
      

您可能更喜欢使用带 `-V` 选项的 `openssl ciphers`，以获得更详细的
输出：

      $ openssl ciphers -V EECDH+aRSA+AES128:kECDHEPSK+AES128
                0x13,0x02 - TLS_AES_256_GCM_SHA384  TLSv1.3 Kx=any      Au=any  Enc=AESGCM(256) Mac=AEAD
                0x13,0x03 - TLS_CHACHA20_POLY1305_SHA256 TLSv1.3 Kx=any      Au=any  Enc=CHACHA20/POLY1305(256) Mac=AEAD
                0x13,0x01 - TLS_AES_128_GCM_SHA256  TLSv1.3 Kx=any      Au=any  Enc=AESGCM(128) Mac=AEAD
                0xC0,0x2F - ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AESGCM(128) Mac=AEAD
                0xC0,0x27 - ECDHE-RSA-AES128-SHA256 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AES(128)  Mac=SHA256
                0xC0,0x13 - ECDHE-RSA-AES128-SHA    TLSv1 Kx=ECDH     Au=RSA  Enc=AES(128)  Mac=SHA1
                0xC0,0x37 - ECDHE-PSK-AES128-CBC-SHA256 TLSv1 Kx=ECDHEPSK Au=PSK  Enc=AES(128)  Mac=SHA256
                0xC0,0x35 - ECDHE-PSK-AES128-CBC-SHA TLSv1 Kx=ECDHEPSK Au=PSK  Enc=AES(128)  Mac=SHA1

类似地，您也可以测试 GnuTLS 的优先级字符串：

      $ gnutls-cli -l --priority=NONE:+VERS-TLS1.2:+ECDHE-RSA:+AES-128-GCM:+AES-128-CBC:+AEAD:+SHA256:+CURVE-ALL:+COMP-NULL:+SIGN-ALL:+CTYPE-X.509
      Cipher suites for NONE:+VERS-TLS1.2:+ECDHE-RSA:+AES-128-GCM:+AES-128-CBC:+AEAD:+SHA256:+CURVE-ALL:+COMP-NULL:+SIGN-ALL:+CTYPE-X.509
      TLS_ECDHE_RSA_AES_128_GCM_SHA256                        0xc0, 0x2f      TLS1.2
      TLS_ECDHE_RSA_AES_128_CBC_SHA256                        0xc0, 0x27      TLS1.2
      
      Protocols: VERS-TLS1.2
      Ciphers: AES-128-GCM, AES-128-CBC
      MACs: AEAD, SHA256
      Key Exchange Algorithms: ECDHE-RSA
      Groups: GROUP-SECP256R1, GROUP-SECP384R1, GROUP-SECP521R1, GROUP-X25519, GROUP-X448, GROUP-FFDHE2048, GROUP-FFDHE3072, GROUP-FFDHE4096, GROUP-FFDHE6144, GROUP-FFDHE8192
      PK-signatures: SIGN-RSA-SHA256, SIGN-RSA-PSS-SHA256, SIGN-RSA-PSS-RSAE-SHA256, SIGN-ECDSA-SHA256, SIGN-ECDSA-SECP256R1-SHA256, SIGN-EdDSA-Ed25519, SIGN-RSA-SHA384, SIGN-RSA-PSS-SHA384, SIGN-RSA-PSS-RSAE-SHA384, SIGN-ECDSA-SHA384, SIGN-ECDSA-SECP384R1-SHA384, SIGN-EdDSA-Ed448, SIGN-RSA-SHA512, SIGN-RSA-PSS-SHA512, SIGN-RSA-PSS-RSAE-SHA512, SIGN-ECDSA-SHA512, SIGN-ECDSA-SECP521R1-SHA512, SIGN-RSA-SHA1, SIGN-ECDSA-SHA1

[comment]: # ({/52b821c4-bfb4ef88})

[comment]: # ({a549cda7-a549cda7})

##### 从AES128 到 AES256切换


Zabbix 使用 AES128 作为数据的内置默认值。假设您正在使用证书并希望在 OpenSSL 1.1.1 上切换到 AES256。

这可以通过在配置文件中添加相应的参数来实现。
`zabbix_server.conf`:

      TLSCAFile=/home/zabbix/ca.crt
      TLSCertFile=/home/zabbix/server.crt
      TLSKeyFile=/home/zabbix/server.key
      TLSCipherCert13=TLS_AES_256_GCM_SHA384
      TLSCipherCert=EECDH+aRSA+AES256:-SHA1:-SHA384
      TLSCipherPSK13=TLS_CHACHA20_POLY1305_SHA256
      TLSCipherPSK=kECDHEPSK+AES256:-SHA1
      TLSCipherAll13=TLS_AES_256_GCM_SHA384
      TLSCipherAll=EECDH+aRSA+AES256:-SHA1:-SHA384

::: noteimportant
虽然只会使用与证书相关的密码套件，但也定义了 `TLSCipherPSK*` 参数，以避免其默认值包含为更广泛的互操作性而设计的安全性较低的密码。PSK 密码套件不能在server/proxy上完全禁用。
:::

和在 `zabbix_agentd.conf`:

      TLSConnect=cert
      TLSAccept=cert
      TLSCAFile=/home/zabbix/ca.crt
      TLSCertFile=/home/zabbix/agent.crt
      TLSKeyFile=/home/zabbix/agent.key
      TLSCipherCert13=TLS_AES_256_GCM_SHA384
      TLSCipherCert=EECDH+aRSA+AES256:-SHA1:-SHA384

[comment]: # ({/a549cda7-a549cda7})
