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ę.

Kompilowanie Zabbix z obsługą szyfrowania

Aby obsługiwać szyfrowanie, 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 - przetestowano 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 Zabbix skompilowane z LibreSSL nie będą mogły używać PSK, można używać tylko certyfikatów.

Więcej informacji na temat konfigurowania SSL dla frontendu Zabbix można znaleźć w tych najlepszych praktykach.

Bibliotekę wybiera się, określając odpowiednią opcję w skrypcie „configure”:

  • --with-gnutls[=DIR]
  • --with-openssl[=DIR] (używane również dla LibreSSL)

Na przykład, aby skonfigurować źródła serwera i agenta z użyciem OpenSSL, można użyć polecenia:

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

Różne komponenty Zabbix mogą być kompilowane z użyciem różnych bibliotek kryptograficznych (np. serwer z OpenSSL, a agent z GnuTLS).

Jeśli planujesz używać kluczy wstępnie współdzielonych (PSK), rozważ użycie bibliotek GnuTLS lub OpenSSL 1.1.0 (albo nowszych) w komponentach Zabbix używających PSK. Biblioteki GnuTLS i OpenSSL 1.1.0 obsługują zestawy szyfrów PSK z utajnieniem przekazywania doskonałym. Starsze wersje biblioteki OpenSSL (1.0.1, 1.0.2c) również obsługują PSK, ale dostępne zestawy szyfrów PSK nie zapewniają utajnienia przekazywania doskonałego.

Zarządzanie szyfrowaniem połączeń

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

Do określania szyfrowania między komponentami Zabbix służą dwa ważne parametry:

  • TLSConnect - określa szyfrowanie używane dla połączeń wychodzących (nieszyfrowane, PSK lub certyfikat)
  • TLSAccept - określa typy połączeń dozwolonych dla połączeń przychodzących (nieszyfrowane, PSK lub certyfikat). Można określić jedną lub więcej wartości.

TLSConnect jest używany w plikach konfiguracyjnych Zabbix proxy (w trybie aktywnym określa tylko połączenia z serwerem) oraz Zabbix agent (dla aktywnych kontroli). W frontend Zabbix odpowiednikiem TLSConnect jest pole Połączenia z hostem w sekcji Zbieranie danych > Hosty > <some host> > karta Szyfrowanie oraz pole Połączenia z proxy w sekcji Administracja > Proxy > <some proxy> > karta Szyfrowanie. Jeśli skonfigurowany typ szyfrowania połączenia nie powiedzie się, nie zostaną podjęte próby użycia innych typów szyfrowania.

TLSAccept jest używany w plikach konfiguracyjnych Zabbix proxy (w trybie pasywnym określa tylko połączenia z serwera) oraz Zabbix agent (dla pasywnych kontroli). W frontend Zabbix odpowiednikiem TLSAccept jest pole Połączenia z hosta w sekcji Zbieranie danych > Hosty > <some host> > karta Szyfrowanie oraz pole Połączenia z proxy w sekcji Administracja > Proxy > <some proxy> > karta Szyfrowanie.

Zwykle konfiguruje się tylko jeden typ szyfrowania dla połączeń przychodzących. Można jednak chcieć zmienić typ szyfrowania, np. z nieszyfrowanego na oparte na certyfikatach, przy minimalnym przestoju i możliwości wycofania zmian. Aby to osiągnąć:

  • Ustaw TLSAccept=unencrypted,cert w pliku konfiguracyjnym agenta i uruchom ponownie Zabbix agent.
  • Przetestuj połączenie z agentem za pomocą zabbix_get, używając certyfikatu. Jeśli działa, możesz ponownie skonfigurować szyfrowanie dla tego agenta w frontend Zabbix, w sekcji Zbieranie danych > Hosty > <some host> > karta Szyfrowanie, ustawiając Połączenia z hostem na Certyfikat.
  • Po zaktualizowaniu pamięci podręcznej konfiguracji serwera (oraz zaktualizowaniu konfiguracji proxy, 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 Zabbix agent. Agent będzie teraz akceptował wyłącznie szyfrowane połączenia oparte na certyfikatach. Połączenia nieszyfrowane i oparte na PSK będą odrzucane.

W podobny sposób działa to na serwerze i proxy. Jeśli w konfiguracji hosta w frontend Zabbix opcja Połączenia z hosta jest ustawiona na „Certyfikat”, od agenta (aktywne kontrole) i zabbix_sender (pozycje typu trapper) będą akceptowane wyłącznie szyfrowane połączenia oparte na certyfikatach.

Najprawdopodobniej skonfigurujesz połączenia przychodzące i wychodzące tak, aby używały tego samego typu szyfrowania albo w ogóle nie były szyfrowane. Technicznie możliwe jest jednak skonfigurowanie ich asymetrycznie, np. szyfrowania opartego na certyfikatach dla połączeń przychodzących i opartego na PSK dla połączeń wychodzących.

Konfiguracja szyfrowania dla każdego hosta jest wyświetlana w frontend Zabbix, w sekcji Zbieranie danych > Hosty, w kolumnie Szyfrowanie agenta. Na przykład:

Przykład Połączenia z hostem Dozwolone połączenia z hosta Odrzucone połączenia z hosta
none\_none.png Nieszyfrowane Nieszyfrowane Szyfrowane, oparte na certyfikatach i PSK
cert\_cert.png Szyfrowane, oparte na certyfikatach Szyfrowane, oparte na certyfikatach Nieszyfrowane i szyfrowane, oparte na PSK
psk\_psk.png Szyfrowane, oparte na PSK Szyfrowane, oparte na PSK Nieszyfrowane i szyfrowane, oparte na certyfikatach
psk\_none\_psk.png Szyfrowane, oparte na PSK Nieszyfrowane i szyfrowane, oparte na PSK Szyfrowane, oparte na certyfikatach
cert\_all.png Szyfrowane, oparte na certyfikatach Nieszyfrowane, szyfrowane oparte na PSK lub certyfikatach -

Połączenia są domyślnie nieszyfrowane. Szyfrowanie należy skonfigurować osobno 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"