Zabbix 5.2: Configurando integracão com Vault externo.

bernardolankheet
Zabbix Brasil
Published in
11 min readNov 6, 2020

Uma das novidades da ultima versão do Zabbix, 5.2, é a integração nativa com o Hashicorp Vault, com isso é melhorar a camada de segurança no armazenamento de informações secretas utilizadas no Zabbix, com isso deixamos toda a parte de armazenamento das credenciais sobre responsabilidade de um Hashicorp Vault externo. Assim não precisamos deixar macros ou em texto plano logins, senhas e informações sensíveis de forma insegura no frontend do Zabbix.

Para quem não conhece o Hashicorp Vault, acessem a pagina do projeto. LINK

Bora para HandsOn.

Nesse ambiente utilizei:

1 — Zabbix Server 5.2;

1.1 — Fiz toda a instalação por pacote dos módulos do Zabbix no mesmo servidor;

1.2 — Crie a tabela e usuários para o banco, importe o schema do banco do Zabbix(script create.sql);

1.3 — Não realize a configuração de conexão com o banco de dados no arquivo de configuração do Zabbix server(/etc/zabbix/zabbix_server.conf);

1.4 — Habilite o systemctl para o serviço do zabbix-server e agente iniciar normalmente com o sistema. (systemctl enable zabbix-server zabbix-agent);

2 — Selinux desabilitado;

3 — Inicialmente deixei o Firewall habilitado, com as regras:

firewall-cmd --add-service={http,https} --permanent
firewall-cmd --add-port={10051/tcp,10050/tcp} --permanent
firewall-cmd --reload

Instalando Hashicorp Vault

Instale o repositório da Hashicorp e depois proceda com a instalação do Vault.

[root@centos ~]# dnf config-manager --add-repo <https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo> 
[root@centos ~]# dnf -y install vault
[root@centos ~]# systemctl enable vault --now

Incluir um host chamado vault no /etc/hosts para responder localmente, pode ser que o vault e zabbix não se comunicam por IP 127.0.0.1 ou localhost, somente por nome.

[root@centos ~]# vi /etc/hosts127.0.0.1   vault

Exporta a url em uma variavel de sistema

[root@centos ~]# export VAULT_ADDR='<https://vault:8200>'

Verifique se a variavel está funcionando

[root@centos ~]# echo $VAULT_ADDR
<https://vault:8200>

Conectando ao local vault e testando a conexão, utilizando um certificado tls default do vault. Se tentar conectar sem certificado, dá erro, porque a comunicação é criptografada.

[root@centos ~]# vault status -ca-cert=/opt/vault/tls/tls.crt
Key Value
--- -----
Seal Type shamir
Initialized false
Sealed true
Total Shares 0
Threshold 0
Unseal Progress 0/0
Unseal Nonce n/a
Version n/a
HA Enabled false
[root@centos ~]# vault -v
Vault v1.5.5 (f5d1ddb3750e7c28e25036e1ef26a4c02379fc01)
[root@centos ~]# vault status
Error checking seal status: Get "<https://vault:8200/v1/sys/seal-status>": x509: certificate signed by unknown authority

Obs: é possivel utilizar o LetsEncrypt para gerar certificado auto assinado e aplicar automaticamente no Vault.

Copiando o certificado do vault para a cadeia de certificado do sistema.

[root@centos ~]# cp /opt/vault/tls/tls.crt /etc/pki/ca-trust/source/anchors/vault.crt
[root@centos ~]# update-ca-trust extra

Agora já é possivel verificar o status do vault sem a necessidade de informar o certificado.

[root@cento ~]# vault status
Key Value
--- -----
Seal Type shamir
Initialized false
Sealed true
Total Shares 0
Threshold 0
Unseal Progress 0/0
Unseal Nonce n/a
Version n/a
HA Enabled false

Vamos neste momento inicializar o vault.

[root@centos ~]# vault operator init
Unseal Key 1: uRA+yK2uHoXmleASIF8dJGDIm93kS3s2l38bn7unm+z/
Unseal Key 2: zRCy1W09e0g13xVLJDsoHJaIAH1+gLy5IRg/zDP4Xh2m
Unseal Key 3: vdmbYj+ioL8HrCzvIHyPHK/7ovIX2XGgzO8jvmF+ACIB
Unseal Key 4: O39U3P2pLo/5MbwmH2BYiQzM9iBEvq9exzsL6QeUGj0g
Unseal Key 5: XEokqTzVJ8iJPWKa0Pjcad7oUsEzZXTRYeKw8P1wtc4P
Initial Root Token: s.2CjswjSonCAHyj3ZQiUnkOiVVault initialized with 5 key shares and a key threshold of 3. Please securely
distribute the key shares printed above. When the Vault is re-sealed,
restarted, or stopped, you must supply at least 3 of these keys to unseal it
before it can start servicing requests.
Vault does not store the generated master key. Without at least 3 key to
reconstruct the master key, Vault will remain permanently sealed!
It is possible to generate new unseal keys, provided you have a quorum of
existing unseal keys shares. See "vault operator rekey" for more information.

Será gerado 5 chaves e um token para de root, é importante salva-los e documenta-los. Pode ser solicitado para recuperação do serviços ou para acesso web ao Vault.

Verique o status agora novamente e verá que em inicialização, estará como true.

[root@centos ~]# vault status
Key Value
--- -----
Seal Type shamir
Initialized true
Sealed true
Total Shares 5
Threshold 3
Unseal Progress 0/3
Unseal Nonce n/a
Version 1.5.5
HA Enabled false

Antes de começarmos a utilizar, precisaremos iniciar um processo do vault chamado “operator unseal”. Onde é um processo de obtenção da chave mestre do texto simples necessária para ler a chave de descriptografia para descriptografar os dados, permitindo o acesso ao Cofre do Vault.

Precisaremos utilizar as chaves unseal que foram apresentadas no momento do init. Podemos notar que no vault status, em Unseal Progress é apresentado 0/3. Logo será preciso repetir 3 vezes o comento e digitar 3 Unseal Key diferentes.

[root@centos ~]# vault operator unseal
Unseal Key (will be hidden):

Repete o processo 3 vezes e informe 3 keys diferentes, das 5 criadas anteriormente.

[root@centos ~]# vault operator unseal
Unseal Key (will be hidden):
Key Value
--- -----
Seal Type shamir
Initialized true
Sealed true
Total Shares 5
Threshold 3
**Unseal Progress 2/3**
Unseal Nonce 1efa39f0-fff3-3127-bd18-514bd058235b
Version 1.5.5
HA Enabled false
[root@centos ~]# vault operator unseal
Unseal Key (will be hidden):
Key Value
--- -----
Seal Type shamir
Initialized true
Sealed false
Total Shares 5
Threshold 3
Version 1.5.5
Cluster Name vault-cluster-bf619eb5
Cluster ID 072191cc-cf3a-b28e-db71-1704c790b82a
HA Enabled false

Apos repetir, verá que o Unseal Progress ****e ****Unseal Nonce não aparecerá mais.

Obs: Se reiniciar o Sistema Operacional, deverá repetir estes passos, exportar a variavel de sistema, recriar e refazer o processo de Unseal.

Realize neste momento o login no Vault. Será necessário informar o token de root, criado no momento da inicialização. Não é recomendável usar o root em produção, há maneiras de criar outros usuarios para este fim.

[root@centos ~]# vault login
Token (will be hidden):
Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.
Key Value
--- -----
token s.2CjswjSonCAHyj3ZQiUnkOiV
token_accessor Lct6fxVO98BzkCwJfsFL4G6F
token_duration ∞
token_renewable false
token_policies ["root"]
identity_policies []
policies ["root"]

Vamos criar um secret engine para podermos guardar todos os nossos secrets para o zabbix.

[root@centos ~]# vault secrets enable -path=servicezabbix kv-v2
Success! Enabled the kv-v2 secrets engine at: servicezabbix/

Crie agora um secret para um usuario que utilizaremos para o zabbix conectar ao banco de dados. Este é o usuario de acesso ao banco de dados do zabbix, o mesmo que criou no momento de subir a base e fazer o import.

[root@centos ~]# vault kv put servicezabbix/database username=zabbixdb password=Zabbix@2020*
Key Value
--- -----
created_time 2020-11-05T13:56:52.700828925Z
deletion_time n/a
destroyed false
version 1

Você poderá ver o Vault criado

[root@centos ~]# vault kv get servicezabbix/database
====== Metadata ======
Key Value
--- -----
created_time 2020-11-05T13:56:52.700828925Z
deletion_time n/a
destroyed false
version 1
====== Data ======
Key Value
--- -----
password Zabbix@2020*
username zabbixdb

Crie uma politica no Vault para o Zabbix frontend, nela daremos permissão para leitura e listagem dos secrets.

[root@centos ~]# vi /etc/vault.d/zabbix-frontend.hclpath "servicezabbix/data/database"
{
capabilities = ["list","read"]
}

Agora podemos gravar a nova politica.

[root@centos ~]# vault policy write zabbix-frontend /etc/vault.d/zabbix-frontend.hcl
Success! Uploaded policy: zabbix-frontend

Agora podemos criar o token de acesso para um novo token para o zabbix-frontend. Documente esse token, ele utilizaremos na configuração do frontend do Zabbix.

[root@centos ~]# vault token create -policy=zabbix-frontend
Key Value
--- -----
token s.09qkfDRsKc6waEvwQMl8Qxbu
token_accessor tpuG2XJkWF9tjwdXrHJMtB4B
token_duration 768h
token_renewable true
token_policies ["default" "zabbix-frontend"]
identity_policies []
policies ["default" "zabbix-frontend"]

Crie uma outra politica agora, para as configurações do Zabbix Server e também para as futuras macros que utilizaremos no frontend do Zabbix.

[root@centos ~]# vi /etc/vault.d/zabbix-server.hcl
path "servicezabbix/data/database"
{
capabilities = ["list","read"]
}
path "servicezabbix/data/macros"
{
capabilities = ["list","read"]
}

Grave a nova politica para o Zabbix Server

[root@centos ~]# vault policy write zabbix-server /etc/vault.d/zabbix-server.hcl
Success! Uploaded policy: zabbix-server

Crie um novo Token para o Zabbix Server, documente este token gerado.

[root@centos ~]# vault token create -policy=zabbix-server
Key Value
--- -----
token s.Wq4erOAMzIdJvThPJ2z7ISyv
token_accessor dSNUj5OsBKitQ9HGnKyUWrC9
token_duration 768h
token_renewable true
token_policies ["default" "zabbix-server"]
identity_policies []
policies ["default" "zabbix-server"]

Agora será preciso informar ao zabbix, que será utilizado o vault para login e senha no banco.

Comente os parametros DBUser= e DBPassword=, não será preciso utiliza-los.

[root@centos ~]#  vi /etc/zabbix/zabbix_server.conf
# Comenta os campos responsaveis pela comunicação com o banco, não utilizaremos eles.
# DBUser=
# DBPassword=
#Pesquise dentro do arquivo por Vault e
VaultToken=<TOKEN ZABBIX SERVER>
VaultURL=https://vault:8200
VaultDBPath=servicezabbix/database

Neste exemplo ficou assim:

...
# DBUser=
....
# DBPassword=
....
### Option: VaultToken
# Vault authentication token that should have been generated exclusively for Zabbix server with read only permission
# to paths specified in Vault macros and read only permission to path specified in optional VaultDBPath
# configuration parameter.
# It is an error if VaultToken and VAULT_TOKEN environment variable are defined at the same time.
#
# Mandatory: no
# Default:
# VaultToken=
VaultToken=s.Wq4erOAMzIdJvThPJ2z7ISyv
### Option: VaultURL
# Vault server HTTP[S] URL. System-wide CA certificates directory will be used if SSLCALocation is not specified.
#
# Mandatory: no
# Default:
# VaultURL=https://127.0.0.1:8200
VaultURL=https://vault:8200
### Option: VaultDBPath
# Vault path from where credentials for database will be retrieved by keys 'password' and 'username'.
# Example: secret/zabbix/database
# This option can only be used if DBUser and DBPassword are not specified.
#
# Mandatory: no
# Default:
# VaultDBPath=
VaultDBPath=servicezabbix/database

Reinicie o serviço do Zabbix-Server;

[root@centos ~]# systemctl restart zabbix-server

Verifica o log do zabbix server se está UP.

[root@centos ~]# tail -f /var/log/zabbix/zabbix-server.log
2261:20201105:134202.724 Web monitoring: YES
2261:20201105:134202.724 VMware monitoring: YES
2261:20201105:134202.724 SMTP authentication: YES
2261:20201105:134202.724 ODBC: YES
2261:20201105:134202.724 SSH support: YES
2261:20201105:134202.724 IPv6 support: YES
2261:20201105:134202.724 TLS support: YES
2261:20201105:134202.724 ******************************
2261:20201105:134202.724 using configuration file: /etc/zabbix/zabbix_server.conf
2261:20201105:134202.807 current database version (mandatory/optional): 05020000/05020000
2261:20201105:134202.807 required mandatory version: 05020000
2261:20201105:134204.044 server #0 started [main process]
2265:20201105:134204.045 server #1 started [configuration syncer #1]
2275:20201105:134204.367 server #11 started [proxy poller #1]
2277:20201105:134204.369 server #13 started [task manager #1]
2278:20201105:134204.370 server #14 started [poller #1]
2280:20201105:134204.372 server #16 started [poller #3]
2276:20201105:134204.374 server #12 started [self-monitoring #1]
2272:20201105:134204.374 server #8 started [history syncer #3]
2267:20201105:134204.375 server #3 started [timer #1]
2268:20201105:134204.376 server #4 started [http poller #1]
2266:20201105:134204.376 server #2 started [housekeeper #1]
2269:20201105:134204.377 server #5 started [discoverer #1]
2270:20201105:134204.378 server #6 started [history syncer #1]
2271:20201105:134204.379 server #7 started [history syncer #2]
2274:20201105:134204.380 server #10 started [escalator #1]
2279:20201105:134204.381 server #15 started [poller #2]
2281:20201105:134204.383 server #17 started [poller #4]
2283:20201105:134204.385 server #19 started [unreachable poller #1]
2284:20201105:134204.386 server #20 started [trapper #1]
2273:20201105:134204.388 server #9 started [history syncer #4]
2282:20201105:134204.389 server #18 started [poller #5]
2285:20201105:134204.390 server #21 started [trapper #2]
2286:20201105:134204.395 server #22 started [trapper #3]
2287:20201105:134204.398 server #23 started [trapper #4]
2288:20201105:134204.401 server #24 started [trapper #5]
2289:20201105:134204.404 server #25 started [icmp pinger #1]
2290:20201105:134204.405 server #26 started [alert manager #1]
2291:20201105:134204.406 server #27 started [alerter #1]
2292:20201105:134204.406 server #28 started [alerter #2]
2293:20201105:134204.407 server #29 started [alerter #3]
2294:20201105:134204.407 server #30 started [preprocessing manager #1]
2295:20201105:134204.408 server #31 started [preprocessing worker #1]
2296:20201105:134204.408 server #32 started [preprocessing worker #2]
2297:20201105:134204.408 server #33 started [preprocessing worker #3]
2298:20201105:134204.409 server #34 started [lld manager #1]
2299:20201105:134204.409 server #35 started [lld worker #1]
2300:20201105:134204.410 server #36 started [lld worker #2]
2301:20201105:134204.411 server #37 started [alert syncer #1]
2282:20201105:134205.743 Zabbix agent item "system.cpu.util[,guest]" on host "Zabbix server" failed: first network error, wait for 15 seconds

Ate nesse momento o Zabbix server já está utilizando os Tokens do Vault para acesso ao banco e o serviço já foi iniciado com sucesso.

Configuração pelo Frontend do Zabbix

Podemos agora conectar via Frontend e começar a configuração finais.

http://IP_OU_DNS/zabbix

Realize as configurações iniciais normalmente, e na parte de configuração da conexão ao Banco de dados, altere em Store credentials in para HashiCorp Vault.

Inclue a url da sua API, que utilizamos anteriormente, o path do Vault secret e Token que criamos para o frontend.

Clique em Next step.

Um ponto importante que notei, é que o token fica totalmente visível no arquivo de configuração do frontend. /etc/zabbix/web/zabbix.conf.php.

[root@centos ~]# vi /etc/zabbix/web/zabbix.conf.php
// Vault configuration. Used if database credentials are stored in Vault secrets manager.
$DB['VAULT_URL'] = '<https://vault:8200>';
$DB['VAULT_DB_PATH'] = 'servicezabbix/database';
$DB['VAULT_TOKEN'] = 's.09qkfDRsKc6waEvwQMl8Qxbu';

Realizando testes com Macros e SSH.

Agora vamos realizar um teste salvando as credencias em um Vault e depois utilizar uma macro de conexão ssh em um host especifico.

Primeiro vamos criar o Vault com as credencias do ssh.

[root@centos ~]# vault kv put servicezabbix/macros username=centos password=centos2020
Key Value
--- -----
created_time 2020-11-05T17:48:43.745962006Z
deletion_time n/a
destroyed false
version 1

Verifique o Vault criado.

[root@centos ~]# vault kv get servicezabbix/macros
====== Metadata ======
Key Value
--- -----
created_time 2020-11-05T17:48:43.745962006Z
deletion_time n/a
destroyed false
version 1
====== Data ======
Key Value
--- -----
password centos2020
username centos

Crie um host agora no Zabbix para teste.

Agora na aba Macros, crie duas macros, uma para login e e outra para senha de SSH.

Em value segue o padrão que utilizamos alterando o tipo para Vault secret.

Sintax: servicezabbix (Secrets Engines):macros(secrets):key

Ficará desta forma:

{$SSH.USER} — servicezabbix/macros:username

{$SSH.PWD} — servicezabbix/macros:password

Clique em Add para salvar os host.

Dentro dente host, crie um item do tipo SSH agent, com a chave ssh.run[uname -a], as duas macros que criamos para username e password, executando o script “uname -a” e do tipo Text. Com isso será executado via ssh o comando uname -a no host remoto.

Volte no terminal e faça um reload das configurações, para o zabbix poder identificar as alterações com o novo Vault criado na macro. (É importante realizar este processo, se não o zabbix não reconhece o Vault cadastrado).

[root@centos ~]# zabbix_server -R config_cache_reload
zabbix_server [4714]: command sent successfully

Agora volte no terminal e selecione o item e clique no botão "Execute now".

Se for em Monitoring > Lasted data, verá o item sendo coletado.

Acessando UI, interface gráfica do Vault.

O Vault possui uma interface simples, nela é possível realizar todos os procedimentos que fizemos via linha de comando, além de consultar todos os polices, secrets e engines cadastrados.

Primeiro passo, temos que liberar a porta 8200 no firewall.

[root@centos ~]# firewall-cmd --add-port={8200/tcp,8200/tcp} --permanent
Warning: ALREADY_ENABLED: 8200:tcp
success
[root@centos ~]# firewall-cmd --reload
success

Conectar no vault via web

https://IP_OU_DNS:8200/

O token é o mesmo criado no momento do init (root token).

Nesse exemplo: s.2CjswjSonCAHyj3ZQiUnkOiV

Pelo console web, é possível ver todos os secrets criados, polices e access, que criamos anteriormente. Também é possível realizar todo o cadastro e manutenção via interface web.

Por fim, quero deixar mais um ponto importante que pude notar, todas as senhas estão gravadas no history do linux. Então é importante sempre limpa-lo.

[root@centos ~]# history -c

É uma integração nova, pode ser que apresente alguns bugs ou encontre dificuldade em utilizar, então fica a fica para montar um laboratório e testar.

Um grande abraço e ate a próxima!!

--

--