- Szyfrowanie i bezpieczeństwo
- Szyfrowanie
- Kompilowanie Zabbix z obsługą szyfrowania
- Zarządzanie szyfrowaniem połączeń
- zabbix_get i zabbix_sender z szyfrowaniem
- Zestawy szyfrów
- Ciphersuites zdefiniowane przez użytkownika
- Rozwiązywanie problemów z szyfrowaniem
- Rozwiązywanie problemów z typem połączenia lub uprawnieniami
- Próba użycia Zabbix sender skompilowanego z obsługą TLS do wysłania danych do serwera/proxy Zabbix skompilowanego bez obsługi TLS
- Jedna strona łączy się z PSK, ale druga strona używa LibreSSL lub została skompilowana bez obsługi szyfrowania
- Jedna strona łączy się z PSK, ale druga strona używa OpenSSL z wyłączonym wsparciem PSK
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ć:
- braku szyfrowania (domyślnie)
- szyfrowania opartego na certyfikatach RSA
- szyfrowania opartego na PSK
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,certw 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=certw 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 |
|---|---|---|---|
![]() |
Nieszyfrowane | Nieszyfrowane | Szyfrowane, oparte na certyfikatach i PSK |
![]() |
Szyfrowane, oparte na certyfikatach | Szyfrowane, oparte na certyfikatach | Nieszyfrowane i szyfrowane, oparte na PSK |
![]() |
Szyfrowane, oparte na PSK | Szyfrowane, oparte na PSK | Nieszyfrowane i szyfrowane, oparte na certyfikatach |
![]() |
Szyfrowane, oparte na PSK | Nieszyfrowane i szyfrowane, oparte na PSK | Szyfrowane, oparte na certyfikatach |
![]() |
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-cipher13lub--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
- Przełączanie z AES128 na AES256
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ędziazabbix_getizabbix_senderzawsze 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"




