Criptografia e segurança

Encryption

O Zabbix oferece suporte a comunicações criptografadas entre os componentes do Zabbix usando o protocolo Transport Layer Security (TLS) v.1.2 e 1.3 (dependendo da biblioteca criptográfica). Há suporte para criptografia baseada em certificado e baseada em chave pré-compartilhada.

A criptografia pode ser configurada para conexões:

  • Entre o Zabbix server, Zabbix proxy, Zabbix agent, Zabbix web service, zabbix_sender e os utilitários zabbix_get
  • Com o banco de dados do Zabbix a partir do Zabbix frontend e server/proxy
  • Entre o Zabbix frontend e o Zabbix server

A criptografia é opcional e configurável para componentes individuais:

  • Alguns proxies e agents podem ser configurados para usar criptografia baseada em certificado com o server, enquanto outros podem usar criptografia baseada em chave pré-compartilhada, e outros ainda podem continuar com comunicações sem criptografia (como antes).
  • O server (proxy) pode usar diferentes configurações de criptografia para diferentes hosts.

Os programas daemon do Zabbix usam uma única porta de escuta para conexões de entrada criptografadas e não criptografadas. Adicionar criptografia não requer a abertura de novas portas nos firewalls.

Limitações
  • As chaves privadas são armazenadas em texto simples em arquivos legíveis pelos componentes do Zabbix durante a inicialização.
  • As chaves pré-compartilhadas são inseridas no frontend do Zabbix e armazenadas no banco de dados do Zabbix em texto simples.
  • A criptografia integrada não protege as comunicações entre o servidor web que executa o frontend do Zabbix e o navegador web do usuário.
  • Atualmente, cada conexão criptografada é aberta com um handshake TLS completo; não há cache de sessão nem tickets implementados.
  • Adicionar criptografia aumenta o tempo para verificações de item e ações, dependendo da latência da rede:
    • Por exemplo, se o atraso dos pacotes for de 100 ms, abrir uma conexão TCP e enviar uma solicitação sem criptografia leva cerca de 200 ms. Com criptografia, cerca de 1000 ms são adicionados para estabelecer a conexão TLS.
    • Pode ser necessário aumentar os timeouts; caso contrário, alguns items e ações que executam scripts remotos em agents podem funcionar com conexões sem criptografia, mas falhar por timeout com criptografia.
  • A criptografia não é suportada por descoberta de rede. As verificações do Zabbix agent realizadas pela descoberta de rede serão sem criptografia e, se o Zabbix agent estiver configurado para rejeitar conexões sem criptografia, essas verificações não terão sucesso.

Compilando o Zabbix com suporte a criptografia

Para oferecer suporte à criptografia, o Zabbix deve ser compilado e vinculado com uma das bibliotecas criptográficas suportadas:

  • GnuTLS - a partir da versão 3.1.18
  • OpenSSL - versões 1.0.1, 1.0.2, 1.1.0, 1.1.1, 3.0.x - 3.5.x
  • LibreSSL - testado com as versões 2.7.4, 2.8.2:
    • LibreSSL 2.6.x não é suportado
    • LibreSSL é suportado como uma substituição compatível do OpenSSL; as novas funções de API específicas do LibreSSL tls_*() não são usadas. Os componentes do Zabbix compilados com LibreSSL não poderão usar PSK; apenas certificados podem ser usados.

Você pode encontrar mais informações sobre a configuração de SSL para o frontend do Zabbix consultando estas boas práticas.

A biblioteca é selecionada especificando a opção correspondente no script "configure":

  • --with-gnutls[=DIR]
  • --with-openssl[=DIR] (também usado para LibreSSL)

Por exemplo, para configurar os fontes do server e do agent com OpenSSL, você pode usar algo como:

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

Diferentes componentes do Zabbix podem ser compilados com diferentes bibliotecas criptográficas (por exemplo, um server com OpenSSL e um agent com GnuTLS).

Se você planeja usar chaves pré-compartilhadas (PSK), considere usar as bibliotecas GnuTLS ou OpenSSL 1.1.0 (ou mais recentes) nos componentes do Zabbix que usam PSKs. As bibliotecas GnuTLS e OpenSSL 1.1.0 suportam conjuntos de cifras PSK com Perfect Forward Secrecy. Versões mais antigas da biblioteca OpenSSL (1.0.1, 1.0.2c) também suportam PSKs, mas os conjuntos de cifras PSK disponíveis não fornecem Perfect Forward Secrecy.

Gerenciamento de criptografia de conexões

As conexões no Zabbix podem usar:

Há dois parâmetros importantes usados para especificar a criptografia entre os componentes do Zabbix:

  • TLSConnect - especifica qual criptografia usar para conexões de saída (sem criptografia, PSK ou certificado)
  • TLSAccept - especifica quais tipos de conexões são permitidos para conexões de entrada (sem criptografia, PSK ou certificado). Um ou mais valores podem ser especificados.

TLSConnect é usado nos arquivos de configuração do Zabbix proxy (no modo ativo, especifica apenas conexões para server) e do Zabbix agent (para verificações ativas). No Zabbix frontend, o equivalente de TLSConnect é o campo Connections to host em Data collection > Hosts > <some host> > aba Encryption e o campo Connections to proxy em Administration > Proxies> <some proxy> > aba Encryption. Se o tipo de criptografia configurado para a conexão falhar, nenhum outro tipo de criptografia será tentado.

TLSAccept é usado nos arquivos de configuração do Zabbix proxy (no modo passivo, especifica apenas conexões do server) e do Zabbix agent (para verificações passivas). No Zabbix frontend, o equivalente de TLSAccept é o campo Connections from host em Data collection > Hosts > <some host> > aba Encryption e o campo Connections from proxy em Administration > Proxies > <some proxy> > aba Encryption.

Normalmente, você configura apenas um tipo de criptografia para conexões de entrada. Mas talvez você queira alterar o tipo de criptografia, por exemplo, de sem criptografia para baseada em certificado, com o mínimo de indisponibilidade e possibilidade de rollback. Para isso:

  • Defina TLSAccept=unencrypted,cert no arquivo de configuração do agent e reinicie o Zabbix agent
  • Teste a conexão com zabbix_get para o agent usando certificado. Se funcionar, você pode reconfigurar a criptografia para esse agent no Zabbix frontend, na aba Data collection > Hosts > <some host> > Encryption, definindo Connections to host como "Certificate".
  • Quando o cache de configuração do server for atualizado (e a configuração do proxy for atualizada, se o host for monitorado por proxy), as conexões com esse agent serão criptografadas
  • Se tudo funcionar como esperado, você pode definir TLSAccept=cert no arquivo de configuração do agent e reiniciar o Zabbix agent. Agora o agent aceitará apenas conexões criptografadas baseadas em certificado. Conexões sem criptografia e baseadas em PSK serão rejeitadas.

De forma semelhante, isso funciona no server e no proxy. Se, no Zabbix frontend, na configuração do host, Connections from host estiver definido como "Certificate", então apenas conexões criptografadas baseadas em certificado serão aceitas do agent (verificações ativas) e do zabbix_sender (itens trapper).

Muito provavelmente, você configurará as conexões de entrada e saída para usar o mesmo tipo de criptografia ou nenhuma criptografia. Mas, tecnicamente, é possível configurá-las de forma assimétrica, por exemplo, criptografia baseada em certificado para conexões de entrada e baseada em PSK para conexões de saída.

A configuração de criptografia de cada host é exibida no Zabbix frontend, em Data collection > Hosts, na coluna Agent encryption. Por exemplo:

Example Connections to host Allowed connections from host Rejected connections from host
none\_none.png Unencrypted Unencrypted Encrypted, certificate and PSK-based encrypted
cert\_cert.png Encrypted, certificate-based Encrypted, certificate-based Unencrypted and PSK-based encrypted
psk\_psk.png Encrypted, PSK-based Encrypted, PSK-based Unencrypted and certificate-based encrypted
psk\_none\_psk.png Encrypted, PSK-based Unencrypted and PSK-based encrypted Certificate-based encrypted
cert\_all.png Encrypted, certificate-based Unencrypted, PSK or certificate-based encrypted -

As conexões são sem criptografia por padrão. A criptografia deve ser configurada individualmente para cada host e proxy.

zabbix_get e zabbix_sender com criptografia

Veja as páginas de manual zabbix_get e zabbix_sender para usá-los com criptografia.

Conjuntos de cifras

Os conjuntos de cifras são configurados internamente por padrão durante a inicialização do Zabbix.

Também há suporte a conjuntos de cifras configurados pelo usuário para GnuTLS e OpenSSL. Os usuários podem configurar conjuntos de cifras de acordo com suas políticas de segurança. O uso desse recurso é opcional (os conjuntos de cifras padrão integrados continuam funcionando).

Para bibliotecas criptográficas compiladas com as configurações padrão, as regras integradas do Zabbix normalmente resultam nos seguintes conjuntos de cifras (em ordem de maior para menor prioridade):

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 configuradas pelo usuário

Os critérios de seleção de ciphersuite integrados podem ser substituídos por ciphersuites configuradas pelo usuário.

Ciphersuites configuradas pelo usuário é um recurso destinado a usuários avançados que entendem ciphersuites TLS, sua segurança e as consequências de erros, e que se sentem à vontade com a solução de problemas de TLS.

Os critérios de seleção de ciphersuite integrados podem ser substituídos usando os seguintes parâmetros:

Escopo da substituição Parâmetro Valor Descrição
Seleção de ciphersuite para certificados TLSCipherCert13 Strings de cipher válidas do OpenSSL 1.1.1 cipher strings para o protocolo TLS 1.3 (seus valores são passados para a função SSL_CTX_set_ciphersuites() do OpenSSL). Critérios de seleção de ciphersuite baseados em certificado para TLS 1.3

Apenas OpenSSL 1.1.1 ou mais recente.
TLSCipherCert Strings de cipher válidas do OpenSSL cipher strings para TLS 1.2 ou strings de prioridade válidas do GnuTLS priority strings. Seus valores são passados, respectivamente, para as funções SSL_CTX_set_cipher_list() ou gnutls_priority_init(). Critérios de seleção de ciphersuite baseados em certificado para TLS 1.2/1.3 (GnuTLS), TLS 1.2 (OpenSSL)
Seleção de ciphersuite para PSK TLSCipherPSK13 Strings de cipher válidas do OpenSSL 1.1.1 cipher strings para o protocolo TLS 1.3 (seus valores são passados para a função SSL_CTX_set_ciphersuites() do OpenSSL). Critérios de seleção de ciphersuite baseados em PSK para TLS 1.3

Apenas OpenSSL 1.1.1 ou mais recente.
TLSCipherPSK Strings de cipher válidas do OpenSSL cipher strings para TLS 1.2 ou strings de prioridade válidas do GnuTLS priority strings. Seus valores são passados, respectivamente, para as funções SSL_CTX_set_cipher_list() ou gnutls_priority_init(). Critérios de seleção de ciphersuite baseados em PSK para TLS 1.2/1.3 (GnuTLS), TLS 1.2 (OpenSSL)
Lista combinada de ciphersuite para certificado e PSK TLSCipherAll13 Strings de cipher válidas do OpenSSL 1.1.1 cipher strings para o protocolo TLS 1.3 (seus valores são passados para a função SSL_CTX_set_ciphersuites() do OpenSSL). Critérios de seleção de ciphersuite para TLS 1.3

Apenas OpenSSL 1.1.1 ou mais recente.
TLSCipherAll Strings de cipher válidas do OpenSSL cipher strings para TLS 1.2 ou strings de prioridade válidas do GnuTLS priority strings. Seus valores são passados, respectivamente, para as funções SSL_CTX_set_cipher_list() ou gnutls_priority_init(). Critérios de seleção de ciphersuite para TLS 1.2/1.3 (GnuTLS), TLS 1.2 (OpenSSL)

Para substituir a seleção de ciphersuite nos utilitários zabbix_get e zabbix_sender - use os parâmetros de linha de comando:

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

Os novos parâmetros são opcionais. Se um parâmetro não for especificado, o valor padrão interno será usado. Se um parâmetro for definido, ele não pode ser vazio.

Se a configuração de um valor TLSCipher* na biblioteca criptográfica falhar, então o server, proxy ou agent não iniciará e um erro será registrado.

É importante entender quando cada parâmetro é aplicável.

Conexões de saída

O caso mais simples é o de conexões de saída:

  • Para conexões de saída com certificado - use TLSCipherCert13 ou TLSCipherCert
  • Para conexões de saída com PSK - use TLSCipherPSK13 ou TLSCipherPSK
  • No caso das utilitários zabbix_get e zabbix_sender, os parâmetros de linha de comando --tls-cipher13 ou --tls-cipher podem ser usados (a criptografia é especificada de forma inequívoca com um parâmetro --tls-connect)
Conexões de entrada

É um pouco mais complicado com conexões de entrada, porque as regras são específicas para componentes e configuração.

Para o agent do Zabbix:

Configuração de conexão do Agent Configuração de cifra
TLSConnect=cert TLSCipherCert, TLSCipherCert13
TLSConnect=psk TLSCipherPSK, TLSCipherPSK13
TLSAccept=cert TLSCipherCert, TLSCipherCert13
TLSAccept=psk TLSCipherPSK, TLSCipherPSK13
TLSAccept=cert,psk TLSCipherAll, TLSCipherAll13

Para o server e o proxy do Zabbix:

Configuração de conexão Configuração de cifra
Conexões de saída usando PSK TLSCipherPSK, TLSCipherPSK13
Conexões de entrada usando certificados TLSCipherAll, TLSCipherAll13
Conexões de entrada usando PSK se o server não tiver certificado TLSCipherPSK, TLSCipherPSK13
Conexões de entrada usando PSK se o server tiver certificado TLSCipherAll, TLSCipherAll13

Algum padrão pode ser observado nas duas tabelas acima:

  • TLSCipherAll e TLSCipherAll13 podem ser especificados somente se for usada uma lista combinada de cifras baseadas em certificado e em PSK. Há dois casos em que isso ocorre: server (proxy) com um certificado configurado (as cifras PSK são sempre configuradas no server, no proxy se a biblioteca criptográfica oferecer suporte a PSK), agent configurado para aceitar conexões de entrada baseadas em certificado e em PSK
  • em outros casos, TLSCipherCert* e/ou TLSCipherPSK* são suficientes

As tabelas a seguir mostram os valores padrão internos de TLSCipher*. Eles podem ser um bom ponto de partida para seus próprios valores personalizados.

Parâmetro 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
Parâmetro 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 Os valores padrão são diferentes para versões mais antigas do OpenSSL (1.0.1, 1.0.2, 1.1.0), para LibreSSL e se o OpenSSL for compilado sem suporte a PSK.

Exemplos de cifras configuradas pelo usuário

Veja abaixo os exemplos a seguir de cifras configuradas pelo usuário:

Testando strings de cifra e permitindo apenas suites de cifras PFS

Para ver quais suites de cifras foram selecionadas, você precisa definir 'DebugLevel=4' no arquivo de configuração ou usar a opção -vv para zabbix_sender.

Pode ser necessário fazer alguns testes com os parâmetros TLSCipher* antes de obter as suites de cifras desejadas. É inconveniente reiniciar o Zabbix server, proxy ou agent várias vezes apenas para ajustar os parâmetros TLSCipher*. Opções mais convenientes são usar zabbix_sender ou o comando openssl. Vamos mostrar ambos.

1. Usando zabbix_sender.

Vamos criar um arquivo de configuração de teste, por exemplo, /home/zabbix/test.conf, com a sintaxe de um arquivo 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

Você precisa de certificados válidos de CA e do agent, além de PSK, para este exemplo. Ajuste os caminhos e nomes dos arquivos de certificado e PSK para o seu ambiente.

Se você não estiver usando certificados, apenas PSK, pode criar um arquivo de teste mais simples:

  Hostname=nonexisting
  ServerActive=nonexisting

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

As suites de cifras selecionadas podem ser vistas executando zabbix_sender (exemplo compilado com 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

Aqui você vê as suites de cifras selecionadas por padrão. Esses valores padrão são escolhidos para garantir interoperabilidade com agents do Zabbix executando em sistemas com versões mais antigas do OpenSSL (a partir de 1.0.1).

Em sistemas mais novos, você pode optar por reforçar a segurança permitindo apenas algumas suites de cifras, por exemplo, apenas suites de cifras com PFS (Perfect Forward Secrecy). Vamos tentar permitir apenas suites de cifras com PFS usando os parâmetros TLSCipher*.

O resultado não será interoperável com sistemas que usam OpenSSL 1.0.1 e 1.0.2, se PSK for usado. A criptografia baseada em certificado deve funcionar.

Adicione duas linhas ao arquivo de configuração test.conf:

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

e teste novamente:

  $ 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        

As listas "certificate ciphersuites" e "PSK ciphersuites" mudaram

  • elas estão mais curtas do que antes, contendo apenas suites de cifras TLS 1.3 e suites de cifras TLS 1.2 ECDHE-* como esperado.

2. TLSCipherAll e TLSCipherAll13 não podem ser testados com zabbix_sender; eles não afetam o valor "certificate and PSK ciphersuites" mostrado no exemplo acima. Para ajustar TLSCipherAll e TLSCipherAll13, você precisa fazer testes com o agent, proxy ou server.

Portanto, para permitir apenas suites de cifras PFS, talvez seja necessário adicionar até três parâmetros

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

em zabbix_agentd.conf, zabbix_proxy.conf e zabbix_server.conf se cada um deles tiver um certificado configurado e o agent também tiver PSK.

Se o seu ambiente Zabbix usar apenas criptografia baseada em PSK e nenhum certificado, então apenas um:

  TLSCipherPSK=kECDHEPSK+AES128

Agora que você entende como funciona, pode testar a seleção de suites de cifras até mesmo fora do Zabbix, com o comando openssl. Vamos testar os valores de todos os três parâmetros 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

Você pode preferir openssl ciphers com a opção -V para uma saída mais detalhada:

  $ 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

Da mesma forma, você pode testar as strings de prioridade para 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
Mudando de AES128 para AES256

O Zabbix usa AES128 como padrão integrado para os dados. Vamos supor que você esteja usando certificados e queira mudar para AES256, no OpenSSL 1.1.1.

Isso pode ser feito adicionando os respectivos parâmetros em 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

Embora apenas conjuntos de cifras relacionados a certificados sejam usados, os parâmetros TLSCipherPSK* também são definidos para evitar seus valores padrão, que incluem cifras menos seguras para uma maior interoperabilidade. Os conjuntos de cifras PSK não podem ser completamente desativados no server/proxy.

E em 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

Solução de problemas de criptografia

Recomendações gerais:

  • Comece entendendo qual componente atua como cliente TLS e qual atua como servidor TLS no caso do problema.
    Zabbix server, proxies e agents, dependendo da interação entre eles, podem atuar tanto como servidores TLS quanto como clientes TLS.
    Por exemplo, o Zabbix server ao se conectar ao agent para uma verificação passiva atua como cliente TLS. O agent está no papel de servidor TLS.
    O Zabbix agent, ao solicitar uma lista de verificações ativas ao proxy, atua como cliente TLS. O proxy está no papel de servidor TLS.
    As utilidades zabbix_get e zabbix_sender sempre atuam como clientes TLS.
  • O Zabbix usa autenticação mútua.
    Cada lado verifica seu par e pode recusar a conexão.
    Por exemplo, o Zabbix server ao se conectar ao agent pode encerrar a conexão imediatamente se o certificado do agent for inválido. E vice-versa - o Zabbix agent ao aceitar uma conexão do server pode encerrar a conexão se o server não for confiável para o agent.
  • Examine os arquivos de log em ambos os lados - no cliente TLS e no servidor TLS.
    O lado que recusa a conexão pode registrar um motivo preciso pelo qual ela foi recusada. O outro lado frequentemente relata um erro mais geral (por exemplo, "Connection closed by peer", "connection was non-properly terminated").
  • Às vezes, uma criptografia configurada incorretamente resulta em mensagens de erro confusas que não apontam de forma alguma para a causa real.
    Nas subseções abaixo, tentamos fornecer uma coleção (longe de ser exaustiva) de mensagens e possíveis causas que podem ajudar na solução de problemas.
    Observe que diferentes toolkits criptográficos (OpenSSL, GnuTLS) frequentemente produzem mensagens de erro diferentes nas mesmas situações de problema.
    Às vezes, as mensagens de erro dependem até mesmo da combinação específica de toolkits criptográficos em ambos os lados.

Solução de problemas de tipo de conexão ou problemas de permissão

Server está configurado para se conectar com PSK ao agent, mas o agent aceita apenas conexões não criptografadas

No log do server ou proxy (com GnuTLS 3.3.16)

Falha ao obter valor do agent: zbx_tls_connect(): gnutls_handshake() failed: \
    -110 A conexão TLS foi encerrada de forma incorreta.

No log do server ou proxy (com OpenSSL 1.0.2c)

Falha ao obter valor do agent: conexão TCP bem-sucedida, não foi possível estabelecer TLS com [[127.0.0.1]:10050]: \
    Conexão fechada pelo peer. Verifique os tipos de conexão permitidos e os direitos de acesso
Um lado se conecta com certificado, mas o outro lado aceita apenas PSK ou vice-versa

Em qualquer log (com 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.

Em qualquer log (com 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"

Tentando usar o Zabbix sender compilado com suporte a TLS para enviar dados para o Zabbix server/proxy compilado sem TLS

No log do lado da conexão:

Linux:

...Em zbx_tls_init_child()
...Biblioteca OpenSSL (versão OpenSSL 1.1.1  11 Sep 2018) inicializada
...
...Em zbx_tls_connect(): psk_identity:"PSK test sender"
...Fim de zbx_tls_connect():FALHA erro:'conexão fechada pelo peer'
...erro ao enviar valor: TCP bem-sucedido, não foi possível estabelecer TLS com [[localhost]:10051]: conexão fechada pelo peer

Windows:

...Biblioteca OpenSSL (versão OpenSSL 1.1.1a  20 Nov 2018) inicializada
...
...Em zbx_tls_connect(): psk_identity:"PSK test sender"
...zbx_psk_client_cb() solicitou a identidade PSK "PSK test sender"
...Fim de zbx_tls_connect():FALHA erro:'erro de E/S em SSL_connect(): [0x00000000] A operação foi concluída com êxito.'
...erro ao enviar valor: TCP bem-sucedido, não foi possível estabelecer TLS com [[192.168.1.2]:10051]: erro de E/S em SSL_connect(): [0x00000000] A operação foi concluída com êxito.
No log do lado que aceita a conexão:
...falha ao aceitar uma conexão de entrada: de 127.0.0.1: o suporte a TLS não foi compilado

Um lado se conecta com PSK, mas o outro lado usa LibreSSL ou foi compilado sem suporte a criptografia

O LibreSSL não oferece suporte a PSK.

No log do lado que está se conectando:

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

No log do lado que está aceitando:

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

No frontend do Zabbix:

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

Um lado se conecta com PSK, mas o outro lado usa OpenSSL com suporte a PSK desativado

No log do lado que está se conectando:

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

No log do lado que está aceitando:

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