- 暗号化とセキュリティ
- 暗号化
- 暗号化サポート付きでZabbixをコンパイルする
- 接続の暗号化管理
- zabbix_get と zabbix_sender の暗号化対応
- 暗号スイート
- ユーザー設定の ciphersuite
- 暗号化の問題のトラブルシューティング
- 接続タイプまたは権限の問題のトラブルシューティング
- TLSサポート付きでコンパイルされた Zabbix sender を、TLS非対応でコンパイルされた Zabbix サーバー/プロキシにデータ送信しようとしています
- 一方はPSKで接続するが、もう一方はLibreSSLを使用しているか、暗号化サポートなしでコンパイルされている
- 一方は PSK で接続するが、もう一方は PSK サポートを無効にした OpenSSL を使用している
暗号化とセキュリティ
暗号化
Zabbix は、Transport Layer Security (TLS) プロトコル v.1.2 および 1.3(暗号ライブラリに依存)を使用して、Zabbix コンポーネント間の暗号化通信をサポートします。証明書ベースの暗号化と事前共有鍵ベースの暗号化がサポートされています。
暗号化は、次の接続に対して設定できます。
- Zabbix サーバー、Zabbix プロキシ、Zabbix エージェント、Zabbix web service、zabbix_sender および zabbix_get ユーティリティ間
- Zabbix データベースへの接続 Zabbix Webインターフェースおよび サーバー/プロキシから
- Zabbix Webインターフェースと Zabbix サーバー間
暗号化はオプションであり、個々のコンポーネントごとに設定できます。
- 一部のプロキシおよびエージェントは、サーバーとの通信に証明書ベースの暗号化を使用するよう設定でき、他のものは事前共有鍵ベースの暗号化を使用でき、さらに別のものは暗号化されていない通信のまま継続できます(従来どおり)。
- サーバー(プロキシ)は、ホストごとに異なる暗号化設定を使用できます。
Zabbix のデーモンプログラムは、暗号化された受信接続と暗号化されていない受信接続の両方に対して 1 つの待ち受けポートを使用します。暗号化を追加しても、ファイアウォールで新しいポートを開く必要はありません。
制限事項
- 秘密鍵は、起動時に Zabbix コンポーネントから読み取り可能なファイルに平文で保存されます。
- 事前共有鍵は Zabbix Webインターフェースで入力され、Zabbix データベースに平文で保存されます。
- 組み込みの暗号化は、Zabbix Webインターフェースを実行している Web サーバーとユーザーの Web ブラウザ間の通信を保護しません。
- 現在、暗号化された各接続は完全な TLS ハンドシェイクで開始され、セッションキャッシュやチケットは実装されていません。
- 暗号化を追加すると、ネットワーク遅延に応じてアイテムのチェックとアクションにかかる時間が増加します。
- たとえば、パケット遅延が 100ms の場合、TCP 接続を開いて暗号化されていない要求を送信するのに約 200ms かかります。暗号化を使用すると、TLS 接続の確立に約 1000 ms が追加されます。
- タイムアウトを増やす必要がある場合があります。そうしないと、エージェント上でリモートスクリプトを実行する一部のアイテムやアクションは、暗号化されていない接続では動作しても、暗号化された接続ではタイムアウトで失敗することがあります。
- ネットワークディスカバリ では暗号化はサポートされていません。ネットワークディスカバリによって実行される Zabbix エージェントのチェックは暗号化されず、Zabbix エージェントが暗号化されていない接続を拒否するように設定されている場合、これらのチェックは成功しません。
暗号化サポート付きでZabbixをコンパイルする
暗号化をサポートするには、Zabbixを以下のいずれかのサポート対象暗号ライブラリとともにコンパイルおよびリンクする必要があります。
- GnuTLS - バージョン3.1.18以降
- OpenSSL - バージョン1.0.1、1.0.2、1.1.0、1.1.1、3.0.x - 3.5.x
- LibreSSL - バージョン2.7.4、2.8.2でテスト済み:
- LibreSSL 2.6.xはサポートされていません
- LibreSSLはOpenSSLの互換代替としてサポートされています。新しい
tls_*()LibreSSL固有のAPI関数は使用されません。 LibreSSLでコンパイルされたZabbixコンポーネントではPSKを使用できず、証明書のみ使用できます。
ZabbixのWebインターフェースでSSLを設定する方法については、こちらのベストプラクティスを参照してください。
ライブラリは、configureスクリプトに対応するオプションを指定して選択します。
--with-gnutls[=DIR]--with-openssl[=DIR](LibreSSLにも使用)
例えば、OpenSSLを使用してサーバーとエージェントのソースを設定するには、次のように指定します。
./configure --enable-server --enable-agent --with-mysql --enable-ipv6 --with-net-snmp --with-libcurl --with-libxml2 --with-openssl
異なるZabbixコンポーネントを、異なる暗号ライブラリでコンパイルすることもできます(例えば、サーバーをOpenSSL、エージェントをGnuTLSでコンパイルするなど)。
事前共有鍵(PSK)を使用する予定がある場合は、PSKを使用するZabbixコンポーネントでGnuTLSまたはOpenSSL 1.1.0(またはそれ以降)のライブラリを使用することを検討してください。GnuTLSおよびOpenSSL 1.1.0のライブラリは、Perfect Forward Secrecyに対応したPSK暗号スイートをサポートしています。 OpenSSLライブラリの古いバージョン(1.0.1、1.0.2c)もPSKをサポートしていますが、使用可能なPSK暗号スイートはPerfect Forward Secrecyを提供しません。
接続の暗号化管理
Zabbix の接続では、次の暗号化方式を使用できます。
- 暗号化なし(デフォルト)
- RSA 証明書ベースの暗号化
- PSK ベースの暗号化
Zabbix コンポーネント間の暗号化を指定するために使用される重要なパラメータは 2 つあります。
- TLSConnect - 送信接続で使用する暗号化方式を指定します(暗号化なし、PSK、または証明書)
- TLSAccept - 受信接続で許可する接続の種類を指定します(暗号化なし、PSK、または証明書)。1 つ以上の値を指定できます。
TLSConnect は、Zabbix プロキシ(アクティブモードでは、サーバーへの接続のみを指定)および Zabbix エージェント(アクティブチェック)の設定ファイルで使用されます。
Zabbix の Webインターフェースでは、TLSConnect に相当する項目は、データ収集 > ホスト > <some host> > 暗号化 タブの ホストへの接続 フィールド、および 管理 > プロキシ > <some proxy> > 暗号化 タブの プロキシへの接続 フィールドです。
設定された接続の暗号化方式に失敗した場合、他の暗号化方式は試行されません。
TLSAccept は、Zabbix プロキシ(パッシブモードでは、サーバーからの接続のみを指定)および Zabbix エージェント(パッシブチェック)の設定ファイルで使用されます。
Zabbix の Webインターフェースでは、TLSAccept に相当する項目は、データ収集 > ホスト > <some host> > 暗号化 タブの ホストからの接続 フィールド、および 管理 > プロキシ > <some proxy> > 暗号化 タブの プロキシからの接続 フィールドです。
通常、受信接続には 1 種類の暗号化方式のみを設定します。ただし、最小限のダウンタイムとロールバックの可能性を確保しながら、暗号化方式を変更したい場合があります。たとえば、暗号化なしから証明書ベースの暗号化へ切り替える場合です。これを実現するには、次の手順を実行します。
- エージェントの設定ファイルで
TLSAccept=unencrypted,certを設定し、Zabbix エージェントを再起動します。 - 証明書を使用して
zabbix_getでエージェントへの接続をテストします。正常に動作する場合は、Zabbix の Webインターフェースで データ収集 > ホスト > <some host> > 暗号化 タブを開き、ホストへの接続 を 証明書 に設定して、そのエージェントの暗号化を再設定できます。 - サーバーの設定キャッシュが更新されると(そのホストがプロキシによって監視されている場合は、プロキシの設定も更新されると)、そのエージェントへの接続が暗号化されます。
- すべてが期待どおりに動作する場合は、エージェントの設定ファイルで
TLSAccept=certを設定し、Zabbix エージェントを再起動します。 これで、エージェントは証明書ベースの暗号化接続のみを受け入れるようになります。 暗号化されていない接続および PSK ベースの接続は拒否されます。
サーバーとプロキシでも同様に動作します。Zabbix の Webインターフェースでホスト設定の ホストからの接続 を「証明書」に設定すると、エージェント(アクティブチェック)および zabbix_sender(トラッパーアイテム)からの証明書ベースの暗号化接続のみが受け入れられます。
通常、受信接続と送信接続には同じ暗号化方式を使用するか、どちらも暗号化しないように設定します。ただし、技術的には非対称に設定することも可能です。たとえば、受信接続には証明書ベースの暗号化を使用し、送信接続には PSK ベースの暗号化を使用できます。
各ホストの暗号化設定は、Zabbix の Webインターフェースの データ収集 > ホスト にある エージェントの暗号化 列に表示されます。 例:
| 例 | ホストへの接続 | ホストから許可される接続 | ホストから拒否される接続 |
|---|---|---|---|
![]() |
暗号化なし | 暗号化なし | 暗号化された接続、証明書ベースおよび PSK ベースの暗号化接続 |
![]() |
暗号化、証明書ベース | 暗号化、証明書ベース | 暗号化なしおよび PSK ベースの暗号化接続 |
![]() |
暗号化、PSK ベース | 暗号化、PSK ベース | 暗号化なしおよび証明書ベースの暗号化接続 |
![]() |
暗号化、PSK ベース | 暗号化なしおよび PSK ベースの暗号化接続 | 証明書ベースの暗号化接続 |
![]() |
暗号化、証明書ベース | 暗号化なし、PSK または証明書ベースの暗号化接続 | - |
接続はデフォルトでは暗号化されません。各ホストおよびプロキシに対して、個別に暗号化を設定する必要があります。
zabbix_get と zabbix_sender の暗号化対応
暗号化を使用した場合の使い方については、zabbix_get と zabbix_sender の man ページを参照してください。
暗号スイート
暗号スイートは、デフォルトでは Zabbix の起動時に内部で設定されます。
また、GnuTLS と OpenSSL ではユーザーが設定した暗号スイートもサポートされています。ユーザーは 設定 により、セキュリティポリシーに従って暗号スイートを構成できます。この機能の使用は任意です(組み込みの デフォルト暗号スイートは引き続き動作します)。
デフォルト設定でコンパイルされた暗号ライブラリでは、Zabbix の組み込みルールにより通常、次の暗号スイートになります(優先度の高い順から低い順):
| Library | Certificate ciphersuites | PSK ciphersuites |
|---|---|---|
| GnuTLS 3.1.18 | TLS_ECDHE_RSA_AES_128_GCM_SHA256 TLS_ECDHE_RSA_AES_128_CBC_SHA256 TLS_ECDHE_RSA_AES_128_CBC_SHA1 TLS_RSA_AES_128_GCM_SHA256 TLS_RSA_AES_128_CBC_SHA256 TLS_RSA_AES_128_CBC_SHA1 |
TLS_ECDHE_PSK_AES_128_CBC_SHA256 TLS_ECDHE_PSK_AES_128_CBC_SHA1 TLS_PSK_AES_128_GCM_SHA256 TLS_PSK_AES_128_CBC_SHA256 TLS_PSK_AES_128_CBC_SHA1 |
| OpenSSL 1.0.2c | ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-RSA-AES128-SHA AES128-GCM-SHA256 AES128-SHA256 AES128-SHA |
PSK-AES128-CBC-SHA |
| OpenSSL 1.1.0 | 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.1.1d | 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 |
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 |
ユーザー設定の ciphersuite
組み込みの ciphersuite 選択基準は、ユーザー設定の ciphersuite によって上書きできます。
ユーザー設定の ciphersuite は、TLS ciphersuite、そのセキュリティ、設定ミスの影響を理解しており、TLS のトラブルシューティングに慣れている上級ユーザー向けの機能です。
組み込みの ciphersuite 選択基準は、次のパラメーターを使用して上書きできます。
| 上書き範囲 | パラメーター | 値 | 説明 |
|---|---|---|---|
| 証明書の ciphersuite 選択 | TLSCipherCert13 | TLS 1.3 プロトコル向けの有効な OpenSSL 1.1.1 cipher strings(その値は OpenSSL 関数 SSL_CTX_set_ciphersuites() に渡されます)。 |
TLS 1.3 の証明書ベースの ciphersuite 選択基準 OpenSSL 1.1.1 以降のみ。 |
| TLSCipherCert | TLS 1.2 向けの有効な OpenSSL cipher strings または有効な GnuTLS priority strings。その値は、それぞれ SSL_CTX_set_cipher_list() または gnutls_priority_init() 関数に渡されます。 |
TLS 1.2/1.3(GnuTLS)、TLS 1.2(OpenSSL)の証明書ベースの ciphersuite 選択基準 | |
| PSK の ciphersuite 選択 | TLSCipherPSK13 | TLS 1.3 プロトコル向けの有効な OpenSSL 1.1.1 cipher strings(その値は OpenSSL 関数 SSL_CTX_set_ciphersuites() に渡されます)。 |
TLS 1.3 の PSK ベースの ciphersuite 選択基準 OpenSSL 1.1.1 以降のみ。 |
| TLSCipherPSK | TLS 1.2 向けの有効な OpenSSL cipher strings または有効な GnuTLS priority strings。その値は、それぞれ SSL_CTX_set_cipher_list() または gnutls_priority_init() 関数に渡されます。 |
TLS 1.2/1.3(GnuTLS)、TLS 1.2(OpenSSL)の PSK ベースの ciphersuite 選択基準 | |
| 証明書と PSK の統合 ciphersuite リスト | TLSCipherAll13 | TLS 1.3 プロトコル向けの有効な OpenSSL 1.1.1 cipher strings(その値は OpenSSL 関数 SSL_CTX_set_ciphersuites() に渡されます)。 |
TLS 1.3 の ciphersuite 選択基準 OpenSSL 1.1.1 以降のみ。 |
| TLSCipherAll | TLS 1.2 向けの有効な OpenSSL cipher strings または有効な GnuTLS priority strings。その値は、それぞれ SSL_CTX_set_cipher_list() または gnutls_priority_init() 関数に渡されます。 |
TLS 1.2/1.3(GnuTLS)、TLS 1.2(OpenSSL)の ciphersuite 選択基準 |
zabbix_get および zabbix_sender ユーティリティで ciphersuite 選択を上書きするには、コマンドラインパラメーターを使用します。
--tls-cipher13--tls-cipher
新しいパラメーターは任意です。パラメーターが指定されていない場合は、内部のデフォルト値が使用されます。パラメーターが定義されている場合は、空にできません。
crypto ライブラリで TLSCipher* 値の設定に失敗した場合、サーバー、プロキシ、またはエージェントは起動せず、エラーがログに記録されます。
各パラメーターがいつ適用されるかを理解することが重要です。
外向き接続
最も単純なケースは外向き接続です。
- 証明書を使用する外向き接続の場合 - TLSCipherCert13 または TLSCipherCert を使用します
- PSK を使用する外向き接続の場合 - TLSCipherPSK13 または TLSCipherPSK を使用します
- zabbix_get および zabbix_sender ユーティリティの場合、コマンドライン
パラメータ
--tls-cipher13または--tls-cipherを使用できます (暗号化は--tls-connectパラメータで明確に指定されます)
受信接続
受信接続では、ルールがコンポーネントと設定ごとに異なるため、少し複雑になります。
Zabbix エージェント の場合:
| 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 サーバー および プロキシ の場合:
| Connection setup | Cipher configuration |
|---|---|
| Outgoing connections using PSK | TLSCipherPSK, TLSCipherPSK13 |
| Incoming connections using certificates | TLSCipherAll, TLSCipherAll13 |
| Incoming connections using PSK if server has no certificate | TLSCipherPSK, TLSCipherPSK13 |
| Incoming connections using PSK if server has certificate | TLSCipherAll, TLSCipherAll13 |
上の2つの表から、次のようなパターンが見て取れます。
- TLSCipherAll と TLSCipherAll13 は、証明書ベース および PSK ベースの暗号スイートを組み合わせた一覧を使用する場合にのみ指定できます。これが該当するのは次の2つの場合です。証明書が設定されたサーバー(プロキシ)(PSK 暗号スイートは、暗号ライブラリが PSK をサポートしている場合、プロキシでは常に設定されます)、および証明書ベースと PSK ベースの両方の受信接続を受け入れるように設定されたエージェントです。
- その他の場合は、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 暗号スイートのみを許可するための暗号スイート文字列のテスト
どの暗号スイートが選択されたかを確認するには、設定ファイルで
DebugLevel=4 を指定するか、zabbix_sender に -vv オプションを
使用します。
目的の暗号スイートを得るには、TLSCipher* パラメーターをいくつか
試行する必要がある場合があります。TLSCipher* パラメーターを調整する
ためだけに Zabbix サーバー、プロキシ、またはエージェントを何度も再起動するのは
不便です。より便利な方法としては、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 証明書、エージェント証明書、および 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 エージェントとの相互運用性を確保するために選ばれています。
より新しいシステムでは、PFS(Perfect Forward Secrecy)を備えた
暗号スイートのみを許可するなど、セキュリティを強化できます。
TLSCipher* パラメーターを使用して、PFS を備えた暗号スイートのみを
許可してみましょう。
PSK を使用する場合、この結果は OpenSSL 1.0.1 および 1.0.2 を使用する システムとは相互運用できません。証明書ベースの暗号化は動作するはずです。
test.conf 設定ファイルに次の 2 行を追加します。
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. TLSCipherAll と TLSCipherAll13 は zabbix_sender ではテストできません。 これらは、上の例で表示される「certificate and PSK ciphersuites」の値には 影響しません。TLSCipherAll と TLSCipherAll13 を調整するには、エージェント、 プロキシ、またはサーバーで試行する必要があります。
したがって、PFS 暗号スイートのみを許可するには、最大 3 つの パラメーターを追加する必要がある場合があります。
TLSCipherCert=EECDH+aRSA+AES128
TLSCipherPSK=kECDHEPSK+AES128
TLSCipherAll=EECDH+aRSA+AES128:kECDHEPSK+AES128
これらを、証明書が設定されており、かつエージェントにも PSK がある場合は、
zabbix_agentd.conf、zabbix_proxy.conf、zabbix_server.conf に追加します。
Zabbix 環境で PSK ベースの暗号化のみを使用し、証明書を使用しない場合は、 次の 1 つだけで十分です。
TLSCipherPSK=kECDHEPSK+AES128
仕組みが理解できたら、openssl コマンドを使って、Zabbix の外でも
暗号スイートの選択をテストできます。3 つすべての 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
より詳細な出力が必要な場合は、openssl ciphers に -V オプションを付ける
方法もあります。
$ 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
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
証明書関連の暗号スイートのみが使用されますが、TLSCipherPSK* パラメータも定義されています。これは、より広い相互運用性のために安全性の低い暗号を含むデフォルト値を避けるためです。PSK の暗号スイートは、サーバー/プロキシ では完全には無効化できません。
また、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
暗号化の問題のトラブルシューティング
一般的な推奨事項:
- 問題のケースで、どのコンポーネントが TLS クライアントとして動作し、どのコンポーネントが TLS サーバーとして動作するかを把握することから始めてください。
Zabbix サーバー、プロキシ、エージェントは、相互のやり取りに応じて、いずれも TLS サーバーおよびクライアントとして動作できます。
たとえば、Zabbix サーバーがパッシブチェックのためにエージェントへ接続する場合、TLS クライアントとして動作します。エージェントは TLS サーバーの役割を担います。
Zabbix エージェントがプロキシからアクティブチェックの一覧を要求する場合、TLS クライアントとして動作します。プロキシは TLS サーバーの役割を担います。
zabbix_getおよびzabbix_senderユーティリティは、常に TLS クライアントとして動作します。 - Zabbix は相互認証を使用します。
それぞれの側が相手を検証し、接続を拒否する場合があります。
たとえば、Zabbix サーバーがエージェントへ接続する際、エージェントの証明書が無効であれば、接続を直ちに閉じることがあります。逆に、Zabbix エージェントがサーバーからの接続を受け入れる場合でも、サーバーがエージェントから信頼されていなければ接続を閉じることがあります。 - TLS クライアント側と TLS サーバー側の両方でログファイルを確認してください。
接続を拒否した側には、拒否した正確な理由が記録されている場合があります。もう一方の側には、より一般的なエラー(例: "Connection closed by peer", "connection was non-properly terminated")が表示されることがよくあります。 - 暗号化の設定ミスにより、実際の原因をまったく示さない紛らわしいエラーメッセージが出ることがあります。
以下の節では、トラブルシューティングに役立つ可能性のあるメッセージと原因の候補を、網羅的ではありませんがまとめています。
なお、異なる暗号ライブラリ(OpenSSL、GnuTLS)は、同じ問題状況でも異なるエラーメッセージを出すことがよくあります。
また、エラーメッセージは、両側で使用されている暗号ライブラリの組み合わせによっても変わることがあります。
接続タイプまたは権限の問題のトラブルシューティング
サーバーはPSKでエージェントに接続するよう設定されていますが、エージェントは暗号化されていない接続のみを受け入れます
サーバーまたはプロキシのログで(GnuTLS 3.3.16 の場合)
エージェントからの値の取得に失敗しました: zbx_tls_connect(): gnutls_handshake() failed: \
-110 TLS接続が正しく終了されませんでした。
サーバーまたはプロキシのログで(OpenSSL 1.0.2c の場合)
エージェントからの値の取得に失敗しました: TCP接続は成功しましたが、[[127.0.0.1]:10050] へのTLSを確立できません: \
相手側によって接続が閉じられました。許可された接続タイプとアクセス権を確認してください
一方が証明書で接続し、もう一方がPSKのみを受け入れる、またはその逆の場合
任意のログ(GnuTLS 使用時):
failed to accept an incoming connection: from 127.0.0.1: zbx_tls_accept(): gnutls_handshake() failed:\
-21 Could not negotiate a supported cipher suite.
任意のログ(OpenSSL 1.0.2c 使用時):
failed to accept an incoming connection: from 127.0.0.1: TLS handshake returned error code 1:\
file .\ssl\s3_srvr.c line 1411: error:1408A0C1:SSL routines:ssl3_get_client_hello:no shared cipher:\
TLS write fatal alert "handshake failure"
TLSサポート付きでコンパイルされた Zabbix sender を、TLS非対応でコンパイルされた Zabbix サーバー/プロキシにデータ送信しようとしています
接続側のログ:
Linux:
...In zbx_tls_init_child()
...OpenSSL library (version OpenSSL 1.1.1 11 Sep 2018) initialized
...
...In zbx_tls_connect(): psk_identity:"PSK test sender"
...End of zbx_tls_connect():FAIL error:'connection closed by peer'
...send value error: TCP successful, cannot establish TLS to [[localhost]:10051]: connection closed by peer
Windows:
...OpenSSL library (version OpenSSL 1.1.1a 20 Nov 2018) initialized
...
...In zbx_tls_connect(): psk_identity:"PSK test sender"
...zbx_psk_client_cb() requested PSK identity "PSK test sender"
...End of zbx_tls_connect():FAIL error:'SSL_connect() I/O error: [0x00000000] The operation completed successfully.'
...send value error: TCP successful, cannot establish TLS to [[192.168.1.2]:10051]: SSL_connect() I/O error: [0x00000000] The operation completed successfully.
受信側のログ:
...failed to accept an incoming connection: from 127.0.0.1: TLS のサポートはコンパイルされていません
一方はPSKで接続するが、もう一方はLibreSSLを使用しているか、暗号化サポートなしでコンパイルされている
LibreSSLはPSKをサポートしていません。
接続側のログ:
...TCP successful, cannot establish TLS to [[192.168.1.2]:10050]: SSL_connect() I/O error: [0] Success
受信側のログ:
...failed to accept an incoming connection: from 192.168.1.2: support for PSK was not compiled in
Zabbix Webインターフェース:
Get value from エージェント failed: TCP successful, cannot establish TLS to [[192.168.1.2]:10050]: SSL_connect() I/O error: [0] Success
一方は PSK で接続するが、もう一方は PSK サポートを無効にした OpenSSL を使用している
接続側のログ:
...TCP は成功しましたが、[[192.168.1.2]:10050] への TLS を確立できません: SSL_connect() が結果コード SSL_ERROR_SSL を設定しました: file ../ssl/record/rec_layer_s3.c line 1536: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure: SSL alert number 40: TLS read fatal alert "handshake failure"
受信側のログ:
...受信した接続を許可できませんでした: from 192.168.1.2: TLS handshake が結果コード 1 を設定しました: file ssl/statem/statem_srvr.c line 1422: error:1417A0C1:SSL routines:tls_post_process_client_hello:no shared cipher: TLS write fatal alert "handshake failure"




