Szyfrowanie i bezpieczeństwo

Szyfrowanie

Zabbix obsługuje szyfrowaną komunikację między komponentami Zabbix przy użyciu protokołu Transport Layer Security (TLS) w wersji 1.2 i 1.3 (w zależności od biblioteki kryptograficznej). Obsługiwane jest szyfrowanie oparte na certyfikatach oraz szyfrowanie oparte na kluczu współdzielonym.

Szyfrowanie można skonfigurować dla połączeń:

  • Między serwerem Zabbix, proxy Zabbix, agentem Zabbix, usługą web Zabbix, narzędziami zabbix_sender i zabbix_get
  • Do bazy danych Zabbix z frontend Zabbix i serwera/proxy
  • Między frontend Zabbix i serwerem Zabbix

Szyfrowanie jest opcjonalne i można je skonfigurować dla poszczególnych komponentów:

  • Niektóre proxy i agenty można skonfigurować tak, aby używały szyfrowania opartego na certyfikatach z serwerem, podczas gdy inne mogą używać szyfrowania opartego na kluczu współdzielonym, a jeszcze inne mogą nadal korzystać z nieszyfrowanej komunikacji (tak jak wcześniej).
  • Serwer (proxy) może używać różnych konfiguracji szyfrowania dla różnych hostów.

Programy demonów Zabbix używają jednego portu nasłuchującego dla szyfrowanych i nieszyfrowanych połączeń przychodzących. Dodanie szyfrowania nie wymaga otwierania nowych portów na zaporach sieciowych.

Ograniczenia
  • Klucze prywatne są przechowywane jako zwykły tekst w plikach czytelnych dla komponentów Zabbix podczas uruchamiania.
  • Klucze współdzielone są wprowadzane w frontend Zabbix i przechowywane w bazie danych Zabbix jako zwykły tekst.
  • Wbudowane szyfrowanie nie chroni komunikacji między serwerem WWW uruchamiającym frontend Zabbix a przeglądarką internetową użytkownika.
  • Obecnie każde szyfrowane połączenie rozpoczyna się pełnym uzgadnianiem TLS; nie są zaimplementowane buforowanie sesji ani bilety sesji.
  • Dodanie szyfrowania zwiększa czas sprawdzania pozycji i wykonywania akcji, w zależności od opóźnienia sieci:
    • Na przykład, jeśli opóźnienie pakietu wynosi 100 ms, otwarcie połączenia TCP i wysłanie nieszyfrowanego żądania zajmuje około 200 ms. Przy szyfrowaniu na ustanowienie połączenia TLS dodawane jest około 1000 ms.
    • Może być konieczne zwiększenie limitów czasu; w przeciwnym razie niektóre pozycje i akcje uruchamiające zdalne skrypty na agentach mogą działać przy nieszyfrowanych połączeniach, ale kończyć się przekroczeniem limitu czasu przy połączeniach szyfrowanych.
  • Szyfrowanie nie jest obsługiwane przez odkrywanie sieci. Sprawdzenia agenta Zabbix wykonywane przez odkrywanie sieci będą nieszyfrowane i jeśli agent Zabbix jest skonfigurowany tak, aby odrzucać nieszyfrowane połączenia, takie sprawdzenia nie powiodą się.

Kompilacja Zabbixa z obsługą szyfrowania

Aby zapewnić obsługę szyfrowania, Zabbix musi zostać skompilowany i połączony z jedną z obsługiwanych bibliotek kryptograficznych:

  • GnuTLS - od wersji 3.1.18
  • OpenSSL - wersje 1.0.1, 1.0.2, 1.1.0, 1.1.1, 3.0.x - 3.5.x
  • LibreSSL - testowane z wersjami 2.7.4, 2.8.2:
    • LibreSSL 2.6.x nie jest obsługiwany
    • LibreSSL jest obsługiwany jako zgodny zamiennik OpenSSL; nowe funkcje API tls_*() specyficzne dla LibreSSL nie są używane. Komponenty Zabbixa skompilowane z LibreSSL nie będą mogły używać PSK, można używać wyłącznie certyfikatów.

Więcej informacji o konfiguracji SSL dla frontend Zabbixa można znaleźć w tych najlepszych praktykach.

Bibliotekę wybiera się, podając odpowiednią opcję w skrypcie "configure":

  • --with-gnutls[=DIR]
  • --with-openssl[=DIR] (używane także dla LibreSSL)

Na przykład, aby skonfigurować źródła dla serwer i agent z OpenSSL, można użyć czegoś takiego:

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

Różne komponenty Zabbixa mogą być kompilowane z różnymi bibliotekami kryptograficznymi (np. serwer z OpenSSL, agent z GnuTLS).

Jeśli planujesz używać kluczy współdzielonych z wyprzedzeniem (PSK), rozważ użycie bibliotek GnuTLS lub OpenSSL 1.1.0 (lub nowszych) w komponentach Zabbixa korzystających z PSK. Biblioteki GnuTLS i OpenSSL 1.1.0 obsługują zestawy szyfrów PSK z Perfect Forward Secrecy. Starsze wersje biblioteki OpenSSL (1.0.1, 1.0.2c) również obsługują PSK, ale dostępne zestawy szyfrów PSK nie zapewniają Perfect Forward Secrecy.

Zarządzanie szyfrowaniem połączeń

Połączenia w Zabbix mogą używać:

Istnieją dwa ważne parametry używane do określania szyfrowania między komponentami Zabbix:

  • TLSConnect - określa, jakiego szyfrowania używać dla połączeń wychodzących (bez szyfrowania, PSK lub certyfikat)
  • TLSAccept - określa, jakie typy połączeń są dozwolone dla połączeń przychodzących (bez szyfrowania, PSK lub certyfikat). Można podać jedną lub więcej wartości.

TLSConnect jest używany w plikach konfiguracyjnych dla proxy Zabbix (w trybie aktywnym określa tylko połączenia z serwerem) oraz agent Zabbix (dla aktywnych kontroli). W frontend Zabbix odpowiednikiem TLSConnect jest pole Connections to host w Data collection > Hosts > <some host> > zakładce Encryption oraz pole Connections to proxy w Administration > Proxies> <some proxy> > zakładce Encryption. Jeśli skonfigurowany typ szyfrowania dla połączenia zakończy się niepowodzeniem, nie zostaną podjęte próby użycia innych typów szyfrowania.

TLSAccept jest używany w plikach konfiguracyjnych dla proxy Zabbix (w trybie pasywnym określa tylko połączenia z serwera) oraz agent Zabbix (dla pasywnych kontroli). W frontend Zabbix odpowiednikiem TLSAccept jest pole Connections from host w Data collection > Hosts > <some host> > zakładce Encryption oraz pole Connections from proxy w Administration > Proxies > <some proxy> > Encryption.

Zwykle konfigurujesz tylko jeden typ szyfrowania dla połączeń przychodzących. Możesz jednak chcieć przełączyć typ szyfrowania, np. z braku szyfrowania na szyfrowanie oparte na certyfikacie, przy minimalnym czasie przestoju i z możliwością wycofania zmian. Aby to osiągnąć:

  • Ustaw TLSAccept=unencrypted,cert w pliku konfiguracyjnym agenta i uruchom ponownie agent Zabbix
  • Przetestuj połączenie z zabbix_get do agenta przy użyciu certyfikatu. Jeśli działa, możesz ponownie skonfigurować szyfrowanie dla tego agenta w frontend Zabbix w zakładce Data collection > Hosts > <some host> > Encryption, ustawiając Connections to host na "Certificate".
  • Gdy pamięć podręczna konfiguracji serwera zostanie zaktualizowana (a konfiguracja proxy zostanie zaktualizowana, jeśli host jest monitorowany przez proxy), połączenia z tym agentem będą szyfrowane
  • Jeśli wszystko działa zgodnie z oczekiwaniami, możesz ustawić TLSAccept=cert w pliku konfiguracyjnym agenta i uruchomić ponownie agent Zabbix. Od tego momentu agent będzie akceptował tylko szyfrowane połączenia oparte na certyfikacie. Połączenia bez szyfrowania oraz oparte na PSK zostaną odrzucone.

W podobny sposób działa to na serwer i proxy. Jeśli w frontend Zabbix w konfiguracji hosta pole Connections from host jest ustawione na "Certificate", to tylko szyfrowane połączenia oparte na certyfikacie będą akceptowane od agenta (aktywnych kontroli) oraz zabbix_sender (pozycje trapper).

Najprawdopodobniej skonfigurujesz połączenia przychodzące i wychodzące tak, aby używały tego samego typu szyfrowania albo w ogóle nie używały szyfrowania. Technicznie możliwa jest jednak konfiguracja asymetryczna, np. szyfrowanie oparte na certyfikacie dla połączeń przychodzących i oparte na PSK dla połączeń wychodzących.

Konfiguracja szyfrowania dla każdego hosta jest wyświetlana w frontend Zabbix w Data collection > Hosts w kolumnie Agent encryption. Na przykład:

Example Connections to host Allowed connections from host Rejected connections from host
none\_none.png Bez szyfrowania Bez szyfrowania Szyfrowane, oparte na certyfikacie i szyfrowane oparte na PSK
cert\_cert.png Szyfrowane, oparte na certyfikacie Szyfrowane, oparte na certyfikacie Bez szyfrowania oraz szyfrowane oparte na PSK
psk\_psk.png Szyfrowane, oparte na PSK Szyfrowane, oparte na PSK Bez szyfrowania oraz szyfrowane oparte na certyfikacie
psk\_none\_psk.png Szyfrowane, oparte na PSK Bez szyfrowania oraz szyfrowane oparte na PSK Szyfrowane, oparte na certyfikacie
cert\_all.png Szyfrowane, oparte na certyfikacie Bez szyfrowania, PSK lub szyfrowane oparte na certyfikacie -

Połączenia są domyślnie bez szyfrowania. Szyfrowanie musi być skonfigurowane indywidualnie dla każdego hosta i proxy.

zabbix_get i zabbix_sender z szyfrowaniem

Zobacz strony podręcznika zabbix_get i zabbix_sender dotyczące używania ich z szyfrowaniem.

Zestawy szyfrów

Zestawy szyfrów są domyślnie konfigurowane wewnętrznie podczas uruchamiania Zabbixa.

Obsługiwane są również zestawy szyfrów skonfigurowane przez użytkownika dla GnuTLS i OpenSSL. Użytkownicy mogą skonfigurować zestawy szyfrów zgodnie z własnymi zasadami bezpieczeństwa. Korzystanie z tej funkcji jest opcjonalne (wbudowane domyślne zestawy szyfrów nadal działają).

W przypadku bibliotek kryptograficznych skompilowanych z ustawieniami domyślnymi wbudowane reguły Zabbixa zwykle dają następujące zestawy szyfrów (w kolejności od wyższego do niższego priorytetu):

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

Ciphersuites zdefiniowane przez użytkownika

Wbudowane kryteria wyboru ciphersuite można zastąpić za pomocą ciphersuite zdefiniowanych przez użytkownika.

Ciphersuite zdefiniowane przez użytkownika to funkcja przeznaczona dla zaawansowanych użytkowników, którzy rozumieją ciphersuite TLS, ich bezpieczeństwo i konsekwencje błędów, oraz którzy czują się swobodnie podczas rozwiązywania problemów z TLS.

Wbudowane kryteria wyboru ciphersuite można zastąpić przy użyciu następujących parametrów:

Zakres nadpisania Parametr Wartość Opis
Wybór ciphersuite dla certyfikatów TLSCipherCert13 Prawidłowe ciągi OpenSSL 1.1.1 cipher strings dla protokołu TLS 1.3 (ich wartości są przekazywane do funkcji OpenSSL SSL_CTX_set_ciphersuites()). Kryteria wyboru ciphersuite oparte na certyfikatach dla TLS 1.3

Tylko OpenSSL 1.1.1 lub nowszy.
TLSCipherCert Prawidłowe ciągi OpenSSL cipher strings dla TLS 1.2 lub prawidłowe ciągi priorytetów GnuTLS priority strings. Ich wartości są przekazywane odpowiednio do funkcji SSL_CTX_set_cipher_list() lub gnutls_priority_init(). Kryteria wyboru ciphersuite oparte na certyfikatach dla TLS 1.2/1.3 (GnuTLS), TLS 1.2 (OpenSSL)
Wybór ciphersuite dla PSK TLSCipherPSK13 Prawidłowe ciągi OpenSSL 1.1.1 cipher strings dla protokołu TLS 1.3 (ich wartości są przekazywane do funkcji OpenSSL SSL_CTX_set_ciphersuites()). Kryteria wyboru ciphersuite oparte na PSK dla TLS 1.3

Tylko OpenSSL 1.1.1 lub nowszy.
TLSCipherPSK Prawidłowe ciągi OpenSSL cipher strings dla TLS 1.2 lub prawidłowe ciągi priorytetów GnuTLS priority strings. Ich wartości są przekazywane odpowiednio do funkcji SSL_CTX_set_cipher_list() lub gnutls_priority_init(). Kryteria wyboru ciphersuite oparte na PSK dla TLS 1.2/1.3 (GnuTLS), TLS 1.2 (OpenSSL)
Łączna lista ciphersuite dla certyfikatu i PSK TLSCipherAll13 Prawidłowe ciągi OpenSSL 1.1.1 cipher strings dla protokołu TLS 1.3 (ich wartości są przekazywane do funkcji OpenSSL SSL_CTX_set_ciphersuites()). Kryteria wyboru ciphersuite dla TLS 1.3

Tylko OpenSSL 1.1.1 lub nowszy.
TLSCipherAll Prawidłowe ciągi OpenSSL cipher strings dla TLS 1.2 lub prawidłowe ciągi priorytetów GnuTLS priority strings. Ich wartości są przekazywane odpowiednio do funkcji SSL_CTX_set_cipher_list() lub gnutls_priority_init(). Kryteria wyboru ciphersuite dla TLS 1.2/1.3 (GnuTLS), TLS 1.2 (OpenSSL)

Aby nadpisać wybór ciphersuite w narzędziach zabbix_get i zabbix_sender, użyj parametrów wiersza poleceń:

  • --tls-cipher13
  • --tls-cipher

Nowe parametry są opcjonalne. Jeśli parametr nie zostanie określony, używana jest wewnętrzna wartość domyślna. Jeśli parametr jest zdefiniowany, nie może być pusty.

Jeśli ustawienie wartości TLSCipher* w bibliotece kryptograficznej zakończy się niepowodzeniem, to serwer, proxy lub agent nie uruchomi się i zostanie zapisany błąd.

Ważne jest, aby zrozumieć, kiedy każdy z parametrów ma zastosowanie.

Połączenia wychodzące

Najprostszym przypadkiem są połączenia wychodzące:

  • W przypadku połączeń wychodzących z certyfikatem - użyj TLSCipherCert13 lub TLSCipherCert
  • W przypadku połączeń wychodzących z PSK - użyj TLSCipherPSK13 lub TLSCipherPSK
  • W przypadku narzędzi zabbix_get i zabbix_sender można użyć parametrów wiersza poleceń --tls-cipher13 lub --tls-cipher (szyfrowanie jest jednoznacznie określone za pomocą parametru --tls-connect)
Połączenia przychodzące

W przypadku połączeń przychodzących jest to nieco bardziej skomplikowane, ponieważ reguły są specyficzne dla komponentów i konfiguracji.

Dla Zabbix agent:

Konfiguracja połączenia agenta Konfiguracja szyfrów
TLSConnect=cert TLSCipherCert, TLSCipherCert13
TLSConnect=psk TLSCipherPSK, TLSCipherPSK13
TLSAccept=cert TLSCipherCert, TLSCipherCert13
TLSAccept=psk TLSCipherPSK, TLSCipherPSK13
TLSAccept=cert,psk TLSCipherAll, TLSCipherAll13

Dla Zabbix serwer i proxy:

Konfiguracja połączenia Konfiguracja szyfrów
Połączenia wychodzące z użyciem PSK TLSCipherPSK, TLSCipherPSK13
Połączenia przychodzące z użyciem certyfikatów TLSCipherAll, TLSCipherAll13
Połączenia przychodzące z użyciem PSK, jeśli serwer nie ma certyfikatu TLSCipherPSK, TLSCipherPSK13
Połączenia przychodzące z użyciem PSK, jeśli serwer ma certyfikat TLSCipherAll, TLSCipherAll13

W dwóch powyższych tabelach można zauważyć pewien wzorzec:

  • TLSCipherAll i TLSCipherAll13 można określić tylko wtedy, gdy używana jest łączna lista zestawów szyfrów opartych na certyfikatach i PSK. Występują dwa przypadki, gdy ma to miejsce: serwer (proxy) z skonfigurowanym certyfikatem (zestawy szyfrów PSK są zawsze skonfigurowane na serwerze, proxy jeśli biblioteka kryptograficzna obsługuje PSK), agent skonfigurowany do akceptowania zarówno przychodzących połączeń opartych na certyfikatach, jak i na PSK
  • w pozostałych przypadkach wystarczające są TLSCipherCert* i/lub TLSCipherPSK*

Poniższe tabele pokazują wbudowane domyślne wartości TLSCipher*. Mogą one stanowić dobry punkt wyjścia do własnych niestandardowych wartości.

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 Domyślne wartości są inne dla starszych wersji OpenSSL (1.0.1, 1.0.2, 1.1.0), dla LibreSSL oraz jeśli OpenSSL został skompilowany bez obsługi PSK.

Przykłady zestawów szyfrów skonfigurowanych przez użytkownika

Poniżej znajdują się następujące przykłady zestawów szyfrów skonfigurowanych przez użytkownika:

Testowanie ciągów szyfrów i zezwalanie wyłącznie na zestawy szyfrów PFS

Aby sprawdzić, które zestawy szyfrów zostały wybrane, należy ustawić DebugLevel=4 w pliku konfiguracyjnym albo użyć opcji -vv dla zabbix_sender.

Może być konieczne pewne eksperymentowanie z parametrami TLSCipher*, zanim uzyskasz pożądane zestawy szyfrów. Niewygodne jest wielokrotne ponowne uruchamianie serwera Zabbix, proxy lub agenta tylko po to, aby dostrajać parametry TLSCipher*. Wygodniejszym rozwiązaniem jest użycie zabbix_sender lub polecenia openssl. Pokażmy oba.

1. Użycie zabbix_sender.

Utwórzmy testowy plik konfiguracyjny, na przykład /home/zabbix/test.conf, o składni pliku 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

Do tego przykładu potrzebujesz poprawnych certyfikatów CA i agenta oraz PSK. Dostosuj ścieżki i nazwy plików certyfikatów oraz PSK do swojego środowiska.

Jeśli nie używasz certyfikatów, a tylko PSK, możesz przygotować prostszy plik testowy:

  Hostname=nonexisting
  ServerActive=nonexisting

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

Wybrane zestawy szyfrów można zobaczyć, uruchamiając zabbix_sender (przykład skompilowany z 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

Tutaj widać domyślnie wybrane zestawy szyfrów. Te wartości domyślne zostały dobrane tak, aby zapewnić współdziałanie z agentami Zabbix uruchomionymi na systemach ze starszymi wersjami OpenSSL (od 1.0.1).

Na nowszych systemach można zwiększyć poziom bezpieczeństwa, zezwalając tylko na kilka zestawów szyfrów, np. wyłącznie na zestawy szyfrów z PFS (Perfect Forward Secrecy). Spróbujmy zezwolić tylko na zestawy szyfrów z PFS za pomocą parametrów TLSCipher*.

Wynik nie będzie zgodny z systemami używającymi OpenSSL 1.0.1 i 1.0.2, jeśli używany jest PSK. Szyfrowanie oparte na certyfikatach powinno działać.

Dodaj dwie linie do pliku konfiguracyjnego test.conf:

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

i przetestuj ponownie:

  $ 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        

Listy „certificate ciphersuites” i „PSK ciphersuites” uległy zmianie

  • są krótsze niż wcześniej i zawierają tylko zestawy szyfrów TLS 1.3 oraz oczekiwane zestawy szyfrów TLS 1.2 ECDHE-*.

2. Parametrów TLSCipherAll i TLSCipherAll13 nie można przetestować za pomocą zabbix_sender; nie wpływają one na wartość „certificate and PSK ciphersuites” pokazaną w powyższym przykładzie. Aby dostroić TLSCipherAll i TLSCipherAll13, trzeba eksperymentować z agentem, proxy lub serwerem.

Aby zezwolić wyłącznie na zestawy szyfrów PFS, może być konieczne dodanie maksymalnie trzech parametrów

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

do plików zabbix_agentd.conf, zabbix_proxy.conf i zabbix_server.conf, jeśli każdy z nich ma skonfigurowany certyfikat, a agent ma również PSK.

Jeśli Twoje środowisko Zabbix używa wyłącznie szyfrowania opartego na PSK i nie używa certyfikatów, wystarczy tylko jeden parametr:

  TLSCipherPSK=kECDHEPSK+AES128

Teraz, gdy już wiesz, jak to działa, możesz testować wybór zestawów szyfrów nawet poza Zabbix, za pomocą polecenia openssl. Przetestujmy wszystkie trzy wartości parametrów 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

Możesz też użyć openssl ciphers z opcją -V, aby uzyskać bardziej szczegółowy wynik:

  $ 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

Podobnie możesz testować ciągi priorytetów dla 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
Przełączanie z AES128 na AES256

Zabbix używa AES128 jako wbudowanego domyślnego algorytmu dla danych. Załóżmy, że używasz certyfikatów i chcesz przełączyć się na AES256 w OpenSSL 1.1.1.

Można to osiągnąć, dodając odpowiednie parametry w pliku 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

Chociaż będą używane wyłącznie zestawy szyfrów związane z certyfikatami, parametry TLSCipherPSK* są również zdefiniowane, aby uniknąć ich wartości domyślnych, które obejmują mniej bezpieczne szyfry dla szerszej interoperacyjności. Zestawów szyfrów PSK nie można całkowicie wyłączyć na serwerze/proxy.

A w pliku 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

Rozwiązywanie problemów z szyfrowaniem

Ogólne zalecenia:

  • Zacznij od ustalenia, który komponent działa jako klient TLS, a który jako serwer TLS w danym przypadku problemowym.
    serwer Zabbix, proxy i agenty, w zależności od interakcji między nimi, mogą działać zarówno jako serwery TLS, jak i klienci TLS.
    Na przykład serwer Zabbix łączący się z agentem w celu wykonania pasywnej kontroli działa jako klient TLS. Agent pełni rolę serwera TLS.
    Agent Zabbix, pobierający listę aktywnych kontroli z proxy, działa jako klient TLS. Proxy pełni rolę serwera TLS.
    Narzędzia zabbix_get i zabbix_sender zawsze działają jako klienci TLS.
  • Zabbix używa uwierzytelniania wzajemnego.
    Każda ze stron weryfikuje swój odpowiednik i może odrzucić połączenie.
    Na przykład serwer Zabbix łączący się z agentem może natychmiast zamknąć połączenie, jeśli certyfikat agenta jest nieprawidłowy. I odwrotnie - agent Zabbix przyjmujący połączenie z serwera może zamknąć połączenie, jeśli serwer nie jest zaufany przez agenta.
  • Sprawdź pliki dziennika po obu stronach - po stronie klienta TLS i serwera TLS.
    Strona, która odrzuca połączenie, może zapisać dokładny powód odrzucenia. Druga strona często zgłasza raczej ogólny błąd (np. "Connection closed by peer", "connection was non-properly terminated").
  • Czasami nieprawidłowo skonfigurowane szyfrowanie skutkuje mylącymi komunikatami o błędach, które w żaden sposób nie wskazują rzeczywistej przyczyny.
    W poniższych podsekcjach staramy się przedstawić (daleko niepełną) listę komunikatów i możliwych przyczyn, które mogą pomóc w rozwiązywaniu problemów.
    Należy pamiętać, że różne zestawy narzędzi kryptograficznych (OpenSSL, GnuTLS) często generują różne komunikaty o błędach w tych samych sytuacjach problemowych.
    Czasami komunikaty o błędach zależą nawet od konkretnej kombinacji zestawów narzędzi kryptograficznych po obu stronach.

Rozwiązywanie problemów z typem połączenia lub uprawnieniami

Serwer jest skonfigurowany do łączenia się z agentem przy użyciu PSK, ale agent akceptuje tylko nieszyfrowane połączenia

W logu serwera lub proxy (z GnuTLS 3.3.16)

Pobranie wartości z agenta nie powiodło się: zbx_tls_connect(): gnutls_handshake() failed: \
    -110 Połączenie TLS zostało nieprawidłowo zakończone.

W logu serwera lub proxy (z OpenSSL 1.0.2c)

Pobranie wartości z agenta nie powiodło się: Połączenie TCP zostało nawiązane pomyślnie, nie można ustanowić TLS z [[127.0.0.1]:10050]: \
    Połączenie zamknięte przez drugą stronę. Sprawdź dozwolone typy połączeń i prawa dostępu
Jedna strona łączy się z certyfikatem, ale druga strona akceptuje tylko PSK lub odwrotnie

W dowolnym logu (z 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.

W dowolnym logu (z 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"

Próba użycia Zabbix sender skompilowanego z obsługą TLS do wysłania danych do serwera/proxy Zabbix skompilowanego bez obsługi TLS

W logu po stronie łączącej:

Linux:

...W zbx_tls_init_child()
...Biblioteka OpenSSL (wersja OpenSSL 1.1.1  11 Sep 2018) zainicjalizowana
...
...W zbx_tls_connect(): psk_identity:"PSK test sender"
...Koniec zbx_tls_connect():FAIL błąd:'połączenie zamknięte przez drugą stronę'
...błąd wysyłania wartości: TCP zakończone powodzeniem, nie można ustanowić TLS do [[localhost]:10051]: połączenie zamknięte przez drugą stronę

Windows:

...Biblioteka OpenSSL (wersja OpenSSL 1.1.1a  20 Nov 2018) zainicjalizowana
...
...W zbx_tls_connect(): psk_identity:"PSK test sender"
...zbx_psk_client_cb() zażądał tożsamości PSK "PSK test sender"
...Koniec zbx_tls_connect():FAIL błąd:'SSL_connect() błąd I/O: [0x00000000] Operacja została pomyślnie zakończona.'
...błąd wysyłania wartości: TCP zakończone powodzeniem, nie można ustanowić TLS do [[192.168.1.2]:10051]: SSL_connect() błąd I/O: [0x00000000] Operacja została pomyślnie zakończona.
W dzienniku po stronie odbierającej:
...nie udało się zaakceptować połączenia przychodzącego: z 127.0.0.1: obsługa TLS nie została skompilowana

Jedna strona łączy się z PSK, ale druga strona używa LibreSSL lub została skompilowana bez obsługi szyfrowania

LibreSSL nie obsługuje PSK.

W logu strony łączącej się:

...TCP successful, cannot establish TLS to [[192.168.1.2]:10050]: SSL_connect() I/O error: [0] Success

W logu strony przyjmującej połączenie:

...failed to accept an incoming connection: from 192.168.1.2: support for PSK was not compiled in

W frontend Zabbix:

Get value from agent failed: TCP successful, cannot establish TLS to [[192.168.1.2]:10050]: SSL_connect() I/O error: [0] Success

Jedna strona łączy się z PSK, ale druga strona używa OpenSSL z wyłączonym wsparciem PSK

W logu strony łączącej:

...TCP successful, cannot establish TLS to [[192.168.1.2]:10050]: SSL_connect() set result code to 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"

W logu strony przyjmującej:

...failed to accept an incoming connection: from 192.168.1.2: TLS handshake set result code to 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"