暗号化とセキュリティ

暗号化

Zabbix は、Transport Layer Security (TLS) プロトコル v.1.2 および 1.3(暗号ライブラリに依存)を使用して、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 の接続では、次の暗号化方式を使用できます。

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> > 暗号化 タブで、そのエージェントの暗号化を再設定し、ホストへの接続 を "Certificate" に設定できます。
  • サーバーの設定キャッシュが更新されると(ホストがプロキシで監視されている場合はプロキシの設定も更新されると)、そのエージェントへの接続は暗号化されます
  • すべてが期待どおりに動作する場合は、エージェントの設定ファイルで TLSAccept=cert を設定し、Zabbix エージェントを再起動します。これで、エージェントは証明書ベースの暗号化接続のみを受け入れるようになります。暗号化なしおよび PSK ベースの接続は拒否されます。

同様の仕組みはサーバーとプロキシでも動作します。Zabbix Webインターフェースのホスト設定で ホストからの接続 が "Certificate" に設定されている場合、エージェント(アクティブチェック)および zabbix_sender(トラッパーアイテム)からは、証明書ベースで暗号化された接続のみが受け入れられます。

通常は、受信接続と送信接続に同じ暗号化方式、または暗号化なしを設定します。ただし技術的には、たとえば受信接続には証明書ベースの暗号化、送信接続には PSK ベースの暗号化というように、非対称に設定することも可能です。

各ホストの暗号化設定は、Zabbix Webインターフェースの データ収集 > ホストエージェント暗号化 列に表示されます。例:

Example Connections to host Allowed connections from host Rejected connections from host
none\_none.png 暗号化なし 暗号化なし 暗号化済み、証明書ベースおよび PSK ベースの暗号化
cert\_cert.png 暗号化済み、証明書ベース 暗号化済み、証明書ベース 暗号化なしおよび PSK ベースの暗号化
psk\_psk.png 暗号化済み、PSK ベース 暗号化済み、PSK ベース 暗号化なしおよび証明書ベースの暗号化
psk\_none\_psk.png 暗号化済み、PSK ベース 暗号化なしおよび PSK ベースの暗号化 証明書ベースの暗号化
cert\_all.png 暗号化済み、証明書ベース 暗号化なし、PSK、または証明書ベースの暗号化 -

接続はデフォルトでは暗号化されていません。暗号化は各ホストおよびプロキシごとに個別に設定する必要があります。

zabbix_get と zabbix_sender の暗号化対応

暗号化を使用した場合の使い方については、zabbix_getzabbix_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.confzabbix_proxy.confzabbix_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"