Zabbix de 0 a 100 - Documentación

From Zabbix-ES
Jump to navigation Jump to search

Introducción

Presentación

Mi nombre es Mariano Obarrio Miles, soy Lic. en Informática y desde hace varios años estoy trabajando con Zabbix, cuento con las certificaciones de Zabbix Certified Professional y Expert. 

Actualmente trabajo como Administrador de sistemas y soy responsable de la administración y monitorización de toda la infraestructura Hardware y Software en mi actual trabajo.
Perfil.png
Nombre  : Mariano J. Obarrio Miles
Estudios: Licenciado en Informática
          Universidad Argentina de la Empresa

          Zabbix Certified Professional
          Zabbix Certified Specialist




LinkedIn: https://www.linkedin.com/in/mobarrio
Twitter : https://twitter.com/mariano_obarrio

Objetivo del Curso

El objetivo de este curso es introducirnos en Zabbix que es una herramienta de monitorizacion de nivel empresarial, esto quiere decir que cumple con los niveles de excelencia que son requeridos dentro de una organización es robusto, flexible y muy fiable.
Al finalizar el curso obtendréis los conocimientos necesarios para poder instalar y administrar Zabbix, conocer su arquitectura y las características que ofrece y explotarlas de la mejor forma posible.
La modalidad del curso es generalmente practica, realizaremos instalaciones, configuraciones y laboratorios donde aplicaremos los conocimientos adquiridos.

Herramientas necesarias

Bueno para poder realizar esta formación será necesario contar con conocimientos básicos de Linux, ya que editaremos ficheros o reiniciaremos servicios desde línea de comando, no so preocupeis que todo es muy fácil.
Otro requisito es tener un ordenador con acceso a Internet para poder descargar las imágenes de Vagrant y un cliente ssh tipo Putty o SecureCRT para poder acceder a ellas.
En el siguiente MAPY os muestro la infraestructura que desplegará Vagrant y como nos conectaremos a ella.
MAPY de Infraestructura
Trabajaremos con 3 maquinas virtuales que se desplegaran con Vagrant sobre Virtualbox, no es necesario grandes conocimientos de Vagrant o de Virtualbox para poder preparar el entorno, pero si os interesa, hay un curso en OpenWebinars muy bueno y rápido de realizar impartido por Alberto Molina se llama Curso Online de Vagrant.

Ahora os explicaré para qué utilizaremos estas máquinas:

 - La primer máquina la utilizaremos para para instalar y configurar Zabbix Server, PostgreSQL y Zabbix Frontend.

 - La segunda la utilizaremos para monitorizarla, hacer pruebas y también probar algunas características avanzadas que comentaremos más adelante como el Auto-Registration. 

 - La tercera máquina la utilizaremos para ver como instalar y configurar un Zabbix Proxy.
Aquí debajo os dejo los links para poder poder descargar todo el software necesario:
 - Cliente SSH tipo Putty o SecureCRT (https://www.putty.org/)
  Nota: Si utilkizmos putty podemos tambien bajarnos el software TTYPlus
 
 - Virtualbox + Extension Pack (https://www.virtualbox.org/wiki/Downloads)
   Nota: Importante Virtualbox no funciona si tenemos habilitada la característica de windows de Hyper-V, hay que deshabilitarla.
   Nota: La última versión de Vagrant 2.2.6 al momento del curso solo funciona con VirtualBox 5.2.36 (released January 14 2020)
 
 - Vagrant  (https://www.vagrantup.com/downloads.html)

Descarga material necesario

Download Putty
Download Vagrant
- Ficheros de Vagrant para crear la infraestructura
# git clone https://bitbucket.org/mobarrio/zabbix-infraestructure.git

Despliegue y Conectividad

20/12/2020 - NOTA IMPORTANTE

A día de hoy la ultima versión LTS de Zabbix es la versión 5.0, que si esta soportada en CentOS 7 y en la cual se basa todo el curso. Si queréis probar las ultimas funcionalidades de Zabbix, tendréis que instalar CentOS 8 (No recomendado), Oracle Linux 8 o alguna versión de Ubuntu o Debian entre otras.

El motivo de esta aclaración es que dados los cambios recientes que comunico Red Hat sobre descontinuar CentOS 8 a los que se suma que Zabbix no liberara los nuevos releases sobre CentOS 7 os dejo unas alternativas con Oracle Linux 8 que es totalmente compatible con todo el material del curso.
 
En estos momento la ultima release de Zabbix es la 5.2 solo soportada en CentOS 8 que como dije antes se puede instalar para probar pero no esta recomendado para producción. Por este motivo os dejo algunas alternativas para desplegar la infraestructura con Oracle Linux 8 y otra para los que les gusta Ubuntu Server 20.04 en el repositorio de Bitbucket.

Despliegue de la infraestructura

Clonaremos el repositorio desde BitBucket para poder crear la infraestructura.
# git clone https://bitbucket.org/mobarrio/zabbix-infraestructure.git
 - Vagrantfile         <- Vagrantfile con los datos necesarios para el despliegue de la infraestructura. 
 - provisioning.sh     <- Archivo para provisionar las máquinas virtuales.
 - Vagrant-Help.txt    <- Pequeña ayuda con comandos de Vagrant útiles.
 - ResponseTimeCURL.sh <- Script para tomar tiempos de acceso a una WEB
 - update-motd.sh      <- Script para personalizar el MOTD  
Importante: Dentro del Vagrantfile está comentada la definición del plugin para conectarnos a través de un proxy. 
Si este es el caso, descomentamos esas líneas y definimos el proxy correctamente.
Bueno vamos a comenzar con el despliegue. Abrimos una terminal con CMD y nos posicionamos en el directorio donde estén los ficheros.

D:\>cd zabbix-infraestructure
CEV01.png
- Ejecutamos el comando vagrant up para desplegar el entorno del curso.

D:\Temp\Curso-Zabbix-Vagrantfiles>vagrant up
CEV02.png

Configurar la conexión al entorno

Vía Vagrant

C:> vagrant ssh zbxsrv01
C:> vagrant ssh zbxclient01

Vía Putty

Configuramos la conexión con el Zabbix Server
Configuramos la conexión con un Client Linux
Aceptamos la clave
Usuario: root - Password: vagrant

Solución de problemas

Reset de password en PostgreSQL si la perdimos

# sudo -u postgres psql zabbix
> ALTER USER zabbix WITH PASSWORD 'Z4bb1x'; 

Desactivar Hiper-V para utilizar VirtualBox

Opción vía CMD
Abrir un CMD como Administrador
C:> bcdedit /set hypervisorlaunchtype off
The operation completed successfully.
Nota: También tiene que estar activo en la BIOS las opciones de virtualizacion ver: VT-x is disabled

Nota: Para activarlo nuevamente ejecutamos bcdedit /set hypervisorlaunchtype auto

Desactivar la Feature SANDBOX de Windows 10 para poder utilizar VirtualBox

Opción vía Powershell
Desde un PowerShell (Admin)
PS C:\windows\system32> Disable-WindowsOptionalFeature –FeatureName "Containers-DisposableClientVM" -Online
Nota: Para activarlo nuevamente ejecutamos Enable-WindowsOptionalFeature –FeatureName "Containers-DisposableClientVM" -All -Online
Opción vía CMD
Abrir un CMD como Administrador
C:> Dism /online /Disable-Feature /FeatureName:"Containers-DisposableClientVM"
Nota: Para activarlo nuevamente ejecutamos Dism /online /Enable-Feature /FeatureName:"Containers-DisposableClientVM" -All

Un poco de historia y conceptos generales

¿Que es Zabbix?

Zabbix es una herramienta de software pensada para la empresa y diseñada para monitorizar en tiempo real millones de métricas y recolectar datos de decenas de miles de dispositivos como pueden ser:
 Zabbix es Open Source, no tiene coste ni limite de dispositivos a monitorizar, esta desarrollado principalmente en C y utiliza la licencia GNU GPL version 2.

Un poco de historia antes de ponernos a trabajar

ZABBIX es un software que fue desarrollado por Alexei Vladishev en el año 1998 y en el año 2001 fue liberado para el publico después de 3 años en el 2004 se obtuvo la primera versión estable. Ya pasaron mas de 15 años y a día de hoy van por la versión 4.4. Con esto podemos decir que es un software muy maduro.
ZABBIX suele lanzar versiones LTS (Long Term Support) que son todas las terminadas en .0 y versiones intermedias que cuentan con 6 meses de soporte y estas son las versiones .2 y .4. Como comente antes actualmente liberaron la versión 4.4 que es una versión intermedia, se supone que es la anterior a que liberen la versión 5.0 que está prevista para Marzo del 2020.

¿Por qué usar Zabbix?

- Es flexible, permite interactuar con todo tipo de elementos, a los cuales puede monitorizar vía agentes (multi-plataforma), HTTP, SNMP, JMX, IPMI o con custom scripts.

- Es Open Source y sin coste.

- No tiene límites en los elementos a monitorizar.

- Reduce el OPEX (Costos de operación) ya que con la detección pronta de problemas, el escalado de los mismos o la auto resolución de ellos, minimizamos el impacto reduciendo el tiempo de inactividad en entornos críticos.

- El acceso es vía una interfaz es web desarrollada en PHP.

- Podemos visualizar los datos monitorizados en tiempo real.

¿Quienes son los usuarios de Zabbix?

Instalación del servidor de Zabbix

Introducción

ZABBIX es un software modular, se pueden instalar todos sus componentes en un mismo host o por separado. Como vemos en la diapositiva, la solución consta de tres partes principales, el server, el front y la base de datos, adicionalmente tenemos los proxys y los agentes que dan flexibilidad a la monitorizacion ya que incorporan muchas funciones muy útiles.
Arquitectura de Zabbix

Requerimientos de Hardware

Los requerimientos de hardware no son grandes, aunque el mayor impacto es sobre la base de datos. Si procesamos miles de valores por segundo, seguramente necesitaremos buenos discos que puedan soportar la alta carga que esto representa.
Ahora que ya sabemos como esta compuesto ZABBIX, procederemos a instalar los diferentes componentes. Comenzando por la Base de Datos.

Instalación de PostgreSQL y Apache

ZABBIX Soporta diferentes bases de datos como PostgreSQL, MySQL, Oracle, IBM DB2 y SQLite. Particularmente SQLite se utiliza muy a menudo en la configuración de los Proxys. Otro dato importante es que las instalaciones se reparten casi el 99% entre PostgreSQL y MySQL y el 1% restantes en Oracle y DB2.
En este curso nosotros utilizaremos PostgreSQL como motor de base de datos para nuestra instalación. 
Para comenzar, nos conectaremos a la máquina de ZBXSRV01 (IP: 10.0.100.100) via Putty o con Vagrant SSH

# yum install -y httpd
# yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
# yum install -y postgresql11 postgresql11-server

# /usr/pgsql-11/bin/postgresql-11-setup initdb
# vi /var/lib/pgsql/11/data/pg_hba.conf
# TYPE  DATABASE        USER            ADDRESS                 METHOD

local   all             all                                     trust <-- Actualizamos de PEER a TRUST o MD5
host    all             all             127.0.0.1/32            trust
host    all             all             ::1/128                 trust
# systemctl enable postgresql-11
# systemctl start postgresql-11
# systemctl status postgresql-11

Instalación de Zabbix Server

NOTA: Si queremos instalar sobre Ubuntu ver el video: https://youtu.be/i8hVMRa4hO8 y la Documentación: https://www.zabbix-es.com.es/index.php/Instalaci%C3%B3n_de_Zabbix_Server_sobre_Ubuntu#Instalaci.C3.B3n_de_PostgreSQL
- yum install zabbix-server-XXXX - Donde XXXX es la DB a la que utilizará para guardar los datos.

# rpm -Uvh https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm
# yum clean all
# yum install -y zabbix-server-pgsql zabbix-agent
# yum install -y centos-release-scl
# vi /etc/yum.repos.d/zabbix.repo
  [zabbix-frontend]
  ...
  enabled=1
  ...
# yum install -y zabbix-web-pgsql-scl zabbix-apache-conf-scl
# sudo -u postgres createuser --pwprompt zabbix
could not change directory to "/root": Permission denied
Enter password for new role: Z4bb1x 
Enter it again: Z4bb1x 

# sudo -u postgres createdb -O zabbix zabbix
# zcat /usr/share/doc/zabbix-server-pgsql*/create.sql.gz | sudo -u zabbix psql zabbix
Paquetes de SQL necesarios para la instalación de la base de datos
- schema.sql
- images.sql
- data.sql 

Nota: Todos incluidos en create.sql.gz

Conexión con la BBDD desde Zabbix server

Al instalar el zabbix server se auto-configuran los siguientes parámetros de la base de datos.
# vi /etc/zabbix/zabbix_server.conf
DBHost=localhost    <---- IP del servidor donde esta la base de datos
DBName=zabbix       <---- Nombre de la base de datos
DBUser=zabbix       <---- Nombre del Usuario para conectar con la base de datos
DBPassword=Z4bb1x   <---- Contraseña del usuario para conectarnos a la base de datos

Configuracion zona Horaria en Zabbix 5.X

# vi /etc/opt/rh/rh-php72/php-fpm.d/zabbix.conf
php_value[date.timezone] = Europe/Madrid

Arranque de Zabbix Server, Zabbix FE, HTTPD (Apache) y PHP-fpm

# systemctl restart zabbix-server zabbix-agent httpd rh-php72-php-fpm
# systemctl enable zabbix-server zabbix-agent httpd rh-php72-php-fpm
# systemctl status zabbix-server zabbix-agent httpd rh-php72-php-fpm

Configuración del Frontend

Introducción

- Es importante destacar que el Zabbix Frontend ataca directamente a la base de datos con lo cual no necesita que el server esté activo salgo para alguna consulta puntual que solo la puede responder el server como el número de ítems procesados.
Paquetes de SQL necesarios para la instalación de la base de datos
- zabbix-web-XXXX - Donde XXXX es la DB a la que conectara

Configuración de la zona horaria

La infraestructura que utilizamos está configurada con la zona horaria de Europa/Madrid, si vosotros estáis en otra zona horaria, con el comando timedatectl list-timezones podemos ver todas las zonas horarias disponibles y con el comando timedatectl set-timezone podemos actualizarla.
# timedatectl list-timezones
# timedatectl set-timezone Europe/Madrid

Zabbix 5.X

# vi /etc/opt/rh/rh-php72/php-fpm.d/zabbix.conf
php_value[date.timezone] = Europe/Madrid

Zabbix 4.X y anteriores

# vi /etc/httpd/conf.d/zabbix.conf
#
# Zabbix monitoring system php web frontend
#

Alias /zabbix /usr/share/zabbix

<Directory "/usr/share/zabbix">
    Options FollowSymLinks
    AllowOverride None
    Require all granted

    <IfModule mod_php5.c>
        php_value max_execution_time 300
        php_value memory_limit 128M
        php_value post_max_size 16M
        php_value upload_max_filesize 2M
        php_value max_input_time 300
        php_value max_input_vars 10000
        php_value always_populate_raw_post_data -1
        php_value date.timezone Europe/Madrid    <--- Descomentar y actualizar
    </IfModule>
</Directory>

<Directory "/usr/share/zabbix/conf">
    Require all denied
</Directory>

<Directory "/usr/share/zabbix/app">
    Require all denied
</Directory>

<Directory "/usr/share/zabbix/include">
    Require all denied
</Directory>

<Directory "/usr/share/zabbix/local">
    Require all denied
</Directory>

Instalación Gráfica del frontend

En el browser abrir la URL de Zabbix: http://10.0.100.100/zabbix  <-- ATENCION
Parametros de PHP  <-- ATENCION
Una vez instalado el frontend, este conecta directamente contra la base de datos, ya que algunas consultas las realiza sin necesidad de pasar por el Zabbix Server. La configuración de la conexión esta en el fichero /etc/zabbix/web/zabbix.conf.php

# cat /etc/zabbix/web/zabbix.conf.php
<?php
// Zabbix GUI configuration file.
global $DB;

$DB['TYPE']     = 'POSTGRESQL';
$DB['SERVER']   = 'localhost'; <----- IP donde esta la BBDD instalada
$DB['PORT']     = '0';
$DB['DATABASE'] = 'zabbix'; <----- Nombre de la base de datos
$DB['USER']     = 'zabbix'; <----- Nombre del usuario
$DB['PASSWORD'] = 'Z4bb1x'; <----- Contraseña del usuario
$DB['DOUBLE_IEEE754'] = 'true';  <----- Contraseña Nuevo parametro de zabbix 5.X importante cuando actualizamos de versiones anteriores.
// Schema name. Used for IBM DB2 and PostgreSQL.
$DB['SCHEMA'] = ;

$ZBX_SERVER      = 'localhost'; <----- IP del Zabbix Server
$ZBX_SERVER_PORT = '10051';     <----- Puerto en que escucha
$ZBX_SERVER_NAME = 'zbxsrv01';  <----- Nombre del Zabbix Server

$IMAGE_FORMAT_DEFAULT = IMAGE_FORMAT_PNG;

TIP: Re-dirección de la página default

Para evitar que se muestre la pagina de APACHE cuando entramos en Zabbix sin poner la ruta completa en el navegador, creamos una pagina de inicio que nos redirecciona a la ruta por defecto de zabbix.
Es recomendable no modificar el path que trae zabbix por defecto, ya que algunas aplicaciones externas a Zabbix atacan la URL de la API por defecto y si la cambiamos puede que no funciones.

# cat <<EOF >/var/www/html/index.html 
<html>
  <head>
    <title>Zabbix Server</title>
    <meta http-equiv="refresh" content="0; URL=http://10.0.100.100/zabbix">
    <meta name="keywords" content="automatic redirection">
  </head>
  <body></body>
</html>
EOF

Arranque de Zabbix Server, Zabbix FE, HTTPD (Apache) y PHP-fpm

# systemctl restart zabbix-server zabbix-agent httpd rh-php72-php-fpm
# systemctl enable zabbix-server zabbix-agent httpd rh-php72-php-fpm
# systemctl status zabbix-server zabbix-agent httpd rh-php72-php-fpm

El archivo de configuración /etc/zabbix/zabbix_server.conf

Tomamos un Snapshot del Server (CMD Vagrant)

C:\> vagrant snapshot save zbxsrv01 zbxsrv01-snap-0001

Entorno gráfico

Introducción

El entorno gráfico está desarrollado en PHP. Generalmente es lo que más cuesta cuando comenzamos a trabajar con ZABBIX, a pesar de que realmente no es complejo tiende a que nos compliquemos y estemos dando vueltas por el, buscando opciones que no encontramos. 

Es importante destacar que generalmente se puede llegar a la misma información desde diferentes ángulos, eso hacer que parezca más complicado de lo que es.
 
Una de las cosas que también nos suele dar dolores de cabeza es que hay menús dentro de las opciones que están más escondidos y cuando las buscamos no los encontramos. Estas dos cosas suelen frustrar mucho a la gente que comienza con ZABBIX.

Luego de mucho tiempo de utilizarlo, les aseguro que se pasaran gran parte del tiempo entre 2 y 5 opciones de todas las que tiene y el resto las utilizaran más esporádicamente.

Monitoring

Dashboard

En esta opción podemos visualizar información genera del sistema. Podemos personalizar las dashboards o crear nuevas. 
Tenemos un conjunto de widgets predefinidos. En esta Dashboard podemos visualizar algunos de ellos como el widget de System Information, el de clock que muestra el reloj que vemos, el  de host availability, el de problems by severity, o el de problems. Pero también podemos incluir Mapas o gráficos

Problems

A mi parecer esta opción de menú es la mas importante junto con "Latest Data", ya que nos muestra todos los triggers que aparecen en nuestro sistema. 
Si aplicamos los filtros adecuados, fácilmente podemos ver que esta pasando y así monitorizar mucho mejor nuestra plataforma.

Overview

Nos ofrece una visión general del estado de los triggers o realiza una comparación de datos entre varios hosts agregándolos.

Las opciones disponibles son 

  - Seleccionar todos los hosts o un grupo especifico de hosts groups desde la opción de Group dropdown

  - Seleccionar que tipo de información vamos a visualizar. (Triggers o datos) en el Type dropdown
 
  - Seleccionar si la visualización sera horizontal (Left) o vertical (Top) en el Host location dropdown

Web

En esta opción obtenemos información de los WEB scenarios.  Ya explicaremos mas adelante que son los web scenarios y para que los utilizamos.
Los hosts que están des-habilitados aparecerán en rojo.

Latest Data

Esta opción es muy utilizada, ya que podemos ver los últimos valores recolectados por los items y también acceder a gráficos o datos históricos.

Si algun ítem esta fallando, también nos dará información de porque falla y así poder solventar el problema.

Graphs

En esta sección podemos visualizar gráficos personalizados para los items que estamos recolectando.

Screens

En esta sección podemos configurar, administrar y visualizar los screens globales y los slide shows. Así como asignar los permisos de quien puede o no visualizarlos.

Esencialmente en un screen podemos agrupar información de diferentes fuentes para visualizarla rápidamente. Crear screen no es complicado y suele ser bastante intuitivo. El screen es una tabla y en cada fila o columna podemos definir elementos predefinidos que queremos que se visualicen.

Los Slides Shows son una agrupación de screens que se visualizarán en pantalla con una duración determinada.
NOTA:A nivel de Dashbords, Screens y Gráficos en general, Zabbix esta realizando un esfuerzo grande en mejorar, cada año hay nuevas mejoras en estos puntos. Así y todo, es muy recomendable a día de hoy potenciar Zabbix con Grafana que es una herramienta pensada para esto. La visualización de los datos es mucho mas profesional y tiene una gama de plugins que potencia muchísimo esta parte.

Maps

En esta sección podemos ver, configurar y administrar mapas de red. Agrupar diferentes componentes de nuestra infraestructura y ver como se están comportando. Un Mapa puede ser incorporado dentro de un Screen.
En el Zabbix Summit 2019, pudimos ver una mapa de red creado por la empresa NTT COM Solutions en 3D, insertado dentro de un Screen que mostraba una infraestructura de comunicaciones en tiempo real, con el trafico entre los nodos que realmente era impresionante.

NTT COM Solutions

Discovery

En esta sección podemos visualizar el resultado de los discoverys realizados. Los mismos son ordenados por las reglas de discovery.
 Si no aplicamos ningún filtro, se visualizaran todos los discoverys habilitados. 

Los discoverys los utilizamos para descubrir maquinas o elementos aplicando diferentes patrones o chequeos. El que trae zabbix por default busca en un rango de red especifico las maquinas que tengan un agente de zabbix instalado.

Services

Esta sección vemos el estatus de la infraestructura o de los servicios de negocio. 

La idea es poder obtener una visión de mas alto nivel (negocio) de la infraestructura que monitorizamos. 

A nivel de negocio no suele interesar el detalle de que host esta generando problemas o que componente esta mal, sino si este afecta o no la disponibilidad del servicio, lo que comúnmente llamamos SLA.

Inventory

Inventario: Esta opción es muy poco utilizada, Por defecto esta desactivada, pero no se pude 
configurar de forma Manual o Automática. Como en nombre lo dice recolecta información y de los hosts y la 
almacena dentro del inventario de ZABBIX.

Overview

Podemos visualizar por agrupaciones de campos del inventario.

Hosts

Visualizamos todos los hosts con su información inventariada y podemos filtrarlos por los campos del inventario.
- General para todo el sistema
Administration -> General -> Other -> Inventory
- Particular para un host
Configuration -> Host -> Inventory
Manual: Lo tenemos que cargar nosotros manualmente.
Automático: Utiliza la información que recolecta de agentes para popular el dato automáticamente 
dentro del inventario. 
Cuando definimos Templates, podemos decirle que el item recolectado sea populado dentro del inventario. 
Para esto seleccionamos 
el item y vamos al campo "Populates host inventory field" ahi seleccionamos con que campo vamos a 
realizar el macheo o emparejamiento y de esta forma cuando recolecte la informacion automaticamente 
populara la información dentro del inventario.
Nota: Los campos dentro del inventario son un poco genéricos y en general poco útiles, podemos ajustar los nombres del inventario a algunos que sean mas representativos para nosotros
FILE: /usr/share/zabbix/include/hosts.inc.php --> $inventoryFields array donde podemos cambiar los nombres de los campos.

Reports

System information

Availability report

Triggers top 100

Audit

Action log

Notifications

Configuration

Host groups

Templates

Hosts

Maintenance

Actions

Event correlation

En esta sección los usuarios pueden configurar y mantener las reglas de correlación de los eventos de zabbix.

La correlación de eventos nos permite enfocarnos en la causa raíz del problema y se basa en los TAGS que definimos en los triggers. 

Por ejemplo si tenemos una caída de un switch, tendríamos muchos hosts informando por errores de conectividad, con la correlación de eventos podemos determinar que estos errores son producidos por la caída del switch y de esta forma nos centramos solamente en ese problema, ya que el resto se solventara cuando este este OK nuevamente.

Discovery

Services

Administration

General

Proxies

Authentication

User groups

Users

Media types

Scripts

[FALTA TERMINAR]
Es el módulo para administrar y mantener el registro de los scripts globales del sistema.

Los script pueden ayudarnos a ejecutar acciones sobre un HOST ya que se pueden invocar desde diferentes partes de la interfaz web: Dashboards, Latest data, Triggers, Eventos o Mapas, tambien pueden ser invocados desde las acciones. De esta forma podemos hacer que dependiendo de una condición predeterminada se ejecute una accion. 

TRABAJAR MÁS: Por ejemplo si se detecta un fichero en el server, ejecutamos una actualización de la aplicación.

Estos scripts se pueden ejecutar en el Zabbix Server, en el Zabbix Proxy o en los Zabbix Agents.

Queue

Que es un Hosts, una Macros y Host groups

Introducción

Host: Es el dispositivo que queremos monitorizar. Para poder crear un HOST necesitamos como mínimo definir un grupo de atributos, como un Nombre, asignarlo a un grupo y definir al menos una interfaz.

      El tipo de interfaz dependera de como queramos monitorizar el Host y los disponibles son con un Agente de Zabbix, vía SNMP, JMX o IPMI. 

     En el siguiente capítulo instalaremos y configuraremos un Zabbix Agent para monitorizar un Host Linux. 
Templates: Aquí enlazamos los templates (plantillas) que este host tendrá. Ya veremos más adelante que son las plantillas y cómo crear una desde cero.
IPMI: Definiciones para la conexión vía IPMP como Autenticación, Privilegios Usuario y Password.
Tags: Aquí definimos Tags para el Host en cuestión. Un Tag es una etiqueta que luego podremos utilizar para realizar diferentes acciones como filtrado de problemas por tag, correlación de eventos por tags, etc.
Macros: Aquí definimos las Macros a nivel de Host que podemos utilizar. La macro no es más que una variable donde almacenamos información que luego utilizaremos. A continuación hablaremos un poco más en detalle sobre las Macros, que tipos hay y donde se definen.
Inventory: Definimos como trabajara el Host con el inventario.
Encryption: Definimos los parámetros de encriptación con los que el Zabbix Agent se conectara con el Zabbix Server.

Macros

Hay macros de sistema que ya están definidas, macros que se definen y utilizan en los Low Level Discovery y las de Usuario que podemos crear nosotros. Dependiendo del tipo de Macro que sea, tienen un formato diferente:

  {MACRO}  Macro del sistema, se pueden utilizar en funciones, triggers, etc. Sistema

  {#MACRO} Macros de LLD (low-level discovery) Se definen y utilizan en los Low-Level Discoverys LDD Macros

  {$MACRO} Macros de Usuario. Estas las definimos nosotros a nivel de Host, Template o Zabbix Server. Usuario
Las MACROS de Usuario se pueden definir dentro de los Hosts, en los templates o a nivel general de Zabbix Server. Dependiendo de donde se definan unas tienen precedencia sobre las otras.

- MACROS Generales:    Son las de nivel más alto y se definen en Administration > General > Macros

- MACROS de Templates: Son las de nivel intermedio, se definen dentro del Template. Ya lo veremos en el próximo capítulo.

- MACROS de Host:      Son las de nivel más bajo y se definen dentro del Host. 
Ejemplo: Si definimos la macro {$SNMP_COMMUNITY} a nivel de host, en el template y de forma general. Zabbix utilizara la del Host primero, si esta no existe, utilizara la del template y sino la General.

Host Groups

Los host groups son una agrupación lógica de hosts. Luego se podrán utilizar en distintas opciones para agrupar o filtrar por ellos.

Creación de un Host e Instalación del Agente

Introducción

Los Agentes de Zabbix están desarrollados en C++ y una de las mejores cosas que tienen es que el bajo footprint, esto quiere decir que la carga que generan en el sistema es muy baja. Actualmente está en desarrollo una versión 2 del Agente, desarrollada en Go y se espera sea lanzada con Zabbix 5. Los agentes mantienen compatibilidad hacia atrás, es decir podemos utilizar agentes antiguos con versiones de Zabbix más modernas. El problema de esto es que no contaremos con las últimas funciones implementadas en ellos.
Antes de instalar el agente comentaremos los diferentes modos de trabajar que el agente nos ofrece.

Modos en que trabajan los agentes e Instalación

Pasivo (pull)
El agente Pasivo (PULL) es el más común, está instalado en el host, escucha en el puerto 10050 y espera a que el server de Zabbix le solicite algo, cuando llega la petición, la resuelve y contesta el resultado.

 La mayor parte de los templates tienen sus ítems configurados con Agente Pasivo. En este modo es el server quien solicita al agente la información. 
Para que funcione correctamente, el agente tiene que apuntar al servidor de Zabbix opción Server= de su archivo de configuración.
Activo (push)
El agente Activo (PUSH), al iniciarse solicita al Zabbix Server que está escuchando en el puerto 10051 que tiene que monitorizar, el server le responde y a partir de este momento es totalmente autónomo, enviará la información por su cuenta cada X tiempo, por defecto son 120s, esto se puede modificar con la opción RefreshActiveChecks= del archivo de configuración del agente. 

Configurar un ítem como agente activo es mucho mejor de cara al rendimiento del server ya que lo descarga de la responsabilidad de estar solicitando la información a todos los clientes periódicamente ya que son ellos los que la reportan.

Otro punto importante es que para configurar el agente en modo activo, es necesario definir explícitamente el Hostname, si este no existe en el server de zabbix exactamente con el mismo nombre, este no será capaz de enviar la información de lo que tiene que monitorizar, si el Hostname no existe intentara con el HostnameItem y si este tampoco existe por default utiliza system.hostname (que es un hostname -a).

También es importante configurar cual es el server que escucha en modo activo y esto se realiza ajustando la opción ServerActive= en el archivo de configuración del agente.

Hay diferentes funciones según se configure el agente (Activo/Pasivo), por ejemplo si queremos analizar un log, en busca de un error y reportarlo si lo encuentra, este ítem se tiene que configurar como Agente Activo.
Nota: Los problemas generales de comunicación entre agente y server suelen ser por: Firewall, SELinux, o mala definición entre el nombre del host y el definido en el zabbix server, este último se soluciona fácilmente si utilizamos el Auto-discovery.
Nota: Si el agente está configurado en modo Activo y queremos que vuelva a solicitar la información al server sin esperar el tiempo pre configurado, simplemente tenemos que reiniciar el agente.
Nota: Comentar los UserParameters que extienden la funcionalidad del agente.

Instalación del Agente

# rpm -Uvh https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm
# yum clean all
# yum install -y zabbix-agent
# systemctl enable zabbix-agent

Creamos un SNAP de zbxclient01 (CMD VAGRANT)

C:\> vagrant snapshot save zbxclient01  zbxclient01-snap-0001

Laboratorio 1: Configuración Manual del Zabbix Agente

[root@zbxclient01 ~]# cat <<EOF >/etc/zabbix/zabbix_agentd.conf
PidFile=/var/run/zabbix/zabbix_agentd.pid
LogFile=/var/log/zabbix/zabbix_agentd.log
LogFileSize=3
Server=10.0.100.100,127.0.0.1
ServerActive=10.0.100.100
Hostname=zbxclient01
Include=/etc/zabbix/zabbix_agentd.d/*.conf
EOF

[root@zbxclient01 ~]# systemctl restart zabbix-agent.service

[root@zbxclient01 ~]# tail -f /var/log/zabbix/zabbix_agentd.log 
 12294:20200122:191707.380 TLS support:           YES
 12294:20200122:191707.380 **************************
 12294:20200122:191707.380 using configuration file: /etc/zabbix/zabbix_agentd.conf
 12294:20200122:191707.381 agent #0 started [main process]
 12295:20200122:191707.381 agent #1 started [collector]
 12296:20200122:191707.381 agent #2 started [listener #1]
 12299:20200122:191707.381 agent #5 started [active checks #1]
 12297:20200122:191707.382 agent #3 started [listener #2]
 12298:20200122:191707.384 agent #4 started [listener #3]
 12299:20200122:191707.438 no active checks on server [10.0.100.100:10051]: host [zbxclient01] not found
 Creación manual del Host
CONFIGURATION > HOSTS > CREATE HOST
Host name             : zbxclient01
Groups                : Linux servers
Agent interfaces      : 
   IP Address         : 10.0.100.101
   Connect to         : IP
   Port               : 10050
Configuramos Nombre e IP del Agente
Verificamos si el Agente de zbxclient01 ya puede conectar
[root@zbxclient01 ~]# systemctl restart zabbix-agent.service

[root@zbxclient01 ~]# tail -f /var/log/zabbix/zabbix_agentd.log 
12325:20200122:192415.833 IPv6 support:          YES
12325:20200122:192415.833 TLS support:           YES
12325:20200122:192415.833 **************************
12325:20200122:192415.833 using configuration file: /etc/zabbix/zabbix_agentd.conf
12325:20200122:192415.833 agent #0 started [main process]
12326:20200122:192415.833 agent #1 started [collector]
12327:20200122:192415.833 agent #2 started [listener #1]
12329:20200122:192415.834 agent #4 started [listener #3]
12328:20200122:192415.835 agent #3 started [listener #2]
12330:20200122:192415.836 agent #5 started [active checks #1]
Nota: Como vemos ya no sale el mensaje de HOST NOT FOUND

Laboratorio 2: Configuración Automática del Zabbix Agente

Antes de ponernos a configurar un Agente, vamos a ver una de las funcionalidades que tiene Zabbix que realmente nos ayuda muchísimo con la gestión de los Agentes.

Que es la Auto-registracion

Esta funcionalidad de Auto Registration, en realidad es una acción que se ejecuta cuando un cliente arranca, en el momento informa al server de que está vivo y le pasa información como el nombre, la ip y entre otros datos el HostMetadata que es lo que utilizaremos para configurar la acción de auto-registracion. 
El HostMetadata no es más que un string de 0-255 caracteres en formato UTF-8. Con lo cual puede ser cualquier tipo de texto, particularmente a mi me gusta usar un hash de tipo MD5 que es único. 
Antes que nada eliminamos el HOST: zbxclient01 que creamos manualmente
CONFIGURATION > HOSTS > Eliminamos zbxclient01
Generación del HASH de Auto-Registración 

[root@zbxsrv01 ~]# echo zabbix2020| md5sum    
97d7c2030d2ccf29f059f4c24a8c0796  -

Este hash 97d7c2030d2ccf29f059f4c24a8c0796 lo utilizaremos tanto en la configuración del zabbix Client para que el lo informe al Zabbix Server y en el Zabbix Server para crear la Acción de Auto Registración.
Desde el Zabbix Frontend crearemos una nueva acción de tipo Auto Registración
CONFIGURATION > ACTIONS > EVENT SOURCE: Auto Registration -> CREATE ACTION
Creamos una nueva acción de tipo Auto-Registration
Name           : Auto-Registration Linux
New condition  : Host metadata - contains - 97d7c2030d2ccf29f059f4c24a8c0796
CAAR05.png
Operations     :
   Details     : Add to host groups: Discovered hosts
   Details     : Link to templates: Template Module ICMP Ping
                       Link to templates: Template OS Linux by Zabbix Agent
   Details     : Set host inventory mode: Automatic
CAAR06.png
Forzamos al server a que relea la configuración
[root@zbxsrv01 ~]# zabbix_server -R config_cache_reload

Configuración en el lado del Zabbix Agent

# cat <<EOF >/etc/zabbix/zabbix_agentd.conf
PidFile=/var/run/zabbix/zabbix_agentd.pid
LogFile=/var/log/zabbix/zabbix_agentd.log
LogFileSize=3
Server=10.0.100.100,127.0.0.1
ServerActive=10.0.100.100
Hostname=zbxclient01
HostMetadata=97d7c2030d2ccf29f059f4c24a8c0796
Include=/etc/zabbix/zabbix_agentd.d/*.conf
EOF

# systemctl start zabbix-agent.service

Creamos un SNAP de zbxclient01 y zbxsrv01 (CMD VAGRANT)

C:\> vagrant snapshot save zbxclient01 zbxclient01-auto-registration-snap-0002
C:\> vagrant snapshot save zbxsrv01 zbxsrv01-auto-registration-snap-0002

Laboratorio 3: UserParameters

Introduccion

Algunas veces queremos extender las funcionalidades del agente con chequeos que no esta predefinidos en el propio agente. Para esto tenemos los User Parameters. Estos parámetros se cargan vía la configuración del agente al momento del arranque del mismo.

Hay varias opciones en la configuración del agente que afectan al funcionamiento de la ejecución de los mismos como AllowRoot, UserParameter e Include.
AllowRoot Permite que el agente se ejecute como ROOT, por defecto esta desactivado y el agente se ejecuta con el usuario zabbix.

UserParameter Definición del parámetro.

Include Incluye ficheros individuales o todos los ficheros en un directorio.
Los userparameters se pueden definir directamente en el archivo de configuración del zabbix_agent.conf o podemos crear fichero agrupando userparameters según funcionalidades.
Se recomienda hacer esto último, es decir crear diferentes ficheros dentro del directorio /etc/zabbix/zabbix_agentd.d/ e incluirlos todos via la sentencia include.

Preparamos el Agente para que cargue los parametros nuevos UserParameters

# cat <<EOF >/etc/zabbix/zabbix_agentd.conf
LogFile=/var/log/zabbix/zabbix_agentd.log
LogFileSize=0
Server=10.0.100.100,127.0.0.1   <--- Importante Localhost para poder conectarlos localmente con zabbix_get
ServerActive=10.0.100.100
Hostname=zbxclient01
HostMetadata=97d7c2030d2ccf29f059f4c24a8c0796
Include=/etc/zabbix/zabbix_agentd.d/*.conf
EOF
[root@zbxclient01 ~]# systemctl restart zabbix-agent.service 
[root@zbxclient01 ~]# systemctl status zabbix-agent.service

La estructura del fichero de Parámetros

La estructura
UserParameter=<clave>,<comando>
Clave   : Es un identificador único. Puede contener parámetros lo que flexibiliza los mismos. Para que acepte parámetros, creamos la clave y seguidamente incluimos [*]. Cada parámetro se pasará desde el Zabbix Server separado por comas y se utilizan dentro del comando reemplazandolos por las macros $1..$9.

Comando : Es el comando que el zabbix agent ejecutará.
Este ejemplo crea un parámetro llamado clustat que utilizaremos más adelante.

[root@zbxclient01]# cat <<EOF >/etc/zabbix/zabbix_agentd.d/userparameter_clustat.conf
UserParameter=clustat[*],echo \$1
EOF
El Zabbix Agent ejecutaría el parámetro anterior de la siguiente forma

Definición: UserParameter=clustat[*],echo $1
Llamada   : clustat["Hola mundo"]
Ejecución : echo "Hola Mundo"
Retorno   : Hola Mundo
Este ejemplo monitoriza el estado de los Sockets en un Linux

[root@zbxclient01]# cat <<EOF >/etc/zabbix/zabbix_agentd.d/userparameter_sockstat.conf
UserParameter=sockstat.sockets,cat /proc/net/sockstat|grep sockets|cut -d' ' -f 3
UserParameter=sockstat.tcp.inuse,cat /proc/net/sockstat|grep TCP|cut -d' ' -f 3
UserParameter=sockstat.tcp.orphan,cat /proc/net/sockstat|grep TCP|cut -d' ' -f 5
UserParameter=sockstat.tcp.timewait,cat /proc/net/sockstat|grep TCP|cut -d' ' -f 7
UserParameter=sockstat.tcp.allocated,cat /proc/net/sockstat|grep TCP|cut -d' ' -f 9
UserParameter=sockstat.tcp.mem,cat /proc/net/sockstat|grep TCP|cut -d' ' -f 11
UserParameter=sockstat.udp.inuse,cat /proc/net/sockstat|grep UDP:|cut -d' ' -f 3
UserParameter=sockstat.udp.mem,cat /proc/net/sockstat|grep UDP:|cut -d' ' -f 5
EOF
Este ejemplo monitoriza diferentes opciones como el numero de ficheros abiertos, el numero de procesos, el estado de servicios o el estado del servicio de NTP

[root@zbxclient01]# cat <<EOF >/etc/zabbix/zabbix_agentd.d/userparameter_general.conf
UserParameter=linux.openfiles,/usr/sbin/lsof | /usr/bin/wc -l
UserParameter=linux.process,/usr/bin/ps -ef | /usr/bin/wc -l
UserParameter=linux.service.status[*],/usr/bin/systemctl is-active \$1 -q ; echo '{"status":'\$?'}'
UserParameter=linux.ntp.status,(([ -x /usr/bin/chronyc ] && /usr/bin/chronyc tracking | egrep -ic "Leap status.*Normal") || ([ -x /usr/sbin/ntpq ] && /usr/sbin/ntpq -pn 2>/dev/null | egrep -c "^\*") || echo 0 )
EOF
Reiniciamos el zabbix_agent para que relea los userparameters.

[root@zbxclient01]# systemctl restart zabbix-agent.service
[root@zbxclient01]# systemctl status zabbix-agent.service

Test

[root@zbxclient01 ~]# yum install -y zabbix-get <- El zabbix_get nos permitirá simular una petición al agente vía línea de comandos.

[root@zbxclient01 ~]# zabbix_get -s 127.0.0.1 -k clustat[3]

[root@zbxclient01 ~]# zabbix_get -s 127.0.0.1 -k clustat["Hola Mundo"]

[root@zbxclient01 ~]# zabbix_get -s 127.0.0.1 -k clustat["Hola","Mundo"] <- $1: Hola, $2: Mundo

[root@zbxclient01 ~]# zabbix_get -s 127.0.0.1 -k linux.process
   Comando a ejecutar: /usr/bin/ps -ef | /usr/bin/wc -l

[root@zbxclient01 ~]# zabbix_get -s 127.0.0.1 -k linux.openfiles
   Comando a ejecutar: /usr/sbin/lsof | /usr/bin/wc -l

Laboratorio 4: Configuración del Agente con Encripción

Generación de clave PSK

# mkdir -p /etc/zabbix/ssl/keys
# openssl rand -hex 32 >/etc/zabbix/ssl/keys/zabbix_psk
# cat /etc/zabbix/ssl/keys/zabbix_psk

Preparamos el Agente para que se comunique con el server

# vi /etc/zabbix/zabbix_agentd.conf
PidFile=/var/run/zabbix/zabbix_agentd.pid
LogFile=/var/log/zabbix/zabbix_agentd.log
LogFileSize=3
Server=10.0.100.100,127.0.0.1   <--- Importante Localhost para poder conectarlos localmente con zabbix_get y probar la Encripción
ServerActive=10.0.100.100
Hostname=zbxclient01
HostMetadata=97d7c2030d2ccf29f059f4c24a8c0796
Include=/etc/zabbix/zabbix_agentd.d/*.conf

TLSConnect=psk                     <--- Como conecta el agente con el Zabbix Server. 
TLSAccept=unencrypted,psk          <--- Que tipo de conecciones se aceptan desde el Zabbix server.
TLSPSKIdentity=Zabbix2020
TLSPSKFile=/etc/zabbix/ssl/keys/zabbix_psk
# systemctl restart zabbix-agent.service

La encripción que utilizara el server para conectarse con el Agente/Proxy

CONFIGURATION > HOSTS > ZBXCLIENT01 > Encryption
Connections to host    : PSK
Connections from host  : PSK
PSK identity           : Zabbix2020
PSK                    : 79da666f7eab34055953b3ee48f58a5486fda5a6e8c286452752824c63386c79

Hacemos click en UPDATE
Configuración en el Zabbix Server
Estado del cliente con la encripcion activa

Test

# yum install -y zabbix-get
# zabbix_get -s 127.0.0.1 -k agent.ping --tls-connect psk --tls-psk-identity Zabbix2020 --tls-psk-file /etc/zabbix/ssl/keys/zabbix_psk

El archivo de configuración /etc/zabbix/zabbix_agent.conf

Instalación de Zabbix Proxy

Introducción

El Zabbix Proxy nos permite escalar horizontalmente la recolección de datos y volcarlos al Zabbix server. Esto nos ayuda mucho cuando tenemos puntos de recolección remotos con muy mala latencia y/o cortes, redes aisladas o lineas de datos con un ancho de banda limitado.
El proxy nos permite recolectar los datos localmente y enviarlo al server periódicamente, si hay un corte en la comunicación con el Zabbix Server, este sigue recolectando la información y cuando vuelve a tener conexión envía los datos acumulados. 
El proxy cuenta con la funcionalidad de compresión, lo que nos ayuda con las líneas de datos con ancho de banda limitado.
También cuenta con la funcionalidad de encriptación lo que nos permite conectar los proxys con el server a través de lineas no seguras.
Al recolectar datos en local, es un único punto de interconexión con el server, si en la infraestructura remota tenemos cientos de equipos, solo interconectamos el Zabbix proxy con el Zabbix Server ya que los agentes se conectaran a través de él.

Modos en que trabaja el proxy e Instalación

Configuración del Proxy Pasivo

Es el Zabbix Server quien se ocupa de solicitar la información al proxy de forma periódica.
Parámetro importante del Zabbix proxy
  ProxyMode - Se tiene que configurar a 1 (passive)
Parámetros importantes del Zabbix server
  StartProxyPollers - Controla cuantos pollers contactan con el proxy.
  ProxyConfigFrequency - Cuán a menudo Zabbix server envía los cambios de configuración al proxy.
  ProxyDataFrequency – Cuán a menudo son requeridos los datos.

Configuración del Proxy Activo

Es el propio proxy quien enviará la información al Zabbix Server. Por defecto esta es la configuración predeterminada.
ProxyMode - Se tiene que configurar a 0 (active) MODO POR DEFECTO
Hostname - Debe coincidir con el nombre del proxy configurado en el frontend.
ProxyOfflineBuffer - Controla cuánto tiempo los datos son almacenados localmente si el proxy no puede contactar con el Server (1H por defecto)
ProxyLocalBuffer - Permite preservar los datos en la base de datos del proxy para ser procesada más tarde.
ConfigFrequency - Controla cuán a menudo el proxy solicita al su configuración al Zabbix server.
DataSenderFrequency - Controla cuán a menudo son enviados los datos recolectados al Zabbix server.
HeartbeatFrequency - Establece cuán a menudo el proxy contactara con el server aunque no tenga nuevos datos que transmitir.

TIPs

TIP 1: Si se poner un delay antes de enviar la información por ejemplo cada 5s, permite que se acumule la información y la envié toda junta al server.

TIP 2: El Proxy solo recolecta datos no verifica triggers.

TIP 3: Se calcula que hasta 500 NVPS una base de datos SQLite lo puede soportar. Si es mas, ya tendremos que pensar en un MySQL o PostgreSQL.

TIP 4: También se puede utilizar con SQLite DB en Memoria.

TIP 5: Es muy importante que el Zabbix Proxy tenga la misma versión que el Zabbix Server.

TIP 6: Si estamos pensando en contratar el soporte directamente con Zabbix, ellos cobran por cara Server y Proxy que tengamos instalados.

A continuación realizaremos 2 laboratorios:

- El primero será la configuración de un Zabbix Proxy contra el Zabbix Server y de un cliente a través de el.

- El segundo será configurar la encripción entre el Zabbix Proxy y el Zabbix Server.
Pero antes vamos a sanear la infraestructura para evitar arrastrar errores.

Preparamos los Laboratorios

Vamos a quitar la configuración de encripcion del Zabbix Client y del Zabbix FrontEnd

En zbxclient01 comentamos las lineas de TLS
[root@zbxclient01]# vi /etc/zabbix/zabbix_agentd.conf                                                    
PidFile=/var/run/zabbix/zabbix_agentd.pid
LogFile=/var/log/zabbix/zabbix_agentd.log
LogFileSize=3
Server=10.0.100.100,127.0.0.1
ServerActive=10.0.100.100
Hostname=zbxclient01
HostMetadata=97d7c2030d2ccf29f059f4c24a8c0796
Include=/etc/zabbix/zabbix_agentd.d/*.conf

#TLSConnect=psk
#TLSAccept=unencrypted,psk
#TLSPSKIdentity=OpenWebinars
#TLSPSKFile=/etc/zabbix/ssl/keys/zabbix_psk
[root@zbxclient01]# systemctl restart zabbix-agent.service 
En Zabbix FrontEnd modificamos los parámetros de Encripcion
CONFIGURATION > HOSTS > ZBXCLIENT01 > Encryption
Connections to host  : No encryption
Connections from host: No encryption

Como comente anteriormente, en el primer laboratorio vamos a vamos a instalar y configurar una maquina que sera nuestro proxy (zbxprxy01) y un cliente (zbxclient01) el cual lo monitorizaremos vía el proxy.

Como podemos ver en este MAPY, el proxy se comunicara con el Server y el cliente lo realizará vía el proxy.
MAPY de Infraestructura escenario 2

Instalación de Zabbix Proxy

Nota: Se puede elegir el soporte de la base de datos a utilizar por el proxy entre MySQL, PostgreSQL o SQLITE3.

zabbix-proxy-mysql    <-- Con soporte para MySQL
zabbix-proxy-pgsql    <-- Con soporte para PGSQL
zabbix-proxy-sqlite3  <-- Con soporte para SQLITE3
[root@zbxprxy01 ~]# rpm -Uvh https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm
[root@zbxprxy01 ~]# yum clean all
[root@zbxprxy01 ~]# yum install -y zabbix-proxy-sqlite3 zabbix-agent
Importamos el esquema inicial de la base de datos
[root@zbxprxy01 ~]# mkdir -p /var/zabbix/database
[root@zbxprxy01 ~]# zcat /usr/share/doc/zabbix-proxy-sqlite3*/schema.sql.gz | sqlite3 /var/zabbix/database/zabbix.db
[root@zbxprxy01 ~]# chown -R zabbix:zabbix /var/zabbix

Laboratorio 1: Configuración básica del Zabbix Proxy

Configuración del lado del Zabbix Proxy

[root@zbxprxy01 ~]# vi /etc/zabbix/zabbix_proxy.conf 
Server=10.0.100.100
Hostname=zbxprxy01
LogFile=/var/log/zabbix/zabbix_proxy.log
LogFileSize=0
PidFile=/var/run/zabbix/zabbix_proxy.pid
SocketDir=/var/run/zabbix
DBName=/var/zabbix/database/zabbix.db
DBUser=zabbix
SNMPTrapperFile=/var/log/snmptrap/snmptrap.log
Timeout=4
ExternalScripts=/usr/lib/zabbix/externalscripts
LogSlowQueries=3000
StatsAllowedIP=127.0.0.1
[root@zbxprxy01 ~]# systemctl enable zabbix-proxy.service 
[root@zbxprxy01 ~]# systemctl start zabbix-proxy.service
[root@zbxprxy01 ~]# systemctl status zabbix-proxy.service

Generamos un Snapshot desde (CMD Vagrant)

C:\> vagrant snapshot save zbxprxy01 zbxprxy01-snap-0001

Configuración del lado del Frontend

Creamos el proxy en Zabbix Server.
ADMINISTRATION -> PROXIES -> CREATE PROXY
Proxies
Proxy name          : zbxprxy01 <- Muy importante que tenga el mismo nombre
Proxy mode          : Active
Proxy address       : 10.0.100.102
Description         : Descripción de Zabbix Proxy
Creación Zabbix Proxy en el FrontEnd
Configuración Zabbix Proxy en el FrontEnd
Estado Zabbix Proxy en el FrontEnd
[root@zbxsrv01]# zabbix_server -R config_cache_reload
[root@zbxprxy01]# systemctl restart zabbix-proxy.service
Estado Zabbix Proxy en el FrontEnd

Configuración del Zabbix Agent Local al Zabbix Proxy

[root@zbxprxy01 ~]# vi /etc/zabbix/zabbix_agentd.conf
PidFile=/var/run/zabbix/zabbix_agentd.pid
LogFile=/var/log/zabbix/zabbix_agentd.log
LogFileSize=0
Server=127.0.0.1
ServerActive=127.0.0.1
Hostname=zbxprxy01
HostMetadata=97d7c2030d2ccf29f059f4c24a8c0796
Include=/etc/zabbix/zabbix_agentd.d/*.conf
[root@zbxprxy01 ~]# systemctl enable zabbix-agent.service 
[root@zbxprxy01 ~]# systemctl start zabbix-agent.service
[root@zbxprxy01 ~]# systemctl status zabbix-agent.service
Comprobaciones en el Frontend
Verificamos que el Host zbxprxy01 se conecta al Zabbix Server via el mismo.
Agentes conectados al Zabbix Proxy
Verificamos que el Host zbxprxy01 existe y se registro vía Auto-registracion
Nuevo Host registrado via Auto-registracion

Configuración de un Zabbix Agent remoto contra el Zabbix Proxy

Reconfiguramos el Zabbix Agent del ZBXCLIENT01 para que acceda via proxy
[root@zbxclient01 ~]# systemctl stop zabbix-agent.service
[root@zbxclient01 ~]# vi /etc/zabbix/zabbix_agentd.conf
PidFile=/var/run/zabbix/zabbix_agentd.pid
LogFile=/var/log/zabbix/zabbix_agentd.log
LogFileSize=0
Server=10.0.100.102
ServerActive=10.0.100.102
Hostname=zbxclient01
HostMetadata=97d7c2030d2ccf29f059f4c24a8c0796
Include=/etc/zabbix/zabbix_agentd.d/*.conf
Eliminamos el zbxclient01 del Zabbix Frontend
CONFIGURATION > HOSTS > ZBXCLIENT01 > Delete
Arrancamos el Agente
[root@zbxclient01 ~]# systemctl start zabbix-agent.service
[root@zbxclient01 ~]# systemctl status zabbix-agent.service
Comprobaciones en el Frontend
Verificamos que el Host zbxclient01 se conecta al Zabbix Server via el zbxprxy01.
Agentes conectados al Zabbix Proxy
Verificamos que el Host zbxclient01 se autoregistro y se monitoriza vía el Proxy.
Nuevo Host registrado via Auto-registracion
Si vemos que los agentes no se ponen en VERDE reiniciamos el Zabbix Proxy
[root@zbxprxy01 ~]# systemctl restart zabbix-proxy.service
Nota: Esto fuerza a que el proxy solicite los chequeos a realizar al Zabbix Server y envíe todos los datos que tiene acumulados.
Agentes ONLINE conectados al Zabbix Proxy

Laboratorio 2: Configuración avanzada del Zabbix Proxy con Encripción

En este laboratorio vamos a reconfigurar el proxy que tenemos instalado para que se comunique de forma encriptada con el Zabbix Server. 
MAPY de Conexión Encriptada entre ZBXPRXY01 y ZBXServer01

Generación de clave PSK utilizadas entre zabbix-server y zabbix-proxy

El primer paso sera crear la clave PSK que utilizaremos para encriptar la comunicación.
[root@zbxprxy01 ~]# mkdir -p /etc/zabbix/ssl/keys
[root@zbxprxy01 ~]# openssl rand -hex 32 >/etc/zabbix/ssl/keys/zabbix_proxy_psk
[root@zbxprxy01 ~]# cat /etc/zabbix/ssl/keys/zabbix_proxy_psk
174ca9394c1ebd45d099eb4f93861c140fff7d103d55b15a435714da50995ef1

Configuración básica del zabbix proxy

[root@zbxprxy01 ~]# vi /etc/zabbix/zabbix_proxy.conf
TLSConnect=psk            # Como debe conectarse el proxy al Zabbix server.
                          # Se utiliza en PROXY Activo, en Proxy Pasivo es ignorada. 
TLSAccept=psk             # Que tipo de conexiones entrantes acepta desde el Zabbix server. 
                          # Solo se utiliza para modo pasivo, es ignorada en modo Activo.
TLSPSKIdentity=ZabbixProxy2020
TLSPSKFile=/etc/zabbix/ssl/keys/zabbix_proxy_psk

Configuración en el Frontend

Configuramos los parámetros de encriptación el proxy dentro del Zabbix Frontend.
ADMINISTRATION -> PROXIES -> zbxprxy01
Proxy                  :
   Proxy Name          : zbxprxy01
   Proxy mode          : Active
   Proxy address       : 10.0.100.102
   Description         : Descripcion del Zabbix Proxy
Configuración Zabbix Proxy en el FrontEnd
Encryption                :
   Connections from proxy : PSK
   PSK identify           : ZabbixProxy2020
   PSK                    : 174ca9394c1ebd45d099eb4f93861c140fff7d103d55b15a435714da50995ef1
Configuración de Encripción del Zabbix Proxy en el FrontEnd
Reiniciamos el Zabbix Server.
[root@zbxsrv01 ~]# systemctl restart zabbix-server
[root@zbxsrv01 ~]# systemctl status zabbix-server

Reiniciamos el Zabbix Proxy
[root@zbxprxy01 ~]# systemctl restart zabbix-proxy
[root@zbxprxy01 ~]# systemctl status zabbix-proxy
[root@zbxprxy01 ~]# tail -f /var/log/zabbix/zabbix_proxy.log
Por ultimo verificamos si la encriptación está activa desde el Frontend
Estado de la Encripción del Zabbix Proxy en el FrontEnd

Laboratorio 3: Configurar la encriptación Full de los Agentes vía Proxy

Explicación

En este ejercicio van a tener que configurar la encripción de los Agentes de Host (Zabbix Agent) zbxprxy01 y zbxclient01 contra el Zabbix Server como podemos ver en el siguiente MAPY. 
MAPY que muestra la conexión encriptada de los Agentes con el Zabbix Server
Si todo está configurado correctamente, lo podremos confirmar desde el Zabbix Frontend tal cual se ve en la siguiente imagen:
Encripción del Zabbix Proxy habilitada

Resolución

Nota: Hay 2 tipos de conexiones encriptadas.

      1. Zabbix Server <--> Zabbix Proxy
      Esta conexión es entre el Server y el Proxy, se configura la encripción por PSK en el fichero de configuración del Zabbix Proxy (zabbix_proxy.conf) y en el Zabbix Front End dentro de Administration -> Proxies -> [Buscamos el Proxy] -> Encryption ponemos exactamente la misma información configurada en el zabbix_proxy.conf del Zabbix Proxy.

      2. Zabbix Proxy <--> Zabbix Agent
      Esta parte es la que puede confundirnos un poco, ya que no configuramos la encripción directamente entre el Zabbix Agente y el Zabbix Proxy, sino que es entre el Zabbix Agent y el Zabbix Front End dentro de Administration  -> Hosts -> [Buscamos el Host] -> Encryption y ponemos exactamente la misma información configurada en el zabbix_agent.conf del Zabbix Agent. El Zabbix Server enviará las claves PSK cuando le informe su configuración al Zabbix Proxy.
Configuración en los Hosts
Creamos la clave de encripción del Agente en el host zxbclient01
[root@zbxclient01 ~]# mkdir -p /etc/zabbix/ssl/keys
[root@zbxclient01 ~]# cat <<EOF >/etc/zabbix/ssl/keys/zabbix_agent_psk
174ca9394c1ebd45d099eb4f93861c140fff7d103d55b15a435714da50995ef1
EOF
[root@zbxclient01 ~]# ls -la /etc/zabbix/ssl/keys
total 8
drwxr-xr-x. 2 root root 48 Jan  9 14:38 .
drwxr-xr-x. 3 root root 18 Jan  9 13:50 ..
-rw-r--r--. 1 root root 65 Jan  9 14:38 zabbix_agent_psk <- Clave para la encripción entre el Zabbix Agente y el Zabbix Server
-rw-r--r--. 1 root root 65 Jan  9 13:54 zabbix_psk       <- Clave para la encripción entre el Zabbix Proxy y el Zabbix Server
[root@zbxclient01 ~]# vi /etc/zabbix/zabbix_agentd.conf
PidFile=/var/run/zabbix/zabbix_agentd.pid
LogFile=/var/log/zabbix/zabbix_agentd.log
LogFileSize=0
Server=10.0.100.102
ServerActive=10.0.100.102
HostMetadata=97d7c2030d2ccf29f059f4c24a8c0796
Include=/etc/zabbix/zabbix_agentd.d/*.conf
TLSConnect=psk
TLSAccept=psk
TLSPSKIdentity=ZabbixAgent2020
TLSPSKFile=/etc/zabbix/ssl/keys/zabbix_agent_psk
[root@zbxclient01 ~]# systemctl restart zabbix-agent.service
[root@zbxclient01 ~]# systemctl status zabbix-agent.service
[root@zbxclient01 ~]# tail -f /var/log/zabbix/zabbix_agentd.log
Creamos la clave de encripción del Agente en el host zxbprxy01
[root@zbxprxy01 ~]# mkdir -p /etc/zabbix/ssl/keys
[root@zbxprxy01 ~]# cat <<EOF >/etc/zabbix/ssl/keys/zabbix_agent_psk
174ca9394c1ebd45d099eb4f93861c140fff7d103d55b15a435714da50995ef1
EOF

[root@zbxprxy01 ~]# vi /etc/zabbix/zabbix_agentd.conf
PidFile=/var/run/zabbix/zabbix_agentd.pid
LogFile=/var/log/zabbix/zabbix_agentd.log
LogFileSize=0
Server=127.0.0.1
ServerActive=127.0.0.1
HostMetadata=97d7c2030d2ccf29f059f4c24a8c0796
Include=/etc/zabbix/zabbix_agentd.d/*.conf
TLSConnect=psk
TLSAccept=psk
TLSPSKIdentity=ZabbixAgent2020
TLSPSKFile=/etc/zabbix/ssl/keys/zabbix_agent_psk
[root@zbxprxy01 ~]# systemctl restart zabbix-agent.service
[root@zbxprxy01 ~]# systemctl status zabbix-agent.service
[root@zbxprxy01 ~]# systemctl restart zabbix-proxy.service
[root@zbxprxy01 ~]# systemctl status zabbix-proxy.service
Configuración en el Zabbix Front End
Configuramos los parámetros de encriptación el proxy dentro del Zabbix Frontend.
CONFIGURATION -> HOSTS -> zbxclient01 y zbxprxy01
Encryption
   Connections to host    : PSK
   Connections from host  : PSK
   PSK identify           : ZabbixAgent2020
   PSK                    : 174ca9394c1ebd45d099eb4f93861c140fff7d103d55b15a435714da50995ef1
Habilitar la Encripción del Zabbix Agent (zbxclient01)
Estado de la Encripción del Zabbix Proxy (zbxprxy01)
Reiniciamos el Zabbix Server
[root@zbxsrv01 ~]# systemctl restart zabbix-server
[root@zbxsrv01 ~]# systemctl status zabbix-server 
Reiniciamos el Zabbix Proxy
[root@zbxprxy01 ~]# systemctl restart zabbix-proxy.service
[root@zbxprxy01 ~]# systemctl status zabbix-proxy.service
[root@zbxprxy01 ~]# tail -f /var/log/zabbix/zabbix_proxy.log 
Reiniciamos el Zabbix Agent en el Proxy
[root@zbxprxy01 ~]# systemctl restart zabbix-agent.service 
[root@zbxprxy01 ~]# systemctl status zabbix-agent.service
[root@zbxprxy01 ~]# tail -f /var/log/zabbix/zabbix_agentd.log
Si todo está configurado correctamente podemos ver que el agente está conectado y que la encripción del agente está habilitada vía PSK
Encripción del Zabbix Proxy habilitada

Limitaciones

- Los Zabbix Proxys no soportan la ejecución de comandos remotos.

- Auto-creación de la base de datos solo funciona para SQLite.

- No gestiona alertas o triggers, el proxy solo se utiliza para la recolección de datos.

El archivo de configuración /etc/zabbix/zabbix_proxy.conf

Introducción a la creación y configuración de Items y Triggers

Introducción

Antes de comenzar vamos a ver algunos conceptos a tener en cuenta.

Item          : Es el elemento que quiero monitorizar. Nos retornará un valor que luego procesaremos y al cual aplicaremos los triggers.

Preprocessing : Esta funcionalidad nos permite tratar los valores recolectados antes de que sean guardados en la base de datos.

Trigger       : Es una expresión lógica de un problema y cuando todas sus condiciones retornan VERDADERO es cuando se dispara.
Tipos de Ítems: Para explicarlos mejor vamos a ir creando cada uno de ellos y veremos sus diferentes funciones.
 * Zabbix Agent
 * Zabbix Agent (Active)
 * Simple Check
 * SNMPv1 agent
 * SNMPv2 agent
 * SNMPv3 agent
 * SNMP Trap
 * Zabbix Internal
 * Zabbix Trapper
 * Zabbix Aggregate
 * External Check
 * Database Monitoring
 * HTTP Agent
 * IPMI Agent
 * SSH Agent
 * TELNET Agent
 * JMX Agent
 * Calculated
 * Dependent Item
Preparamos los Labs
IMPORTANTE: - Antes de comenzar vamos borramos toda la configuración de encripcion en el ZBXCLIENT01 y ZBXPRXY01
IMPORTANTE: - Antes eliminaremos los templates del Host zbxclient01 desde el Zabbix Frontend para comenzar sin información a monitorizar y reconfiguramos el Zabbix Agent para que se conecte directamente al Server así las pruebas serán mas fluidas. 

CONFIGURATION > HOSTS > ZBXCLIENT01 > TEMPLATES > Unlink and clear
Reconfiguramos el Zabbix Agente del zbxclient01 y zbxprxy01
zbxclient01
[root@zbxclient01]# cat <<EOF >/etc/zabbix/zabbix_agentd.conf       
PidFile=/var/run/zabbix/zabbix_agentd.pid
LogFile=/var/log/zabbix/zabbix_agentd.log
LogFileSize=3
Server=10.0.100.100,127.0.0.1
ServerActive=10.0.100.100
Hostname=zbxclient01
HostMetadata=97d7c2030d2ccf29f059f4c24a8c0796
Include=/etc/zabbix/zabbix_agentd.d/*.conf
EOF
zbxprxy01
[root@zbxprxy01]# cat <<EOF >/etc/zabbix/zabbix_agentd.conf       
PidFile=/var/run/zabbix/zabbix_agentd.pid
LogFile=/var/log/zabbix/zabbix_agentd.log
LogFileSize=3
Server=10.0.100.100,127.0.0.1
ServerActive=10.0.100.100
Hostname=zbxprxy01
HostMetadata=97d7c2030d2ccf29f059f4c24a8c0796
Include=/etc/zabbix/zabbix_agentd.d/*.conf
EOF
Reconfiguramos los Agentes en Zabbix Frontend

CONFIGURATION > HOSTS > ZBXCLIENT01 > Encryption

   Connections to host    : No encryption
   Connections from host  : No encryption
   UPDATE

CONFIGURATION > HOSTS > ZBXPRXY01 > Encryption

   Connections to host    : No encryption
   Connections from host  : No encryption
   UPDATE
Reiniciamos todos los servicios
[root@zbxsrv01]# systemctl restart zabbix-server
[root@zbxprxy01]# systemctl stop zabbix-proxy.service
[root@zbxprxy01]# systemctl disable zabbix-proxy.service
Nota:Verificamos en el FrontEnd si el host zbxprxy01 accede por la Interfaz 10.0.100.102
[root@zbxprxy01]# systemctl restart zabbix-agent.service
[root@zbxprxy01]# systemctl status zabbix-agent.service
[root@zbxprxy01]# tail -f /var/log/zabbix/zabbix_agentd.log
[root@zbxclient01]# systemctl restart zabbix-agent.service
[root@zbxclient01]# systemctl status zabbix-agent.service
[root@zbxclient01]# tail -f /var/log/zabbix/zabbix_agentd.log
[root@zbxprxy01 ~]# systemctl restart zabbix-agent.service

Laboratorio 1: Creación del Ítem

Crearemos un Ítem de CPU Idle utilizando la función del Agente system.cpu.util
Función interna del Zabbix Agente systemc.cpu.util
Vamos a crear el item de % de Utilizacion de CPU
CONFIGURATION -> HOSTS -> ZBXCLIENT01 -> ITEMS -> Create Item
CIT01.png
Name                : CPU
Type                : Zabbix agent
Key                 : system.cpu.util[all,idle,avg1]
Type of information : Numeric (float)
Units               : %
Update interval     : 5s
New application     : Performance
Description         : CPU Utilization in percentage
CIPT02.png
Forzamos que Zabbix Server recargue la cache de configuración
[root@zbxsrv01 ~]# zabbix_server -R config_cache_reload
Verificamos en Latest data como se están recolectando las métricas
MONITORING -> LATEST DATA -> zbxclient01
CIPT03.png

Laboratorio 2: Reglas de Preprocesamiento

Esto es relativamente nuevo, aparecen en Zabbix 3.4 y desde entonces están evolucionando constantemente.
Las reglas de preprocesamiento ejecutan una transformación al dato recibido antes de almacenarlo en la base de datos.
En este ejemplo aplicaremos 2 reglas al valor recuperado.

  - In Range: Validamos que el dato esté dentro del rango establecido
              Aplicaremos la opción de Custom on fail que nos permite tomar una acción si el valor no esta dentro del rango deseado.

  - Discar unchanged with heartbeat: Esto descarta los valores iguales y almacena cada X tiempo uno. Si no son iguales los almacena directamente.
Creamos las reglas de preprocesamiento para el item de CPU
CONFIGURATION -> HOSTS -> ITEMS -> CPU -> PREOPROCESSING -> Preprocessing steps -> Add
Preprocessing steps
In range                        : 0    100
Discard unchanged with heartbeat: 1m
CIPT04.png

Laboratorio 3: Creación de Triggers

CIPT05.png
Creamos un trigger de Warning para el item anterior.
Name               : {HOST.NAME} - % CPU idle es inferior al 60%
Operational data   : 60% Mdo Normal - Actual: {ITEM.LASTVALUE}
Problem expression : {zbxclient01:system.cpu.util[all,idle,avg1].last()}<=60
OK event generation: Expression
Allow manual close : Check
Description        : % CPU usage es inferior al 60%
CIPT06.png
Creamos un trigger de High para el item anterior.
Name               : {HOST.NAME} - % CPU idle es inferior al 5%
Operational data   : >60% Modo Normal - Actual: {ITEM.LASTVALUE}
Problem expression : {zbxclient01:system.cpu.util[all,idle,avg1].last()}<=5
OK event generation: Expression
Allow manual close : Check
Description        : % CPU usage es superior al 95%
CIPT07.png
Simularemos algo de carga para ver si el trigger de Warning se dispara.

[root@zbxclient01 system]# stress -c 1
stress: info: [19754] dispatching hogs: 2 cpu, 0 io, 0 vm, 0 hdd
CIPT08.png
Simularemos algo de carga para ver si el trigger de High se dispara.

[root@zbxclient01 system]# stress -c 2
stress: info: [19754] dispatching hogs: 2 cpu, 0 io, 0 vm, 0 hdd
CIPT09.png
Vemos que los dos triggers están activos al mismo tiempo. Esto es correcto pero confunde la visualización ya que es obvio que si el de High se dispara el de Warning tambien estara activo. Para solucionar esto podemos utilizar la dependencia entre triggers.

Laboratorio 4: Dependencia entre triggers

Una vez dentro del trigger de Warning seleccionamos de quien depende
Vemos como se visualiza la dependencia
Vemos como se oculta el Trigger de Warning y solo se ve el de High
Nota: No es una buena práctica crear Items y triggers de forma local en los hosts, son muy difíciles de gestionar. Para evitar esta mala práctica, existen los Templates.

Creación y configuración de Templates

Introducción

Ahora que ya sabemos como crear Items y triggers en un Host, vamos a ver como crearlos en un Template.

Un Template o Plantilla es una agrupación de Aplicaciones, items, triggers, gráficos, screens y discovers. Básicamente definiremos todo lo anterior de la forma más genérica posible y luego lo aplicaremos a un grupo de Hosts.
Template  : Es una agrupación de Items, Aplicaciones, Triggers, Gráficos, Srceens, Discoverys y Web Scenarios.

Aplicación: Es una agrupación de Items. Nos resultará útil para filtrar cuando busquemos datos en tiempo real.

Item      : Es el elemento que quiero monitorizar. Nos retornará un valor que luego procesaremos y al cual aplicaremos los triggers.

Trigger   : Es una expresión lógica de un problema y cuando todas sus condiciones retornan TRUE es cuando se dispara.

Gráficos  : Es la representación gráfica del valor recuperado en el tiempo.

Screens   : Es la visualización de varios gráficos en una sola pantalla.

Discovery : Nos permite crear items prototypes, triggers prototypes, de forma dinámica. Por ejemplo si vemos los templates de Linux o Windows, estos utilizan discoverys para auto-descubrir los filesystems, crean triggers para cada uno de los ítems descubiertos. 

Web Scenarios: Esta es la forma de crear chequeos WEBs. Por ejemplo si queremos ver si una aplicación web está funcionando o el tiempo en que tarda en cargar, podemos crear un chequeo de este tipo. No es de lo más intuitivo, generalmente lo utilizo para ver si una web está activa, por ejemplo una con IIS y si da error, ejecutó una acción automática que es reiniciar el servicio.

Laboratorio 1: Template General

Introducción

En el siguiente Lab vamos a crear y probar los principales tipos de ítems que incorpora Zabbix. Para ello crearemos un template donde crearemos estos ítems y los aplicaremos al cliente zbxclient01.
Crearemos un template utilizando Zabbix Frontend.
CONFIGURATION -> TEMPLATE -> Create Template
   Template name          : Template App Zabbix-ES Multi-Items
   Visible name           : 
   Groups                 : Templates
   Description            : Ejemplo de creación de template

Creación de Ítem tipo SSH agent

Este tipo de ítem, nos permite ejecutar comandos vía SSH contra el host remoto.
Creamos el Ítem de SSH Agent.
Name                  : FreeMemSSH
Type                  : SSH agent
Key                   : ssh.run[free,{HOST.CONN},,] <- ssh.run[<unique short description>,<ip>,<port>,<encoding>]
Authentication method : Password
User name             : root
Password              : vagrant
Executed script       : free -b
Type of information   : Text
Update interval       : 10s
History storage period: 90d
New application       : SSH agent
Description           : 
Creación del Ítem
Aplicamos el Template al Host zbxclient01
CONFIGURATION -> HOSTS -> zbxclient01 -> TEMPLATES -> Linked Templates -> ADD -> Template App Zabbix-ES Multi-Items -> UPDATE
Releemos la configuración para que se apliquen los cambio del Template
[root@zbxsrv01 ~]# zabbix_server -R config_cache_reload
Retornara
[root@zbxclient01 ~]# free -b
              total        used        free      shared  buff/cache   available
Mem:     1039007744   104611840   808525824    20103168   125870080   788234240
Swap:    2147479552           0  2147479552
Vamos a ver como esta recolectando los datos
MONITORING -> LATEST DATA -> FILTER -> HOSTS -> zbxclient01

Creación de Ítem tipo Dependent ítem

Este tipo de ítem depende de otro recolectado anteriormente. Lo bueno es que con una sola llamada podemos crear múltiples items via las reglas de preprocesamiento.

Para este ejemplo utilizaremos el ítem anteriormente creado, pero antes vamos a ajustar el History storage period del Ítem SSH Agent ya que no queremos que guarde nada, simplemente lo utilizaremos como contenedor temporal hasta que lo preprocesemos.
CONFIGURATION > HOSTS > ZBXCLIENT01 > ITEMS > FreeMemSSH
History storage period: Do not keet history
Creamos el item dependiente del Master item (FreeMemSSH)
Name                  : SwapFree
Type                  : Dependent item
Key                   : SwapFree
Master item           : FreeMemSSH
Type of information   : Numeric (unsigned)
Units                 : b
New application       : SSH agent y Dependent item
Description           : 
Preprocessing steps
Regular Expression    : Swap:\s+(\d+)\s+(\d+)\s+(\d+)   \3
Custom on fail        : Set Value to     0
Creación del Ítem de SwapFree
Definición de las reglas de preprocesamiento
Creamos el item dependiente del Master item (FreeMemSSH)
Name                  : SwapTotal
Type                  : Dependent item
Key                   : SwapTotal
Master item           : FreeMemSSH
Type of information   : Numeric (unsigned)
Units                 : b
New application       : SSH agent y Dependent item
Description           : 
Preprocessing steps
Regular Expression    : Swap:\s+(\d+)\s+(\d+)\s+(\d+)   \1
Custom on fail        : Set Value to     1
Creación del Ítem de SwapTotal
Definición de las reglas de preprocesamiento
Releemos la configuración para que se apliquen los cambio del Template
[root@zbxsrv01 ~]# zabbix_server -R config_cache_reload

Creación de Ítem tipo Calculated

Este tipo de ítem nos resulta útil cuando queremos calcular valores entre ítems ya se encuentran en la base de datos de zabbix.
Creamos el item de tipo calculado para sacar el porcentaje de SWAP libre.
Name                : % Swap Free
Type                : Calculated
Key                 : SwapFreePercent
Formula             : 100-(last(SwapFree)/(last(SwapTotal) + count("SwapTotal",#1,0)))
Type of information : Numeric (float)
Units               : %
Update interval     : 10s
New application     : Calculated
Description         : 
Nota: Cambia el 0 por 1 pero no cambia nada si el divisor no es 0. Cuenta si el último valor es 0 si encuentra un 0 la cuenta retorna 1 con lo cual al valor del swap que es 0 le suma 1 y si no encuentra un 0 retorna swap + 0 y en ningún caso hay división por 0. 

Mas Info: https://www.zabbix.com/forum/zabbix-help/21474-the-problem-of-division-by-zero

Creación del Ítem calculado de los valores de SwapFree y SwapTotal
Creamos un trigger de Warning para el item anterior.
Name               : {HOST.NAME} - %Free SWAP es inferior al 80%
Operational data   : Actual: {ITEM.LASTVALUE}
Problem expression : {Template App Zabbix-ES Multi-Items:SwapFreePercent.min(#3)}<=80
OK event generation: Expression
Allow manual close : Check
Description        : 
Creamos un trigger para el ítem anterior
Creamos un trigger que se disparara cuando el SWAP sea CERO o esté desactivada.
Name               : {HOST.NAME} - Free SWAP es 0 o esta desactivada.
Operational data   : Actual: {ITEM.LASTVALUE}
Problem expression : {Template App Zabbix-ES Multi-Items:SwapFree.min(#3)}=0
OK event generation: Expression
Allow manual close : Check
Description        : 
Releemos la configuración para que se apliquen los cambio del Template
[root@zbxsrv01 ~]# zabbix_server -R config_cache_reload
Probamos el Trigger
Vamos al cliente y desactivamos el SWAP
[root@zbxclient01 ~]# swapoff -a
[root@zbxclient01 ~]# free
              total        used        free      shared  buff/cache   available
Mem:        1014656       88304      811704       13380      114648      790876
Swap:             0           0           0
[root@zbxclient01 ~]# swapon -a

Creación de Ítem tipo Zabbix Aggregated

Este tipo de ítem nos permite agregar resultados de ítems ya recolectados por Zabbix realizando consultas a la base de datos directamente, trabaja sobre los Hosts dentro de un Host Group y busca claves que coincidan aplicando diferentes funciones como Máximo, Mínimo, Promedio, Contar o Sumar. En mi caso lo utilizo bastante cuando tenemos la misma métrica aplicada a diferentes Hosts y en cada uno puede dar diferentes valores. 

Por ejemplo si tenemos un cluster de dos nodos y queremos monitorizar que los recursos del mismo están activos, pero hay recursos que solo pueden estar en uno de los dos nodos al mismo tiempo (Ej. la IP de servicio) y si no están en ninguno o en los dos, se podría considerar un fallo. En estos casos nos ayuda mucho este tipo de Ítems.

Como no tenemos un cluster vamos a simular que los hosts zbxclient01 y zbxprxy01 serán los nodos de nuestro cluster y el recurso será un fichero en el FileSystem, si este fichero existe, el recurso estará activo, de lo contrario se tomará como que no lo está y por consiguiente se considerará un fallo en el cluster.

Arquitectura a simular
Primero veremos la estructura de la Key del Item

groupfunc["host group","item key",itemfunc,timeperiod]
groupfunc : Define el tipo de agrupamiento que realizará.
          grpavg	Valor Promedio
          grpmax	Valor Máximo
          grpmin	Valor Mínimo
          grpsum	Suma de Valores

host group: Es el host Group donde buscará las coincidencias de las Keys.

item key  : Es la clave que buscara en los Hosts que están en el Host Group anterior.

itemfunc  : Es el tipo de función que aplicaremos Promedio, Contar, Último Valor, Máximo, Mínimo o Suma.

timeperiod: Especifica un periodo de tiempo de la última recolección de valores.
Creamos el Ítem que verifica si el fichero existe en disco.
Name                : NodoPrimario
Type                : Zabbix agent
Key                 : vfs.file.exists[/nodo_activo]
Type of information : Numeric (unsigned)
Units               : 
Update interval     : 3s
New application     : ClusterAPP
Description         : Checks if file exists. Returns 0 - not found; 1 - regular file or a link (symbolic or hard) to regular file exists

Verifica si existe el fichero /nodo_activo de ser así retorna 1 sino retorma 0.
Ahora aplicamos el Template al zbxprxy01 que sera nuestro nodo de respaldo en el cluster.
CONFIGURING -> HOSTS -> zbxprxy01 -> Templates -> Add -> Template App Zabbix-ES Multi-Items
Esto simula si un recurso está o no activo en uno de los nodos del cluster.
Creamos el Ítem que verificará el recurso en los Nodos
Creamos el Host Group y agregamos los 2 (zbxclient01 y zbxprxy01) nodos a él.
Group Name          : Cluster Zabbix-ES
Creamos el Host Group
Asignamos los hosts al nuevo Grupo
Asignar el nodo1 al nuevo HG
Asignar el nodo2 al nuevo HG
Crearemos un template utilizando Zabbix Frontend que verifique y monitorizará los nodos..
CONFIGURATION -> TEMPLATE -> Create Template
   Template name          : Template App Zabbix-ES Cluster
   Visible name           : 
   Groups                 : Templates
   Description            : Verifica si el recurso de FS esta Activo.
Creamos el Template
Crearemos el item agregado que verificara si el recurso esta activo en alguno de los nodos
CONFIGURATION -> TEMPLATES -> Template App Zabbix-ES Cluster -> ITEMS -> Create Item
Name                : Cluster Activo
Type                : Zabbix Aggregate
Key                 : grpsum["Cluster Zabbix-ES","vfs.file.exists[/nodo_activo]",last,0]
Type of information : Numeric (Unsigned)
Update interval     : 3s
New application     : ClusterAPP
Description         : 
Creamos el Item
Creamos un trigger de High para verificar si el cluster esta activo .
Name               : {HOST.NAME} - Cluster Down
Problem expression : {Template App Zabbix-ES Cluster:grpsum["Cluster Zabbix-ES","vfs.file.exists[/nodo_activo]",last,0].last(#1)}<1
OK event generation: Expression
Allow manual close : Check
Description        : Verifica si el recurso esta en uno de los nodos del cluster.
Creamos el Trigger
Creamos un Pseudo-Host que funcionara como nuestro Cluster ficticio.
CONFIGURATION -> HOSTS -> Create Host
Host name         : Cluster Zabbix-ES
Group             : Pseudo-Hosts
Agent interfaces  : 127.0.0.1
TEMPLATES -> Add -> Template App Zabbix-ES Cluster
Creamos el Pseudo-Host
Asignamos el Template de Cluster a este Host
Releemos la configuración para que se apliquen los cambio del Template
[root@zbxsrv01 ~]# zabbix_server -R config_cache_reload
Verificamos los valore recolectados por los nodos
MONITORING -> LATEST DATA -> Application -> ClusterAPP
Si todos están en CERO, el trigger tiene que estar activo
MONITORING -> PROBLEMS
 Activamos el recurso en uno de los dos nodos zbxclient01 y verificamos si nuestro cluster se recupera.
  # touch /nodo_activo
Introducimos un fallo y verificamos como se dispara el Trigger.
  # rm -f /nodo_activo
Comprobamos fallo en el recurso
Verificamos que no hay datos en ninguno de los 2 nodos por consiguiente tampoco en el item agregado.

Creación de Ítem tipo External Check

Este tipo de ítem nos resulta útil cuando no tenemos forma de verificar el dispositivo utilizando los métodos convencionales, para esto tenemos los externals checks, que son básicamente cualquier cosa que podamos ejecutar y luego procesar los resultados.
Es importante entender que todos los scripts que utilicemos tendrán que estar en un PATH determinado (/usr/lib/zabbix/externalscripts) este path se puede modificar cambiando la opción ExternalScripts en el fichero zabbis_server.conf. 
En el host zbxsrv01 dentro del directorio /vagran tenemos un script llamado ResponseTimeCURL.sh este script es un bash que básicamente llama a un CURL que se conecta con una WEB y toma unas mediciones, el resultado lo devuelve como un JSON con el siguiente formato:
# /vagrant/ResponseTimeCURL.sh www.google.com | jq
{
  "http_code": 200,
  "size_download": 5918,
  "size_header": 698,
  "size_request": 125,
  "size_upload": 0,
  "speed_download": 54591,
  "speed_upload": 0,
  "connect": 0.037,
  "namelookup": 0.016,
  "starttransfer": 0.108,
  "appconnect": 0,
  "pretransfer": 0.038,
  "redirect": 0,
  "total": 0.108
}
De estos valores nos quedaremos con Total y StartTransfer, el resto os dejo a vosotros que los investigueis. 

starttransfer: Es el tiempo en segundos, desde el inicio de la comunicación hasta que comienza a transferir el primer byte.

total        : Es el tiempo total en segundos hasta que la operación termina por completo.
Copiamos el script dentro del Path indicado para que Zabbix lo pueda utilizar.
[root@zbxsrv01 ~]# cp /vagrant/ResponseTimeCURL.sh /usr/lib/zabbix/externalscripts
[root@zbxsrv01 ~]# chmod 755 /usr/lib/zabbix/externalscripts/ResponseTimeCURL.sh
Nota:Si da error el scrip al ejecutarlo del tipo -bash: /usr/lib/zabbix/externalscripts/ResponseTimeCURL.sh: /bin/bash^M: bad interpreter: No such file or directory es por el retorno de carro, se tiene que ejecutar lo siguiente para solventar el problema:
# dos2unix /usr/lib/zabbix/externalscripts/ResponseTimeCURL.sh
Ahora vemos a crear un item que monitorice el tiempo de respuesta de una página web.
Name                   : Google Response Time
Type                   : External check
Key                    : ResponseTimeCURL.sh[http://www.google.com]
Type of information    : Text
Update interval        : 5s
History storage period : Do not keep history
New application        : External check
Description            : 
Creación del Ítem de External Check
Creación del Ítem Dependiente StartTransferTime
Name                : StartTransferTime
Type                : Dependent item
Key                 : google.starttransfer
Type of information : Numeric (float)
Units               : s
New application     : Dependent item y External check
Description         : 
Preprocessing steps
JSONPath            : $.starttransfer
Creación del Ítem Dependiente StartTransferTime
Con las reglas de preprocesamiento extraemos el valor deseado
Creación del Ítem Dependiente TotalTime
Name                : TotalTime
Type                : Dependent item
Key                 : google.total
Type of information : Numeric (float)
Units               : s
New application     : Dependent item y External check
Description         : 
Preprocessing steps
JSONPath            : $.total
Creación del Ítem Dependiente Total Time
Con las reglas de preprocesamiento extraemos el valor deseado
Releemos la configuración para que se apliquen los cambio del Template
[root@zbxsrv01 ~]# zabbix_server -R config_cache_reload
Verificamos que los datos se están recolectando correctamente.
MONITORIUNG -> LATEST DATA -> HOST: zbxclient01 -> External check
Con las reglas de preprocesamiento extraemos el valor deseado

Creación de Ítem tipo Simple Check

Este tipo de ítem se lo utiliza para chequear servicios remotos sin la necesidad de un agente instalado. Es el propio Zabbix Server quien los chequea.
Creamos el ítem
Name                : Simple Check TCP Perf - Google.com
Type                : Simple check
Key                 : net.tcp.service.perf[http,www.google.com]
Type of information : Numeric (float)
Units               : s
Update interval     : 3s
New application     : Simple check
Description         : Checks performance of TCP service. Returns 0 - service is down; seconds - the number of seconds spent while connecting to the service
Creación del Ítem
Creamos un trigger de Warning para el ítem anterior.
Name               : {HOST.NAME} - Conection to www.google.com is very slow
Operational data   : Actual: {ITEM.LASTVALUE}
Problem expression : {Template App Zabbix-ES Multi-Items:net.tcp.service.perf[http,www.google.com].max(3)}>=0.05
OK event generation: Expression
Allow manual close : Check
Description        : 
Creamos un trigger para el ítem anterior
Releemos la configuración para que se apliquen los cambio del Template
[root@zbxsrv01 ~]# zabbix_server -R config_cache_reload
Verificamos que los datos se están recolectando correctamente.
MONITORIUNG -> LATEST DATA -> HOST: zbxclient01 -> Application: Simple check

Creación de Ítem tipo Zabbix Trapper

Este tipo de ítem es muy útil ya que no es Zabbix quien tiene que solicitar el dato, sino que está esperando a que se lo envíen. 

El Server, Agent y el Proxy tiene un timeout máximo de 30 segundos, esto quiere decir que cualquier ítem a recolectar que tarde mas de ese tiempo es descartado. En algunos casos la recolección de datos dura más de 30 segundos, en este caso podemos utilizar el Zabbix Trapper.

Para poder utilizar esto necesitamos instalar una utilidad que se llama zabbix_sender, esta nos permite enviar traps a un Host específico. 
Creamos en el Zabbix Server el Ítem tipo Trapper
Name                : Zabbix Trapper
Type                : Zabbix Trapper
Key                 : zbx.get.trapper
Type of information : Text
Description         : Recibe un trap vía Zabbix_sender
Creamos el Ítem de Zabbix Trapper
Refrescamos la caché en el server
[root@zbxsrv01 ~]# zabbix_server -R config_cache_reload 
En el zbxclient01 instalamos el Zabbix Sender
[root@zbxclient01 ~]# yum install -y zabbix-sender
Bueno ya tenemos configurado el Ítem en el Server, en un template que esta linkeado a un host y el cliente tenemos instalado el zabbix_sender, ya estamos listos para hacer una prueba, pero antes de realizarla, vamos a ver algunas de las opciones principales de Zabbix Sender
 
-z - Especificamos la IP del Zabbix Server

-p - Especificamos el puerto del Zabbix Server (Por defecto es 10051)

-s - Especificamos el HOST donde enviaremos el Trap. Importante definir el nombre del host y no el visible.

-k - Especificamos la Key

-o - Especificamos el valor a enviar.
[root@zbxclient01 ~]# /usr/bin/zabbix_sender -z 10.0.100.100 -p 10051 -s "zbxclient01" -k 	zbx.get.trapper -o "Esto es una prueba de trap 1."
Response from "10.0.100.100:10051": "processed: 1; failed: 0; total: 1; seconds spent: 0.000026"
sent: 1; skipped: 0; total: 1
[root@zbxclient01 ~]# echo "zbxclient01 zbx.get.trapper Esto es una prueba de trap 2." | /usr/bin/zabbix_sender -c /etc/zabbix/zabbix_agentd.conf -i -
Response from "10.0.100.100:10051": "processed: 1; failed: 0; total: 1; seconds spent: 0.000023"
sent: 1; skipped: 0; total: 1
Nota: Mas informacion del comando en Zabbix Docs
En el Server verificamos desde Latest Data si los datos están llegando
Latest Data
Creamos un trigger de Información para verificar si se recibe un trap y que se cierra a los 30 segundos automaticamente.
Name               : {HOST.NAME} - Zabbix Trap Received
Problem expression : {Template App Zabbix-ES Multi-Items:zbx.get.trapper.nodata(1s)}=0
OK event generation: Recovery expression
Recovery expression: {Template App Zabbix-ES Multi-Items:zbx.get.trapper.nodata(30s)}=1
Allow manual close : Check
Description        : Detecta si un trap es recibido.
Creamos un Trigger que se cierra automáticamente a los 30 segundos
Releemos la configuración para que se apliquen los cambio del Template
[root@zbxsrv01 ~]# zabbix_server -R config_cache_reload
Enviamos un Trap desde el zbxclient01
[root@zbxclient01 ~]# zabbix_sender -z 10.0.100.100 -s zbxclient01 -k zbx.get.trapper -o "Envio Trap 1"     
Response from "10.0.100.100:10051": "processed: 1; failed: 0; total: 1; seconds spent: 0.000026"
sent: 1; skipped: 0; total: 1
Verificamos si tenemos alguna alarma activa por el trap recibido.
MONITORIUNG -> Problems
NOTA: Como este trigger tiene una recovery expression a los 30s, se recuperara de forma automática.

Creación de Ítem tipo SNMPv2 Agent

Este tipo de ítem es el más conocido, se  puede acceder a todos los dispositivos que utilicen SNMP sin necesidad de un Agente en local.

Lo más importante de este ítem es saber la mib que tenemos que llamar, la comunidad y que tipo de dato retorna. 

También es muy importante para que funcione correctamente tener creada y configurada la interfaz de SNMP en el Host. 
Instalamos en zbxclient01 las herramientas de SNMP y arrancamos el servicio de SNMPD
[root@zbxclient01]# yum install -y net-snmp net-snmp-utils
[root@zbxclient01]# systemctl enable snmpd
[root@zbxclient01]# systemctl start snmpd
Probamos que el agente de SNMP este activo.
[root@zbxclient01]# snmpget -On -v 2c -c public 10.0.100.101 .1.3.6.1.2.1.25.1.1.0    
.1.3.6.1.2.1.25.1.1.0 = Timeticks: (1018870) 2:49:48.70
En Zabbix Server creamos la interfaz de SNMP en el Host
Creamos la interfaz de SNMP en el Host
En Zabbix Server creamos un ítem de tipo SNMPv2 Agent
Name                : Uptime
Type                : SNMPv2 agent
Key                 : snmpv2[1.3.6.1.2.1.25.1.1.0]
SNMP OID            : .1.3.6.1.2.1.25.1.1.0
SNMP community      : public
Type of information : Numeric (unsigned)
Units               : uptime
Update interval     : 10s
New application     : SNMPv2 Agent
Description         : 
Creamos un ítem de tipo SNMPv2 Agent
Preprocessing steps
Custom Multiplier   : 0.01
Preprocesamiento del dato
Refrescamos la caché en el server
[root@zbxsrv01 ~]# zabbix_server -R config_cache_reload 
Verificamos que los datos se están recolectando correctamente.
MONITORIUNG -> LATEST DATA -> HOST: zbxclient01 -> Application: SNMPv2 Agent

Creación de Ítem tipo Zabbix internal

Este tipo de ítems lee de la base de datos información del zabbix.
Creamos el ítem de tipo Zabbix Internal
Name                : Zabbix History
Type                : Zabbix Internal
Key                 : zabbix[history]
Type of information : Numeric (unsigned)
Units               : 
Update interval     : 1m
New application     : Zabbix Internal
Description         : Number of values stored in table HISTORY.
Creación del Ítem
Refrescamos la caché en el server
[root@zbxsrv01 ~]# zabbix_server -R config_cache_reload

Creación de Ítem tipo Zabbix agent (pasive)

Creamos un ítem que utiliza una función propia del zabbix agent.
Name                : kernel.maxfiles
Type                : Zabbix agent
Key                 : kernel.maxfiles
Type of information : Numeric (unsigned)
Update interval     : 10s
New application     : Zabbix agent
Description         : Maximum number of processes supported by OS. Returns integer
Creación del Ítem
Refrescamos la caché en el server
[root@zbxsrv01 ~]# zabbix_server -R config_cache_reload

Creación de Ítem tipo Zabbix agent (active) - Log file monitoring

Creamos el ítem de tipo zabbix agent active
Name                : ORA-00600
Type                : Zabbix agent (active)
Key                 : log["/var/log/messages","ORA-00600",,,skip,]
Type of information : Log
Update interval     : 30s
New application     : Zabbix agent (active)
Description         : This is the generic internal error number for Oracle program exceptions. It indicates that a process has encountered a low-level, unexpected condition.
Creación del Ítem
Creamos un trigger de High para el ítem anterior.
Name               : {HOST.NAME} - ORA-00600 Error detected
Operational data   : Actual: {ITEM.LASTVALUE}
Problem expression : {Template App Zabbix-ES Multi-Items:log["/var/log/messages","ORA-00600",,,skip,].regexp(ORA-00600)}=1
OK event generation: Expression
Description        : This is the generic internal error number for Oracle program exceptions. It indicates that a process has encountered a low-level, unexpected condition.
Creación del Trigger
Refrescamos la caché en el server
[root@zbxsrv01 ~]# zabbix_server -R config_cache_reload
Preparamos el agente y hacemos una prueba
Asignamos permisos al usuario zabbix para que pueda leer el /var/log/messages
[root@zbxclient01 ~]# setfacl -m u:zabbix:r /var/log/messages

Nota: Hacemos esto ya que el Agente de Zabbix se ejecuta nativamente con el usuario ZABBIX y este no tiene permisos para leer el log. Si no realizamos esto, podemos obtener el error: Cannot open file "/var/log/messages": [13] Permission denied
Reiniciamos el Agente
[root@zbxclient01 ~]# systemctl restart zabbix-agent.service 
[root@zbxclient01 ~]# systemctl status zabbix-agent.service 
Monitorizamos el Log en una ventana
[root@zbxclient01 ~]# tail -f /var/log/messages
Generamos un evento en otra ventana
[root@zbxclient01 ~]# logger "ORA-00600: internal error code, arguments: [2662], [2910], [829087674], [2910], [829528307], [1451708231]"
Verificamos que el trigger se dispara (hay que esperar unos 30s)
MONITORIUNG -> PROBLEMS

Laboratorio 2: Low-Level Discovery

Introducción

El Low-level discovery o LLD nos permite crear de forma automática items, triggers y gráficos. Este es el principal beneficio del LLD, que auto descubra los elementos que queremos monitorizar de forma autónoma y cree los ítems y triggers según el elemento sea descubierto.

Por ejemplo Zabbix puede monitorizar Filesystems o Interfaces de red de forma automática, sin tener que crearlas manualmente. También se pueden eliminar entidades auto descubiertas de forma automatica segun los resultados del discovery que se realiza periódicamente. Es decir si eliminamos un filesystems, el autodiscovery periodico ya no lo descubrirá y Zabbix lo eliminara posteriormente.
Nota:  Desde la versión de Zabbix 4.2 el formato del JSON que acepta el LLD cambio. Ya no espera que contenga el objeto data como se puede ver en algunos documentos antiguos. Esto es importante de cara al montaje del los LLDs. Los actuales LLDs aceptan un JSON que contenga un array, esto es para poder soportar nuevas funcionalidades como el item value preprocessing y los customs paths para las macros de los LLDs.
Formato anterior a Zabbix 4.2
{
	"data":[
		{ "{#FSNAME}":"/",                   "{#FSTYPE}":"rootfs"   },
		{ "{#FSNAME}":"/tmp",                "{#FSTYPE}":"ext3"     },
		{ "{#FSNAME}":"/var",                "{#FSTYPE}":"ext3"     }
	]
}
Formato posterior a Zabbix 4.2
[
	{ "{#FSNAME}":"/",                           "{#FSTYPE}":"rootfs"   },
	{ "{#FSNAME}":"/tmp",                        "{#FSTYPE}":"ext3"     },
	{ "{#FSNAME}":"/var",                        "{#FSTYPE}":"ext3"     }
]


Zabbix trae un conjunto de Discoverys ya implementados como pueden ser:
discovery of network interfaces
discovery of CPUs and CPU cores
discovery of SNMP OIDs
discovery of JMX objects
discovery using ODBC SQL queries
discovery of Windows services
discovery of host interfaces in Zabbix
Para mas información ver documentación de Zabbix 4.2 o superior: https://www.zabbix.com/documentation/current/manual/discovery/low_level_discovery

Low Level Discovery utilizando Zabbix Agent + UserParameter

Preparamos la Regla de Autodiscover en el Zabbix Agent
[root@zbxclient01 ~]# vi /etc/zabbix/zabbix_agentd.d/userparameter_lld.conf
UserParameter=lld.disk, /usr/bin/iostat -y 2>/dev/null | /usr/bin/sed -n '/Device/,$p' |  /usr/bin/awk 'BEGIN{sep="";print "["} NR!=1 { if($1) { print sep"{\"{#DEV}\":\""$1"\"}" } sep=","}END{print "]"}'
UserParameter=dev.putilization[*], /usr/bin/iostat -yx 1 2 $1 | /usr/bin/tail -2 | /usr/bin/head -1 | /usr/bin/awk '{print $NF}'
Nota: Este script genera una salida con el formato en JSON que espera la Discovery Rule. 

[root@zbxclient01 ~]# systemctl restart zabbix-agent.service 
Probamos si funciona el LLD
[root@zbxclient01 ~]# zabbix_get -s 127.0.0.1 -k lld.disk
[
  {"{#DEV}":"sda"}
]
Creamos la Discovery Rule desde el Zabbix Frontend
CONFIGURATION > TEMPLATES > Template App Zabbix-ES Multi-Items >  DISCOVERY RULES > CREATE DISCOVERY RULE

Name                       : LLD Devices
Type                       : Zabbix Agent
Key                        : lld.disk
Update interval            : 1m 
Keep lost resources period : 30d
Creamos el Item prototype desde el Zabbix Frontend
CONFIGURATION > TEMPLATES > Template App Zabbix-ES Multi-Items >  DISCOVERY RULES > ITEM PROTOTYPES > CREATE ITEM PROTOTYPE

Name                       : % {#DEV} Utilization
Type                       : Zabbix Agent
Key                        : dev.putilization["{#DEV}"] <- ES LA KEY definida en el userparameter del agente que se le pasa como parámetro la macro del LLD
Type of information        : Numeric (float)
Units                      : %
Update interval            : 3s
New application            : Discovery rule
Creamos un Trigger Prototype desde el Zabbix Frontend
CONFIGURATION > TEMPLATES > Template App Zabbix-ES Multi-Items >  DISCOVERY RULES > TRIGGER PROTOTYPES > CREATE TRIGGER PROTOTYPE

Name                       : {HOST.NAME} - % High disk usage device: {#DEV}
Severity                   : HIGH
Expression                 : {Template App Zabbix-ES Multi-Items:dev.putilization["{#DEV}"].avg(#3)}>=60
Allow manual close         : CHECK

Recargamos la Cache de configuración desde el Zabbix Server 
[root@zbxsrv01 ~]# zabbix_server -R config_cache_reload
Forzamos el Discovery desde el Zabbix Frontend
CONFIGURATION > HOSTS > ZBXCLIENT01> DISCOVERY RULES > Check Now
Monitorizamos el disco
MONITORING > LATEST DATA > HOSTS: ZBXCLIENT01, APPLICATION: Discovery rule > APPLY
Generamos un poco de carga y vemos cómo se comporta el nuevo Trigger
[root@zbxclient01 ~]# dd if=/dev/sda of=/dev/null bs=1024

Laboratorio 3: Integración de Zabbix con Prometheus

Introducción

En el siguiente Lab vamos a ver una de las últimas funcionalidades que incorporó Zabbix, la integración nativa con los exporters de Prometheus.

Prometheus fue fundado por Sound Cloud en el 2012 y se libero el codigo en el 2015. Es bastante nuevo pero esta teniendo muy buena acogida porque es muy simple de instalar, monitorizar y esta soportado por la CNFC (Cloud Native Computing Fundation).

Es importante destacar que no es Prometheus:
 - No es un sistema de almacenamiento de Logs, no hace log tracking con lo que no podemos recolectar logs, eventos de logs o texto.
 - No detecta anomalías automáticamente.
 - No es escalable y no fue desarrollado para mantener un histórico de datos muy grande. Si bien se pueden guardar los datos en InfluxDB no 
fue creado para esto.
 - No es una solución Unificada, tiene muchos componentes que interactúan entre si como Prometheus para recolectar, node_exporter para monitorizar, alert manager, cadviser, etc...

Que es prometheus:
 - Es una solución recomendada para monitorizar cloud, SaaS y OpenStack.
Para este laboratorio, no utilizaremos el Agente de Zabbix, sino un item HTTP que se conectara con un exporter de Prometheus. Esta funcionalidad se implementó hace muy poco en Zabbix y nos permite conectarnos a exporters de Prometheus de forma nativa y tratar las métricas obtenidas vía preprocesamiento.
https://openmetrics.io/
Incluir Ejemplos tipo: https://blog.zabbix.com/zabbix-4-2-prometheus-integration/7558/#08

Instalación Exporter de Prometheus en zbxclient01

[root@zbxclient01 system]# useradd -m -s /bin/bash prometheus 
[root@zbxclient01 system]# su - prometheus
[prometheus@zbxclient01 ~]$ wget https://github.com/prometheus/node_exporter/releases/download/v1.0.1/node_exporter-1.0.1.linux-amd64.tar.gz
[prometheus@zbxclient01 ~]$ tar -xzvf node_exporter-1.0.1.linux-amd64.tar.gz
[prometheus@zbxclient01 ~]$ mv node_exporter-1.0.1.linux-amd64 node_exporter
[prometheus@zbxclient01 ~]$ exit
[root@zbxclient01 system]# cat <<EOF >/etc/systemd/system/node_exporter.service
[Unit]
Description=Node Exporter
Wants=network-online.target
After=network-online.target

[Service]
User=prometheus
ExecStart=/home/prometheus/node_exporter/node_exporter

[Install]
WantedBy=default.target
EOF
[root@zbxclient01 system]# systemctl daemon-reload
[root@zbxclient01 system]# systemctl enable node_exporter.service
[root@zbxclient01 system]# systemctl start node_exporter.service
Acceso via URL: http://10.0.100.101:9100/metrics

Creamos un Template para las pruebas contra Prometheus

Template Name         : Template App Zabbix-ES Prometheus
Groups                : Templates
Description           : Template basado en un exporter de prometheus
TZProm01.png
Creamos una Macro en la que definimos el port del node_exporter
Macro                 : {$NODE_EXPORTER_PORT}
Valor                 : 9100
TZProm02.png
Aplicamos el Template al zbxclient01
CONFIGURATION > HOSTS > TEMPLATES > Link new templates
Creamos el Master Ítem con todos los datos que retorna el Node_exporter
Name                  : Master Item
Type                  : HTTP agent
Key                   : master[node_exporter]
URL                   : http://{HOST.CONN}:{$NODE_EXPORTER_PORT}/metrics
Request type          : GET
Type of information   : Text
Update interval       : 30s
History storage period: Do not keep history
New application       : Prometheus
Description           : Métricas de Prometheus Node_Exporter
TZProm03.png
TZProm04.png
Creamos un ítem Dependiente del Master para extraer un valor directamente vía Prometheus Pattern

Nota: Este ejemplo nos muestra cómo podemos acceder a los ítems de Prometheus vía Prometheus pattern con el parametro go_memstats_heap_inuse_bytes que retorna 4.358144e+06 y aplicando nuevamente preprocesamiento vía Javascript obtenemos 4358144

# HELP go_memstats_heap_inuse_bytes Number of heap bytes that are in use.
# TYPE go_memstats_heap_inuse_bytes gauge
go_memstats_heap_inuse_bytes 4.358144e+06

RETORNA: 4358144
Name                  : Heap InUse
Type                  : Dependent item
Key                   : go_memstats_heap_inuse_bytes[node_exporter]
URL                   : Master Item
Type of information   : Numeric (float)
Units                 : b
New application       : Prometheus
Description           : Number of heap bytes that are in use.
TZProm05.png
Preprocessing steps
Name                  : Prometheus pattern
Parameters            : go_memstats_heap_inuse_bytes

Name                  : JavaScript
Parameters            : return Number(value)
TZProm06.png
Creamos una Discovery Rule y creamos las LDD Macros

Nota: Este ejemplo nos muestra cómo podemos acceder a los ítems de Prometheus vía Prometheus to JSON aplicando la expresión: node_network_receive_bytes_total{device=~".*"}

RETORNA:
[
  {
    "name": "node_network_receive_bytes_total",
    "value": "2.48981225e+08",
    "line_raw": "node_network_receive_bytes_total{device=\"eth0\"} 2.48981225e+08",
    "labels": {
      "device": "eth0"
    },
    "type": "counter",
    "help": "Network device statistic receive_bytes."
  },
  {
    "name": "node_network_receive_bytes_total",
    "value": "5.2624563e+07",
    "line_raw": "node_network_receive_bytes_total{device=\"eth1\"} 5.2624563e+07",
    "labels": {
      "device": "eth1"
    },
    "type": "counter",
    "help": "Network device statistic receive_bytes."
  },
  {
    "name": "node_network_receive_bytes_total",
    "value": "1.237289e+06",
    "line_raw": "node_network_receive_bytes_total{device=\"lo\"} 1.237289e+06",
    "labels": {
      "device": "lo"
    },
    "type": "counter",
    "help": "Network device statistic receive_bytes."
  }
]
Name                      : Low Level Discovery Network Devices
Type                      : Dependent item
Key                       : node_network_devices[node_exporter]
URL                       : Master Item
Keep lost resources period: 30d
TZProm07.png
Preprocessing steps
Name                      : Prometheus to JSON
Parameters                : node_network_receive_bytes_total{device=~".*"}
TZProm08.png
De este JSON extraemos las macros que utilizaremos en los Items Prototypes.
LLD Macros
Name                      : {#DEVICE}
Parameters                : $.labels.device

LLD macro                 : {#HELP}
Parameters                : $.help
TZProm09.png
Creamos un item prototype utilizando las LLD Macros
Name                  : Network Total Receive {#DEVICE}
Type                  : Dependent item
Key                   : node_network_receive_bytes_total[{#DEVICE}]
URL                   : Master Item
Type of information   : Numeric (float)
Units                 : b
New application       : Prometheus
Description           : Network device statistic receive_bytes.
TZProm10.png
TZProm11.png


Preprocessing steps
Name                      : Prometheus pattern
Parameters                : node_network_receive_bytes_total{device="{#DEVICE}"}

Name                      : JavaScript
Parameters                : return Number(value)
TZProm12.png
Más información en la documentación de Zabbix
https://www.zabbix.com/documentation/5.0/manual/config/items/itemtypes/prometheus
https://www.zabbix.com/documentation/5.0/manual/discovery/low_level_discovery/prometheus

Ejercicio práctico: Añadir al host zbxclient01 el de Template OS Linux by Prom y confirmar si recolecta datos

Objetivo: En este ejemplo vemos cómo podemos monitorizar un Linux con el Template por defecto que trae Zabbix Server para Prometheus.

Resolución

- Seleccionar el Host zbxclient01
- Seleccionar Templates
- Buscamos el template Template OS Linux by Prom y lo incluimos.
- Vamos a Latest Data para ver si se están recolectando los items.

  Nota: Recordar que para no esperar, debemos reiniciar la configuration Cache en Zabbix Server con el comando: zabbix_server -R config_cache_reload
IMPORTANTE: https://share.zabbix.com

Instalación y configuración de zabbix-java-gatewey

Instalamos Tomcat en zbxclient01

# yum install -y tomcat
--- Instalamos alguna aplicacion
# yum install -y tomcat-webapps tomcat-admin-webapps 
-- Configuramos Tomcat para que arranque JMX
# vi /etc/tomcat/tomcat.conf
JAVA_OPTS="-Djava.rmi.server.hostname=10.0.100.101 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=7199 -Dcom.sun.management.jmxremote.rmi.port=7199 -Xms256M -Xmx512M -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.net.preferIPv4Stack=true -Djava.net.preferIPv4Addresses=true"
Nota:-Djava.rmi.server.hostname={IP DEL HOST DONDE ESTA EL TOMCAT}
-- Iniciamos tomcat
# systemctl enable tomcat.service 
# systemctl start tomcat.service 
# systemctl status tomcat.service 
-- Verificamos los puertos principales
# ss -
8080  Puerto del Tomcat
8009  Puerto del conector JK
7199  Puerto del JMX

Instalar Java Gateway en zbxsrv01

# yum install zabbix-java-gateway
# cat /etc/zabbix/zabbix_java_gateway.conf 
-- En el zabbix server tienes que configurar
# vi /etc/zabbix/zabbix_server.conf
   StartJavaPollers=5      <- Numero de poolers de Java que se arrancan de Java Gateway
   JavaGateway=127.0.0.1   <- Cual es la ip del servidor de Java Gateway
   JavaGatewayPort=10052   <- Puerto del comunicación entre ZabbixServer y Java Gateway
# systemctl restart zabbix-server
# systemctl start zabbix-java-gateway
# systemctl enable zabbix-java-gateway
# tail -f /var/log/zabbix/zabbix_java_gateway.log 
IMPORTANTE: Agrega la interfaz de JMX en el HOST PORT 7199 a monitorizar y el de "Template App Apache Tomcat JMX" o "Template App Generic Java JMX"

Alertas

Introducción

Las alertas son una de las funciones primarias que tiene Zabbix, esto nos permite ejecutar una acción sobre un un evento detectado. 

El flujo es el que podemos ver en el siguiente esquema, un HOST dispara un TRIGGER, este genera un EVENTO y a este le podemos asignar una ACCIÓN como puede ser enviar un Mail, un SMS, crear un incidente automáticamente en JIRA (Webhook) o simplemente ejecutar un Script para solventar el problema, esto se llama remediación.
HOSTS -> TRIGGER -> EVENT -> ACTION (eMail, SMS, Webhooks, Custom alertscripts)
Media Oficial
Las acciones consisten en condiciones y operaciones. Básicamente, cuando se cumplen las condiciones podemos ejecutar una operación. Las dos operaciones principales son enviar un mensaje (notificación) y ejecutar un comando remoto.
Cuando configuramos una alerta, podemos definir el escalado de las mismas, por ejemplo podemos recibir un evento y la primer acción es informar a los operadores via mail, si este no se soluciona en 15 minutos envía un SMS y genera un ticket en nuestro sistema de ticketing, si en 30 minutos no está solventado envía SMS al segundo nivel de soporte.
Como comentamos antes, podemos crear acciones a partir de eventos, tenemos diferentes tipos de eventos nosotros en este caso nos centraremos en los eventos generados por los Triggers, estos se generan cuando un trigger cambia su estado (OK -> PROBLEM -> OK). 
En los siguientes laboratorios veremos cómo enviar una notificación utilizando el sistema de mensajería Telegram o la notificación más básica que es via Mail.

Laboratorio 1: Configuración y envío de alertas vía Telegram - Zabbix 5.X o superior

Telegram webhook - Media de Telegram Oficial
Los pasos serán los siguientes:
1. Creamos y configuramos la bot en Telegram
2. Configuramos la Media de Telegram en el Zabbix Frontend
3. Creamos el usuario Admin para que utilice la Media de Telegram
4. Creamos una acción de tipo Trigger 
5. Generamos un evento para ver como envía el mensaje vía Telegram

Configuramos la Media a un Usuario

ADMINISTRATION > USERS > [Usr: Admin] > MEDIA > Add
Type             : Telegram
Send to          : [ID DEL GRUPO QUE RECUPERAMOS CON /getgroupid]
When active      : 1-7,00:00-24:00
Use if severity  : Todos marcados
Enabled          : CHECKED
Asignamos la nueva Media al Usuario

Configuramos una acción que se disparara cuando se activa un TRIGGER

CONFIGURATION > ACTIONS > Event Source: [Triggers] > Create Action
Action
Name                : Notificaciones por Telegram
Type of calculation : And/Or
Conditions          : Problem is not suppressed
                      Trigger severity is greater than or equals Information
DEMOASL01.png
Operations  details 
Steps               : 1 -1
Step duration       : 0
Operation type      : Send message
Send to User groups : Zabbix administrators
Send only to        : Telegram Groups
DEMOASL02.png
Recargamos la cache para no tener que esperar
[root@zbxsrv01]# zabbix_server -R config_cache_reload
Generamos un evento para ver cómo envia la notificacion a Telegram
[root@zbxclient01 ~]# logger "ORA-00600: internal error code, arguments: [2662], [2910], [829087674], [2910], [829528307], [1451708231]"

Laboratorio 1 bis: Configuración y envío de alertas vía Telegram - Zabbix 4.X o inferior

Los pasos serán los siguientes:
1. Creamos y configuramos la bot en Telegram
2. Configuramos la Media de Telegram en el Zabbix Frontend
3. Creamos el usuario Admin para que utilice la Media de Telegram
4. Creamos una acción de tipo Trigger 
5. Generamos un evento para ver como envia el mensaje via Telegram
IMPORTANTE: El script que vamos a utilizar esta desarrollado por Ilya Ableev en el siguiente enlace podemos ver más documentación y ejemplos de como funciona https://github.com/ableev/Zabbix-in-Telegram

Configuración de @BotFather

Creamos una bot en Telegram con @BotFather
Creación de una Bot con @BotFather
1. Con el comando /newbot creamos una nueva bot.
2. Le damos un Nombre a la nueva bot. Ej: Zabbix de 0 a 100
3. Definimos el usuario de la bot, importante tiene que terminar en bot.  Ej: zbxowbot
4. Copiamos el Token de la nueva bot. Ej.: 984773026:AAGGanGafk_b6tTccZ8zh2LDKE7yX72o5Qg
Clonamos el repositorio de Zabbix-in-Telegram recomendado por Zabbix Share 
[root@zbxsrv01]# cd /usr/src/
[root@zbxsrv01]# git clone https://github.com/ableev/Zabbix-in-Telegram.git
[root@zbxsrv01]# cd Zabbix-in-Telegram/
Instalamos Python PIP y con el las dependencias necesarias para utilizar los scripts de envío de alertas
[root@zbxsrv01]# yum install python-pip
[root@zbxsrv01]# pip install -r requirements.txt
Copiamos los scripts dentro del directorio de AlertScripts

   Nota: El Path al directorio de AlertScripts esta definido dentro de zabbix_server.conf en la opción AlertScriptsPath=. Por defeto es AlertScriptsPath=/usr/lib/zabbix/alertscripts

[root@zbxsrv01]# cp zbxtg.py /usr/lib/zabbix/alertscripts/
[root@zbxsrv01]# cp zbxtg_group.py /usr/lib/zabbix/alertscripts/
[root@zbxsrv01]# cp zbxtg_settings.example.py /usr/lib/zabbix/alertscripts/zbxtg_settings.py

Configuramos algunos parametros del zbxtg
tg_key              <--- Es el token que nos da @BotFather cuando creamos una nueva bot
zbx_server          <--- La URL completa al zabbix server
zbx_api_user        <--- Es la cuenta que utilizamos para el login (Admin)
zbx_api_pass        <--- Es el password de la cuenta
zbx_server_version  <--- Define la versión de Zabbix Server que estamos utilizando.
zbx_db_host         <--- Es el Host donde está alojada la base de datos.
zbx_db_database     <--- Es el Nombre de la base de datos de Zabbix.
zbx_db_user         <--- Es el Usuario de coneccion a la base de datos.
zbx_db_password     <--- Es el Password para acceder a la base de datos.
[root@zbxsrv01]# vi /usr/lib/zabbix/alertscripts/zbxtg_settings.py

Ej.:

  tg_key = "506123068:AAGcRjDlVgUVGHqtsuFGsHZyJkxA0A539JY"  # telegram bot api key
  zbx_server = "http://127.0.0.1/zabbix/"  # zabbix server full url
  zbx_api_user = "Admin"
  zbx_api_pass = "zabbix"
  zbx_server_version = 4  # for Zabbix 4.x version, default will be changed in the future with this
  zbx_db_host = "localhost"
  zbx_db_database = "zabbix"
  zbx_db_user = "zabbix"
  zbx_db_password = "Z4bb1x"
Creamos un grupo de Telegram y lo Suscribimos a la BOT

Para esto tenemos que crear un Grupo en Telegram, en este caso le ponemos el nombre "Zabbix de 0 a 100" pero pueden utilizar en que uds quieran, y en este grupo vamos a incluir la bot que creamos anteriormente.
Lo primero que tenemos que hacer para habilitar la comunicación con la bot, esto lo hacemos ejecutando el comando /start@zbxowbot en el grupo que creamos.
El primer mensaje lo enviamos desde la interfaz gráfica de Telegram para que nos valide y tiene que ser /start@[usuario de la bot].
Suscribimos nuestro usuario la BOT

Los mensajes los podemos recibir vía un grupo al que estemos inscriptos o directamente desde la BOT, para esto tenemos que suscribirnos a ella.
El primer mensaje lo enviamos desde la interfaz gráfica de Telegram para que nos valide y tiene que ser /start.
Probamos desde línea de comando si los mensajes llegan vía el Grupo o Directamente.

[root@zbxsrv01]# cd /usr/lib/zabbix/alertscripts/

Recepción de mensajes vía el Grupo de Telegram
[root@zbxsrv01 alertscripts]# ./zbxtg.py "Zabbix de 0 a 100" "Linea 1: Esto es una prueba de envío." "Linea 2: Mas información." --group --debug
Vemos que el mensaje llega a Telegram
Recepción de mensajes directamente.
[root@zbxsrv01 alertscripts]# ./zbxtg.py @MiUsuario "Subject" "texto" --debug

Configuración de Zabbix Frontend

Creamos una nueva media para enviar alertas vía Telegram.
ADMINISTRATION -> MEDIA TYPES -> CREATE MEDIA TYPE
Notificaciones a Usuarios
Name                : Telegram Users
Type                : Script
Script name         : zbxtg.py
Script parameters
   {ALERT.SENDTO}
   {ALERT.SUBJECT}
   {ALERT.MESSAGE}
 
Description         : Envío de alertas por Telegram a usuarios
Enabled             : CHECKED
Notificaciones a Grupos
Name                : Telegram Groups
Type                : Script
Script name         : zbxtg.py
Script parameters
   {ALERT.SENDTO}
   {ALERT.SUBJECT}
   {ALERT.MESSAGE}
   --group               <- Si queremos enviar a grupos.
 
Description         : Envío de alertas por Telegram a grupos
Enabled             : CHECKED
Creamos una nueva Media
Configuramos la Media a un Usuario
ADMINISTRATION > USERS > [Usr: Admin] > MEDIA > Add
Type             : Telegram
Send to          : @Destinatario o "Nombre del Grupo" [Zabbix-ES] <- Importante sin comillas
When active      : 1-7,00:00-24:00
Use if severity  : Todos marcados
Enabled          : CHECKED
Asignamos la nueva Media al Usuario
Configuramos una acción que se disparara cuando un evento nuevo aparezca
CONFIGURATION > ACTIONS > Event Source: [Triggers] > Create Action
Action
Name                : Notificaciones por Telegram
Type of calculation : And/Or
Conditions          : Problem is not suppressed
                      Trigger severity is greater than or equals Information
DEMOASL01.png
Operations  details 
Steps               : 1 -1
Step duration       : 0
Operation type      : Send message
Send to User groups : Zabbix administrators
Send only to        : Telegram Groups
DEMOASL02.png
Recargamos la cache para no tener que esperar
[root@zbxsrv01]# zabbix_server -R config_cache_reload
Generamos un evento para ver cómo envia la notificacion a Telegram
[root@zbxclient01 ~]# /usr/bin/zabbix_sender -z 10.0.100.100 -p 10051 -s "zbxclient01" -k zbx.get.trapper -o "Esto es una prueba de trap 1."

Laboratorio 2: Configuración y envío de alertas vía eMail

Los pasos serán los siguientes:
1. Configuramos la Media de Email
2. Creamos un Usuario
3. Creamos un Grupo de Usuarios
4. Creamos una acción de tipo Trigger 
5. Generamos un evento para ver como envia el Email
Configuramos la Media de eMail
ADMINISTRATION > MEDIA TYPES > [Email]
Name                : Email
Type                : Email
SMTP Server         : localhost
SMTP server port    : 25
SMTP helo           : zbxsrv01
SMTP email          : zabbix@midominio.com
Connection security : None
Authentication      : None
Message format      : Plain Text
Description         : Configuración de SMTP
DEMOASL0201.png
Creamos un usuario
ADMINISTRATION > USERS > [Create User]
User
Alias               : mobarrio
Name                : Mariano
Surname             : Obarrio Miles
Groups              : Asignamos el grupo Notificaciones de tipo Información
DEMOASL0208.png
Media
Type                : Email (10 Minute Mail)
Send to             : [cuenta de mail]
DEMOASL0209.png
Permissions
User type           : Zabbix user
Permissions         : {Se asignan vía User Groups}
Creamos un grupo de usuarios que recepciona los mails
ADMINISTRATION > USER GROUPS > [Create user group]
User group
Group name          : Notificaciones de tipo Información
Users               : mobarrio
DEMOASL0212.png
Permissions
Host group          : All groups
Permissions         : Read
DEMOASL0210.png
DEMOASL0211.png
Creamos una accion de tipo Trigger
CONFIGURATION > ACTIONS > Event source: Triggers > [Create Action]
Action
Name                : Notificaciones por Mail
Type of calculation : And/Or
Conditions          : Problem is not suppressed
                      Trigger severity is greater than or equals Information
DEMOASL0203.png
Operations  details 
Steps               : 1 -1
Step duration       : 0
Operation type      : Send message
Send to Users       : mobarrio (Mariano Obarrio Miles)
Send only to        : Email

DEMOASL0213.png
DEMOASL0204.png
Generamos un evento para ver como envia el Email
[root@zbxclient01 ~]# /usr/bin/zabbix_sender -z 10.0.100.100 -p 10051 -s "zbxclient01" -k zbx.get.trapper -o "Esto es una prueba de trap 1."

DEMOASL0206.png
DEMOASL0214.png

Laboratorio 3: Configuración de alertas vía MS Teams y Escalado vía eMail

MSTeams webhook - Media Oficial
Los pasos serán los siguientes:
1. Creamos y configuramos el Grupo de MS Teams
2. Configuramos la Media de msteams en el Zabbix Frontend
3. Creamos el usuario Admin para que utilice la Media de MSTeams
4. Creamos una acción de tipo Trigger
5. Generamos un evento para ver como envía el mensaje vía MSTeams
Obtenemos una cuenta en 10 Minute Mail
Generamos un evento para ver como envia el Email
[root@zbxclient01 ~]# /usr/bin/zabbix_sender -z 10.0.100.100 -p 10051 -s "zbxclient01" -k zbx.get.trapper -o "Evento para MSTeams."

DEMOASL0206.png
DEMOASL0214.png
Ref.: Parametros para realizar un Test de MS Teams

Tips y buenas prácticas

Zabbix Server: Refresh Configuration Cache

Configuration Syncer arranca cada 30s y pasa los datos de la base de datos al Configuration cache que lo utilizaran los poolers. Si no queremos esperar podemos ejecutar el comando "zabbix_server -R config_cache_reload" que fuerza el reload.

Esto es útil cuando modificamos un datos en el FE y queremos que se apliquen los cambios, como puede ser el tipo de item,  si no refrescamos la cache puede tardar un tiempo en aplicar los cambios.

Zabbix Proxy: Refresh Configuration Cache

El Proxy refresca el configuration cache cada 1h, si actualizamos algo y queremos que entre mas pronto en el scheduler podemos refrescar la cache utilizando el siguiente comando "zabbix_proxy -R config_cache_reload" que fuerza el reload.

Zabbix Server: Items y Templates

Ajustar los tiempos de History y Trends a lo realmente necesario, para no guardar datos eternamente.

Si un ítem es de tipo Master y no tiene sentido guardar su información, configurar a CERO o en las últimas versiones de Zabbix permite seleccionar la opción de No almacenar, antes esto no existía.

Es muy importante no configurar Items directamente en los HOSTS de forma aislada. Es una buena práctica siempre crear los items en un template y aplicarlo al HOST.

Zabbix Server: Configuración

No incrementar los parámetros del server indiscriminadamente porque tengamos una máquina sobredimensionada, esto puede traer otros problema y empeorar la performance del server.

Zabbix Server: Incrementar y Decrementar el nivel de Debug

Incrementar el nivel de DEBUG a 4
# zabbix_server --runtime-control log_level_increase
# zabbix_server --runtime-control log_level_increase
# zabbix_server --runtime-control log_level_increase
# zabbix_server --runtime-control log_level_increase
Decrecrementar el nivel de DEBUG a 0
# zabbix_server --runtime-control log_level_decrease
# zabbix_server --runtime-control log_level_decrease
# zabbix_server --runtime-control log_level_decrease
# zabbix_server --runtime-control log_level_decrease
Para incrementar/decrementar el nivel de DEBUG de un proceso
# zabbix_server --runtime-control log_level_increase=<PROCESO>
# zabbix_server --runtime-control log_level_decrease=<PROCESO>

Procesos en el Server
alert manager - Administra tareas y alertas
alerter - Proceso que envía notificaciones.
configuration syncer - Proceso para administrar la cache en memoria del configuration data
discoverer - Proceso para el discovery de dispositivos
escalator - Proceso para las acciones de escalado.
history syncer - History DB writer
housekeeper - Proceso para remover datos historicos
http poller - Poller de monitorizacion web
icmp pinger - Poller de icmpping checks
ipmi manager - Administrador del poller de IPMI
ipmi poller - Poller de los chequeos de IPMI
java poller - Poller de los chequeos de Java
lld manager - Administrador de procesos para las tareas de low-level discovery
lld worker - Proceso worker de las tareas de low-level discovery
poller - Poller para los chequeos pasivos
preprocessing manager - Administrador de las tareas de preprocesamiento.
preprocessing worker - Proceso para el preprocesamiento de datos.
proxy poller - Poller para proxys pasivos.
self-monitoring - Proceso para la recolección de estadísticas internas del server.
snmp trapper - Trapper para los traps de SNMP
task manager - Proceso para la ejecución remota de tareas por parte de otros componentes como(close problem, acknowledge problem, check item value now, remote command functionality)
timer - Timer para procesar mantenimientos.
trapper - Trapper para chequeos activos, traps, y la comunicación con el proxy.
unreachable poller - Poller para los dispositivos no accesibles (unreachable devices)
vmware collector - VMware data collector responsable para la recolección de datos del VMware.

Firewall: Apertura de puertos para la comunicación entre el Server y el Agente

Nota: Si se quiere tener el firewall activo podemos abrir los puertos que utiliza Zabbix.
# firewall-cmd --list-all
# firewall-cmd --add-port={10051/tcp,10050/tcp} --permanent
# firewall-cmd --reload
# firewall-cmd --list-all
# systemctl restart zabbix-agent.service

Zabbix y la comunidad

- Zabbix SIA - https://www.zabbix.com
- Git de Zabbix - https://git.zabbix.com/
- Twitter Oficial - https://twitter.com/zabbix
- Facebook Oficial - https://www.facebook.com/zabbix/
- LinkedIn Oficial- https://www.linkedin.com/company/zabbix/
- Youtube Channel Oficial - https://www.zabbix-es.com.es/index.php/Zabbix_Series_Youtube
- Documentación Oficial - https://www.zabbix.com/manuals
- Templates Oficial - https://share.zabbix.com/
- Eventos Oficial - https://www.zabbix.com/events
- Webinars Oficial - https://www.zabbix.com/webinars
- WIKI Zabbix-ES - https://www.zabbix-es.com.es
- Zabbix International Community Telegram Group
- ZabbixEspañol Telegram Group

Píldoras Generales

Integración de Zabbix con Grafana

Desinstalamos si lo esta la versión de docker preinstalada

# yum remove docker \
                 docker-client \
                 docker-client-latest \
                 docker-common \
                 docker-latest \
                 docker-latest-logrotate \
                 docker-logrotate \
                 docker-selinux \
                 docker-engine-selinux

Instalamos docker

# yum install -y yum-utils device-mapper-persistent-data lvm2
# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# yum install -y docker-ce docker-ce-cli containerd.io
# systemctl start docker
# systemctl enable docker

Instalamos docker compose

# curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose
# ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
# docker-compose --version

Despliegue de Grafana con Docker-Compose

- Instalación con Docker
- La Base de datos por default es SQLLite, para probar va bien, para producción, recomiendo MySQL o PostgreSQL!
Datos para el Login a Grafana y conexión vía Zabbix Datasource
- Acceso           : http://10.0.100.101:8081
- Usuario          : admin 
- Password         : zabbix
- Datasource Zabbix: http://10.0.100.100/zabbix/api_jsonrpc.php 
- Usuario          : admin 
- Password         : zabbix
# mkdir -p /dockers/grafana/data
# mkdir -p /dockers/grafana/log
# mkdir -p /dockers/postgres/data

# chmod -R 777 /dockers/grafana
# chmod -R 777 /dockers/postgres

# cd /dockers/grafana
# cat <<EOF >docker-compose.yml 
version: "3.6"
services:
  postgres:
    image: "postgres"
    container_name: postgres
    restart: always
    networks:
      - internal-net
    ports:
      - 5432:5432
    environment:
      - POSTGRES_USER=admin
      - POSTGRES_PASSWORD=admin
      - POSTGRES_DB=grafana
    volumes:
      - ./postgres/data:/var/lib/postgresql/data/
 
  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    depends_on:
      - redis
      - postgres
    networks:
      - internal-net
    ports:
      - "8081:3000"
    volumes:
      - ./grafana/data:/var/lib/grafana
      - ./grafana/log:/var/log/grafana
    environment:
      GF_DATABASE_HOST: "postgres:5432"
      GF_DATABASE_TYPE: postgres
      GF_DATABASE_USER: admin
      GF_DATABASE_PASSWORD: admin
      GF_DATABASE_SSL_MODE: disable
      GF_AUTH_LOGIN_COOKIE_NAME: grafana_session
      GF_AUTH_LOGIN_MAXIMUM_INACTIVE_LIFETIME_DAYS: 7
      GF_AUTH_LOGIN_MAXIMUM_LIFETIME_DAYS: 30
      GF_AUTH_TOKEN_ROTATION_INTERVAL_MINUTES: 1440
      GF_SESSION_PROVIDER: redis
      GF_SESSION_PROVIDER_CONFIG: "addr=redis:6379,pool_size=300,db=grafana,prefix=grafana"
      GF_SESSION_COOKIE_SECURE: "true"
      GF_PANELS_DISABLE_SANITIZE_HTML: "true"
      GF_LOG_LEVEL: debug
      GF_LOG_MODE: console
      GF_INSTALL_PLUGINS: alexanderzobnin-zabbix-app
      GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS: alexanderzobnin-zabbix-app, alexanderzobnin-zabbix-datasource
      GF_SERVER_ROOT_URL: http://10.0.100.101:8081
      GF_SECURITY_ADMIN_PASSWORD: zabbix

  redis:
    container_name: redis
    image: redis:latest
    ports:
      - 6379:6379
    networks:
      - internal-net
    environment:
      - ALLOW_EMPTY_PASSWORD=yes

networks:
  internal-net:
    driver: bridge
EOF
# docker-compose up -d
# docker-compose logs -f

Configuración de SNMP Traps en Zabbix

Nota: Existen 2 tipos de scripts para monitorizar SNMP el Zabbix Reciver y el SNMPTT. Nosotros utilizaremos el propio de Zabbix.

Documentación Original

Pre-requisitos Centos 7

# yum install -y net-snmp-utils net-snmp-perl net-snmp

Pre-requisitos Centos 8

# rpm -qa| grep snmp
net-snmp-5.8-14.el8_2.1.x86_64
net-snmp-utils-5.8-14.el8_2.1.x86_64
net-snmp-libs-5.8-14.el8_2.1.x86_64
net-snmp-agent-libs-5.8-14.el8_2.1.x86_64
pcp-pmda-snmp-5.0.2-5.el8.x86_64
# yum remove net-snmp net-snmp-libs net-snmp-agent-libs net-snmp-utils
# wget http://repo.okay.com.mx/centos/8/x86_64/release//net-snmp-perl-5.8-7.el8.2.x86_64.rpm
# wget http://repo.okay.com.mx/centos/8/x86_64/release//net-snmp-5.8-7.el8.2.x86_64.rpm
# wget http://repo.okay.com.mx/centos/8/x86_64/release//net-snmp-utils-5.8-7.el8.2.x86_64.rpm
# wget http://repo.okay.com.mx/centos/8/x86_64/release//net-snmp-agent-libs-5.8-7.el8.2.x86_64.rpm
# wget http://repo.okay.com.mx/centos/8/x86_64/release//net-snmp-libs-5.8-7.el8.2.x86_64.rpm
# yum install net-snmp-perl-5.8-7.el8.2.x86_64.rpm net-snmp-5.8-7.el8.2.x86_64.rpm net-snmp-utils-5.8-7.el8.2.x86_64.rpm net-snmp-libs-5.8-7.el8.2.x86_64.rpm net-snmp-agent-libs-5.8-7.el8.2.x86_64.rpm

Activar SNMP Trapper en el server

# vi /etc/zabbix/zabbix_server.conf
SNMPTrapperFile=/var/log/snmptrap/snmptrap.log
StartSNMPTrapper=1
# mkdir -p /var/log/snmptrap
# chmod 750 /var/log/snmptrap
# chown zabbix:zabbix /var/log/snmptrap

Configuración SNMP TRAP

# vi /etc/snmp/snmptrapd.conf
authCommunity execute public
authCommunity execute publica
perl do "/usr/bin/zabbix_trap_reciver.pl"

Configurar el script de Reciver

# wget -O /usr/bin/zabbix_trap_reciver.pl https://git.zabbix.com/projects/ZBX/repos/zabbix/raw/misc/snmptrap/zabbix_trap_receiver.pl   # Alternativa: https://raw.githubusercontent.com/prelegalwonder/zabbix/master/misc/snmptrap/zabbix_trap_receiver.pl
# chmod 755 /usr/bin/zabbix_trap_reciver.pl

# vi /usr/bin/zabbix_trap_reciver.pl
$SNMPTrapperFile = '/var/log/snmptrap/snmptrap.log';

# systemctl restart zabbix-server

Activamos el SNMPD

# systemctl enable snmptrapd
# systemctl start snmptrapd

Rotacion del log

# vi /etc/logrotate.d/zabbix_traps
/var/log/snmptrap/snmptrap.log {
    weekly
    size 10M
    compress
    compresscmd /usr/bin/bzip2
    compressoptions -9
    notifempty
    dateext
    dateformat -%Y%m%d
    missingok
    maxage 365
    rotate 10
}

Forzamos una rotacion para probar la configuracion
# logrotate -v -f /etc/logrotate.d/zabbix_traps 
Nota: Con esto tendremos 10 copias comprimidas del fichero "snmptrap.log"

Configuración en Zabbix Server

Creación del Template de Fallback
Nota: snmptrap.fallback <- Todo lo que no machea con la expresión regular anterior va a parar fallback.
IMPORTANTE: Administration -> General -> Other -> Log unmatched SNMP traps: Para saber que traps estoy recibiendo pero no monitorizando.
Template Name: Template SNMP trap fallback
Groups       : Templates
Creación del Template
Creación del Item de fallback
Name               : SNMP trap fallback
Type               : SNMP trap
Key                : snmptrap.fallback
Type of information: Log
New Application    : SNMP fallback
Creación del Item
Creación del Trigger de fallback
Name               : {HOST.NAME} - Unmatched SNMP trap received
Severity           : Information
Expression         : {Template SNMP trap fallback:snmptrap.fallback.nodata(300)}=0
Allow manual close : CHECK
Description        : Genera alerta si entra un TRAP no controlado.
Creación del Trigger
Nota: Esta alerta saltara durante 5 minutos.
Creación del Template de SNMP Traps
Nota: En este templete generaremos alertas para traps conocidos.
Template Name: Template SNMP traps
Groups       : Templates
Creación del Template
- Lincamos el Template al template de fallback
Link
Creación del Item de un Trap Conocido
Name               : SNMP trap enterprises.8074.2.3.2.3
Type               : SNMP trap
Key                : snmptrap["SNMPv2-SMI::enterprises.8074.2.3.2.3"]
Type of information: Text
New Application    : SNMP::Trap
Creación del Item
Creación del Trigger del Trap Definido
Name               : {HOST.NAME} - SNMP Trap enterprises.8074.2.3.2.3
Severity           : Warning
Expression         : {Template SNMP traps:snmptrap["SNMPv2-SMI::enterprises.8074.2.3.2.3"].nodata(60)}=0
Allow manual close : CHECK
Description        : Genera alerta si entra un TRAP predefinido.
Creación del Trigger
Nota: Esta alerta saltara durante 1 minuto.
Configuración de Zabbix Server para la recepción de los TRAPs
- Vamos al HOST Zabbix Server y creamos la Interfaz de SNMP en localhost
SNMP Interface
- Asignamos el template de "Template SNMP trap" al Zabbix Server
Link Template
snmptrap 
  Key: [<EXPRESION REGULAR>]

Pruebas - Enviar un TRAP

# /usr/bin/snmptrap -v 1 -c public 10.0.100.100 '.1.3.6.1.6.3.1.1.5.4' '0.0.0.0' 6 33 '55' .1.3.6.1.6.3.1.1.5.4 s "eth0"
--- TRAP No Conocido
# cat /tmp/zabbix_traps.tmp
18:03:36 2019/03/25 ZBXTRAP 127.0.0.1
PDU INFO:
  notificationtype               TRAP
  version                        0
  receivedfrom                   UDP: [127.0.0.1]:19374->[127.0.0.1]:162
  errorstatus                    0
  messageid                      0
  community                      public
  transactionid                  1
  errorindex                     0
  requestid                      0
VARBINDS:
  DISMAN-EVENT-MIB::sysUpTimeInstance type=67 value=Timeticks: (55) 0:00:00.55
  SNMPv2-MIB::snmpTrapOID.0      type=6  value=OID: IF-MIB::linkUp.0.33
  IF-MIB::linkUp                 type=4  value=STRING: "eth0"
  SNMP-COMMUNITY-MIB::snmpTrapCommunity.0 type=4  value=STRING: "public"
  SNMPv2-MIB::snmpTrapEnterprise.0 type=6  value=OID: IF-MIB::linkUp
--- TRAP Conocido
# /usr/bin/snmptrap -v 1 -c public 10.0.100.100 '.1.3.6.1.6.3.1.1.5.3' '0.0.0.0' 6 33 '55' enterprises.8074.2.3.2.3 s "teststring000"
# cat /tmp/zabbix_traps.tmp
11:15:03 2019/03/26 ZBXTRAP 127.0.0.1
PDU INFO:
  notificationtype               TRAP
  version                        0
  receivedfrom                   UDP: [127.0.0.1]:35683->[127.0.0.1]:162
  errorstatus                    0
  messageid                      0
  community                      public
  transactionid                  6
  errorindex                     0
  requestid                      0
VARBINDS:
  DISMAN-EVENT-MIB::sysUpTimeInstance type=67 value=Timeticks: (55) 0:00:00.55
  SNMPv2-MIB::snmpTrapOID.0      type=6  value=OID: IF-MIB::linkDown.0.33
  IF-MIB::linkDown               type=4  value=STRING: "teststring000"
  SNMP-COMMUNITY-MIB::snmpTrapCommunity.0 type=4  value=STRING: "public"
  SNMPv2-MIB::snmpTrapEnterprise.0 type=6  value=OID: IF-MIB::linkDown
Problema detectado



Zabbix Agent2

Teoria y documentación

https://www.zabbix.com/documentation/current/manual/concepts/agent2
https://www.zabbix.com/documentation/current/manual/appendix/config/zabbix_agent2
https://www.zabbix.com/documentation/current/manual/config/items/restrict_checks
https://www.zabbix.com/documentation/current/manual/config/items/itemtypes/zabbix_agent/zabbix_agent2

Ventajas del Agent2

  • Infraestructura de Plugins
  • Active Checks paralelos
  • Soporte de intervalos flexibles para todos los chequeos
  • Soporte de conexiones persistentes (conexiones a DB)
  • Acepta traps y eventos entrantes (suscripción MQTT, escuchando puertos TCP / UDP, etc.)
  • Monitoreo de servicios systemd out of the box
  • Reemplazo directo del agente existente

Storage Persistente para Zabbix Agent2

+--------+                                                   +--------+ Casos de Uso
| Zabbix |                                                   | Zabbix | - Comunicaciones inestables.
|        | ------------------ Lost Connection ---------------|        | - Monitorización de datos críticos
| Agent2 |                                                   | Server | - Ráfagas de datos
+--------+                                                   +--------+
EnablePersistentBuffer=1
PersistentBufferFile=/var/spool/zabbix/agent.db
PersistentBufferPeriod=1d

Seguridad desde el lado del Agente

Zabbix Blog: Support of whitelists and blacklists for metrics on agent side
# Whitelist for MySQL related checks
AllowKey=mysql[*]
DenyKey=*
# Blacklist to deny all shell scripts
DenyKey=system.run[*]
# Blacklist to deny access to /etc/passwd
DenyKey=vfs.file.contents[/etc/passwd,*]

Instalación del Zabbix Agent2 desde repositorio

# yum remove zabbix-agent
# yum install zabbix-agent2
# vi /etc/zabbix/zabbix_agent2.conf
Server=10.0.100.100,10.0.100.101,127.0.0.1
StatusPort=8090
ServerActive=10.0.100.100
Hostname=zbxclient01
HostMetadata=97d7c2030d2ccf29f059f4c24a8c0796
# systemctl enable zabbix-agent2
# systemctl start zabbix-agent2
# tail -f /var/log/zabbix/zabbix_agent2.log

Configuración de storage persistente

# systemctl stop zabbix-agent2

# mkdir -p /var/spool/zabbix
# chown zabbix:zabbix /var/spool/zabbix
# vi /etc/zabbix/zabbix_agent2.conf 
EnablePersistentBuffer=1
PersistentBufferFile=/var/spool/zabbix/zabbix_agent2.db
PersistentBufferPeriod=1d

# systemctl start zabbix-agent2

Pruebas de Agente y Plugins

# zabbix_agent2 --print
# zabbix_agent2 -t "vfs.file.md5sum[/etc/passwd]" 
# zabbix_agent2 -t "vfs.file.md5sum[/etc/shadow]"
# zabbix_agent2 -R metrics

- Activamos el StatusPort=8090 http://10.0.100.101:8090/status
Configuración del Plugin de Dockers
# setfacl --modify user:zabbix:rw /var/run/docker.sock
# systemctl restart zabbix-agent2
# tail -f /var/log/zabbix/zabbix_agent2.log
# zabbix_get -s 10.0.100.101 -k docker.ping
# zabbix_get -s 10.0.100.101 -k docker.containers.discovery[false] | jq
# zabbix_get -s 10.0.100.101 -k docker.images.discovery | jq
# zabbix_get -s 10.0.100.101 -k docker.container_info[f4e09e124782cb43378999bcf05445e2e6bf91c0cd84701732f204eb788a0025] | jq
Configuración del Plugin de MemCached
# zabbix_get -s 10.0.100.101 -k memcached.ping["tcp://localhost:11211",admin,admin]
# zabbix_get -s 10.0.100.101 -k memcached.stats["tcp://localhost:11211",admin,admin,] | jq

Configuración del Plugin de MySQL
# zabbix_get -s 10.0.100.101 -k mysql.ping["tcp://localhost:3306",admin,admin]
# zabbix_get -s 10.0.100.101 -k mysql.db.discovery["tcp://localhost:3306",admin,dadminmo] | jq
# zabbix_get -s 10.0.100.101 -k mysql.db.size["tcp://localhost:3306",admin,admin,admin] | jq
# zabbix_get -s 10.0.100.101 -k mysql.version["tcp://localhost:3306",admin,admin]
Configuración del Plugin de PostgreSQL
# zabbix_get -s 10.0.100.101 -k pgsql.db.discovery["tcp://localhost:5432",admin,admin,] | jq
# zabbix_get -s 10.0.100.101 -k pgsql.ping["tcp://localhost:5432",admin,admin,grafana]
# zabbix_get -s 10.0.100.101 -k pgsql.dbstat["tcp://localhost:5432",admin,admin,admin] | jq

Configuración del Plugin de Redis
# zabbix_get -s 10.0.100.101 -k redis.ping["tcp://localhost:6379",]
# zabbix_get -s 10.0.100.101 -k redis.info["tcp://localhost:6379",,]


Particionado de Zabbix - PostgreSQL + TimescaleDB (aka: TSDB)

MUY IMPORTANE: Todo el proceso de creación de las Hipertablas se tiene que realizar con el Zabbix Server y Zabbix Frontend DETENIDOS. 
                  El proceso de creación es bloqueante, se para zabbix Server y Frontend y se vuelve a arrancar una vez finalice la creación de todas las Hipertablas.

Documentacion oficial

Instalación de TSDB

Nota:Ejecutar bajo el usuario root
# tee /etc/yum.repos.d/timescale_timescaledb.repo <<EOL
[timescale_timescaledb]
name=timescale_timescaledb
baseurl=https://packagecloud.io/timescale/timescaledb/el/7/\$basearch
repo_gpgcheck=1
gpgcheck=0
enabled=1
gpgkey=https://packagecloud.io/timescale/timescaledb/gpgkey
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
metadata_expire=300
EOL
# yum clean all
# yum repolist`
# yum update -y
# yum install -y timescaledb-postgresql-12
- Como el script timescaledb_tune modifica el postgres.conf hacemos una copia por si necesitamos algun dato.
Nota:Ejecutar bajo el usuario postgres
$ cp /var/lib/pgsql/12/data/postgresql.conf /var/lib/pgsql/12/data/postgresql.conf.preTSDB
$ cp /var/lib/pgsql/12/data/pg_hba.conf /var/lib/pgsql/12/data/pg_hba.conf.preTSDB
- Ejecutamos el script que tunea nuestro postgres segun los datos de CPU y Memoria que tengamos en el sistema.
$ timescaledb-tune --pg-config=/usr/pgsql-12/bin/pg_config

 Ver Salida del comando
Nota:Ejecutar bajo el usuario root
# systemctl restart postgresql-12
- Crear la extension de TSDB
# psql -U postgres -d zabbix -c "CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE;"
- Siempre mirar el script que trae zabbix por si hay cambios.
# zcat /usr/share/doc/zabbix-server-pgsql-5.0.3/timescaledb.sql.gz

- Creamos los chunks y tomamos tiempos de ejecución. Nota: Recomendable ejecutar con screen.

- Detenemos Zabbix Server y Zabbix Frontend
# systemctl stop zabbix-server.service
# systemctl stop httpd.service 
- Creación de Hipertablas Opción 1
# zcat /usr/share/doc/zabbix-server-pgsql-5.0.3/timescaledb.sql.gz | sudo -u zabbix psql zabbix

- Creación de Hipertablas Opción 2
psql -U postgres -c "SELECT create_hypertable('history_log', 'clock', chunk_time_interval => 86400, migrate_data => true);" zabbix
psql -U postgres -c "SELECT create_hypertable('history_str', 'clock', chunk_time_interval => 86400, migrate_data => true);" zabbix
psql -U postgres -c "SELECT create_hypertable('history_text', 'clock', chunk_time_interval => 86400, migrate_data => true);" zabbix
psql -U postgres -c "SELECT create_hypertable('history', 'clock', chunk_time_interval => 86400, migrate_data => true);" zabbix
psql -U postgres -c "SELECT create_hypertable('trends', 'clock', chunk_time_interval => 86400, migrate_data => true);" zabbix
psql -U postgres -c "SELECT create_hypertable('trends_uint', 'clock', chunk_time_interval => 86400, migrate_data => true);" zabbix
psql -U postgres -c "SELECT create_hypertable('history_uint', 'clock', chunk_time_interval => 86400, migrate_data => true);" zabbix
psql -U postgres -c "UPDATE config SET db_extension='timescaledb',hk_history_global=1,hk_trends_global=1;" zabbix
psql -U postgres -c "UPDATE config SET compression_status=1,compress_older='7d';" zabbix
- Arrancamos Zabbix Server y Zabbix Frontend
# systemctl start zabbix-server.service
# systemctl start httpd.service 
- Tiempos medios para una BD de 237GB
 create_hypertable: history_log  (5s)
 create_hypertable: history_str  (13s)
 create_hypertable: history_text (2m)
 create_hypertable: history      (1h 25m)
 create_hypertable: history_uint (1h 53m)
 create_hypertable: trends       (27m)
 create_hypertable: trends_uint  (56m)
- Verificamos los chunks creados.
psql -U postgres -d zabbix -c "SELECT chunk_table,total_bytes FROM chunk_relation_size('history_log');"
psql -U postgres -d zabbix -c "SELECT chunk_table,total_bytes FROM chunk_relation_size('history_str');"
psql -U postgres -d zabbix -c "SELECT chunk_table,total_bytes FROM chunk_relation_size('history_text');"
psql -U postgres -d zabbix -c "SELECT chunk_table,total_bytes FROM chunk_relation_size('history_uint');"
psql -U postgres -d zabbix -c "SELECT chunk_table,total_bytes FROM chunk_relation_size('history');"
psql -U postgres -d zabbix -c "SELECT chunk_table,total_bytes FROM chunk_relation_size('trends');"
psql -U postgres -d zabbix -c "SELECT chunk_table,total_bytes FROM chunk_relation_size('trends_uint');"

Reiniciamos Zabbix Server

# systemctl restart zabbix-server

Consultas generales a TSDB

SELECT * FROM timescaledb_information.compressed_chunk_stats;
SELECT * FROM timescaledb_information.hypertable;
SELECT * FROM timescaledb_information.hypertable WHERE table_schema='public' AND table_name='metrics';
SELECT * FROM timescaledb_information.license;
SELECT * FROM timescaledb_information.compressed_hypertable_stats;


Introducción al Blacklisting via Zabbix Agent

Documentación oficial

https://www.zabbix.com/documentation/current/manual/appendix/config/zabbix_agentd
https://www.zabbix.com/documentation/current/manual/config/items/restrict_checks
https://blog.zabbix.com/support-of-whitelists-and-blacklists-for-metrics-on-agent-side/11878/
Hoy vamos a hablar del blacklisting que incorpora zabbix a partir de la versión 5.0.2.

Antes de la versión 5.0.2, si teníamos habilitado el parámetro de agente EnableRemoteCommands, Zabbix nos dejaba ejecutar cualquier comando vía agente, por ejemplo utilizando el script zabbix_get, esto en los Linux puede ser un problema un poco mas acotado ya que la instalación por defecto en Linux se realiza con un usuario de menos privilegios (ZABBIX), pero en windows el servicio del agente esta instalado bajo la cuenta de system, lo que permitiría poder ejecutar prácticamente cualquier cosa.

Actualmente zabbix incorporo el concepto de blacklist y whitelist en el agente, lo que nos permite trabajar y gestionar un poco mas granularmenté los permisos de que puede o no hacer el agente.
Estas tareas las realiza con 2 nuevos parámetros del agente AllowKey y DenyKey, que básicamente chequean una expresión con wildcards.

Por defecto todo esta permitido, menos las ejecuciones como system.run[*] que se deniegan por default. tenemos que ir incluyendo claves según nuestras necesidades. Una buena practica es no tener una Blacklist muy extensa ya que lo mas probable es que no podamos contemplar todos los casos de uso y algo se nos pueda escapar. Por este motivo, es mejor decirle que permitimos y finalizamos con lo que seria un DenyAll (DenyKey=*).

Desde la versión de Zabbix 5.0.2 el parámetro EnableRemoteCommands del agent esta:
 - Deprecado para Zabbix agent
 - No soportado para Zabbix agent2

Hay una serie de reglas que tenemos que tener en cuanta y que son importantes al momento de trabajar con estas listas

- Una lista blanca (whitelist) sin una regla de DENY, solo esta permitida para ítems system.run[*].
  Para todos los otros ítems, el parámetro AllowKey no esta permitido si no se utiliza el parámetro DenyKey. Es decir que solo con parámetros AllowKey el Agente no arrancara.

- El orden importa. Los parámetros se chequean uno a uno dependiendo del orden en que aparecen, en cuanto uno machea con la regla definida, sea de allow o deny deja de procesar los siguientes.
  Por ejemplo si tenemos una regla de allow y deny que cumple la coincidencia con ambas, solo procesara la primera.  

- Esta soportado un numero ilimitado de parámetros AllowKey/DenyKey.

- El wildcard (*) representa cualquier carácter o numero dependiendo de la posición en la que este. Se puede utilizar tanto en el nombre de la key como en el parámetro.

- Si especificamos un ítem como no permitido, el agente reportara un mensaje de UNSOPPORTED. Esto es asi por motivos de seguridad.

- Zabbix agent utilizando la opción -p no mostrara las keys que no están permitidas.

- Zabbix agent utilizando la opción -t devolverá "Unsupported item key." como estado si la key no esta soportada por configuración.
 
- Los comandos denegados no se loguearan en el agente a pesar de que este habilitado el LogRemoreCommands=1

Algo de practica

La instalación por defecto no tiene definido un parámetro AllowKey y si por defecto tiene el parametro DenyKey=system.run[*]
- Esto quiere decir que no podemos ejecutar cosas como:
# zabbix_agentd -t system.run[cat /etc/passwd]
system.run[cat /etc/passwd]                   [m|ZBX_NOTSUPPORTED] [Unsupported item key.]

# zabbix_agentd -t system.run[ls -la /]
system.run[ls -la /]                          [m|ZBX_NOTSUPPORTED] [Unsupported item key.]
- Pero si podemos ejecutar cosas como:
# zabbix_agentd -t vfs.file.contents[/etc/passwd,*]
- Para poder ejecutar, tenemos que habilitar la Key antes de la de Deny y reiniciar el agente.
# vi /etc/zabbix/zabbix_agentd.conf
AllowKey=system.run[*]

# systemctl restart zabbix-agent.service
# zabbix_agentd -t system.run[ls -la /]
- Podemos restringir para no acceder al contenido del directorio /etc
# vi /etc/zabbix/zabbix_agentd.conf
DenyKey=vfs.file.contents[/etc/*,*]
DenyKey=vfs.file.*[/etc/*,*]

# systemctl restart zabbix-agent.service
- Pero si ejecutamos esto:
# zabbix_agentd -t vfs.file.contents[/tmp/../etc/passwd,*]
Nota: Pero seguramente no podremos evaluar todas las posibles acciones que alguien pueda ejecutar para lograr el acceso. De ahi que siempre en mejor tener una Whitelist detallada y finalizar con un DenyKey=*.


Ejemplos de Paterns

Accediendo a la API de Prometheus y PromQL desde Zabbix

Que es Prometheus?

Prometheus es una aplicación de software gratuita utilizada para la supervisión y alerta de eventos. Registra métricas en tiempo real en una base de datos de series de tiempo construida utilizando un modelo de extracción HTTP, con consultas flexibles y alertas en tiempo real.

Que es PromQL?

Es el lenguaje que desarrollo prometheus para hacer consultas.

Que podemos monitorizar?

   Este link los lleva a los diferentes exporters que existen en prometheus.
   https://prometheus.io/docs/instrumenting/exporters/

Arquitectura de lo que vamos a monitorizar

Tenemos instalado en una maquina 10 contenedores con NGINX, 1 Prometheus Server, 1 node_exporter, 1 cadvisor y 1 grafana.
Prometheus Server: Es la pieza central que realizara toda la monitorizacion y extraerá los datos de los exporters.
CAdvisor: Es el exporter que monitorizara los contenedores.
Grafana: Nos permitirá generar alguna grafica, también veremos como se integra nativamente con Prometheus.
Node_Exporter: Es el exportes que nos da métricas de sistema operativo (similar a lo que nos puede dar el agente de zabbix)

Descargar el Template

Media:Template PromQL Dockers.zip

URLs Útiles

Wikipedia           https://en.wikipedia.org/wiki/Prometheus_(software)
Prometheus          https://prometheus.io/
PromQL Basics       https://prometheus.io/docs/prometheus/latest/querying/basics/
Query Functions     https://prometheus.io/docs/prometheus/latest/querying/functions/
Operadores          https://prometheus.io/docs/prometheus/latest/querying/operators/
PromQL para humanos https://timber.io/blog/promql-for-humans/

Primeras consultas de PromQL

- Nos muestra los diferentes Targets y su estado si están Up o Down.
up
- Mejoramos la búsqueda para solo centrarnos en un Target especifico.
up{job="prometheus"}
- También podemos utilizar negación en las búsquedas utilizando el operador !=.
up{job!="prometheus"}
- Métricas que nos dan el uso Total de la CPU de los contenedores
container_cpu_usage_seconds_total
- Utilizando los filtros podemos extraer el de uno en particular utilizando el operador =~.
container_cpu_usage_seconds_total{name=~"nginx_port_8081_1"}

Nos retorna el uso de todas las CPUs que tiene el contenedor: cpu00 y cpu01
- Podemos combinar operadores para lograr un filtrado mas especifico.
container_cpu_usage_seconds_total{name=~"nginx_port_808.*",cpu="cpu00"}
- Podemos calcular el promedio de los últimos 5 minutos aplicando la función rate.
rate(container_cpu_usage_seconds_total{name=~"nginx_port_8081_1"}[5m])
- Otra métrica que nos retorna los cores que tienen el equipo.
machine_cpu_cores
- Con estos dos ultimas métricas podemos calculas el % de Uso de la CPU de un contenedor.
sum (rate (container_cpu_usage_seconds_total{name=~"nginx_port_8081_1"}[5m])) / sum (machine_cpu_cores) * 100

Nota: Obtenemos el promedio de CPU de los últimos 5m, los sumamos y lo dividimos por el numero de cores, además lo multiplicamos por 100 para obtener el %.
- Obtenemos solo la CPU de los contenedores de NGINX
container_cpu_usage_seconds_total{cpu!="",name=~"nginx.*"}
- Verificamos si hay 20 (2 Cores * 10 Containers)
count(container_cpu_usage_seconds_total{cpu!="",name=~"nginx.*"})
- Calculamos el uso de CPU de todos
sum (rate (container_cpu_usage_seconds_total{cpu!="",name=~"nginx.*"}[5m])) /  sum (machine_cpu_cores) * 100
- Crear un LLD con LLD Macros
container_cpu_usage_seconds_total{cpu=~"cpu00",name=~"nginx.*"}

API de Prometheus para realizar las consultas de PromQL desde Zabbix vía HTTP Agent

http://[PROMETHEUS_SERVER]:9090/api/v1/query?query=[QUERY]

LLD Overrides

Que es y para que se utiliza el LLD

Con los LLDs podemos realizar discoverys y automatizar la creacion de Items, triggers, Graph y Host Prototypes que son para decirlo de una forma facil, elementos genéricos que se aplicaran al dato que recuperemos en el discovery.

El ejemplo mas simple es el de un discovery de FS, no sabemos cuantos FS podemos tener en una maquina, pero si podemos verlos con el comando DF si fuera un linux, el LLD nos permite descubrir los FS y crear Items y triggers que los monitoricen

Pero también podemos tener la necesidad de que algunos de los items no sigan el patrón que nosotros queremos tener para todo lo que auto descubrimos, como puede ser un FS / no es igual que un /var o /home, ya que si el / se nos llena la maquina deja de funcionar, pero si el /var se llena, no podremos escribir logs pero la maquina seguirá operativa. Por este motivo podemos decidir que un FS puede tener una criticidad mayor que otro, con un umbral diferente, etc.

Templates y scripts

Media:LLD y LLD Overrides.7z

Links y Videos Relacionados
Termplates - Practica Lab 2: Low-Level Discovery - Mariano Obarrio curso Zabbix de 0 a 100
Zabbix 5.0 Monitoring Tutorials - LLD Overrides Explained - Dmitry Lambert
How To Use Zabbix Low Level Discovery - Zabbix Blog
Formato pre 4.2
{
  data: [
    { "{#CLAVE1}": "VALOR1", "{#CLAVE2}": "VALOR1" },
    { "{#CLAVE1}": "VALOR2", "{#CLAVE2}": "VALOR2" },
    { "{#CLAVE1}": "VALOR3", "{#CLAVE2}": "VALOR3" }
  ]
}
Formato Post 4.2
[
  { "{#CLAVE1}": "VALOR1", "{#CLAVE2}": "VALOR1" },
  { "{#CLAVE1}": "VALOR2", "{#CLAVE2}": "VALOR2" },
  { "{#CLAVE1}": "VALOR3", "{#CLAVE2}": "VALOR3" }
]

LLD Override (sobreescritura)

Con la relativamente nueva opcion de Override, vamos a sobreescribir algunas propiedades de los itemas, triggers , graficos o hosts en el momento del discovery.


Para los ejemplos utilizaremos los siguientes scripts
Script: nodos.sh 
#!/usr/bin/bash

cat <<EOF
[
  { "{#HOST}": "OSMaster01", "{#PATH}":"/OS/Master01", "{#DESC}": "OpenShift Nodo Master 1" },
  { "{#HOST}": "OSMaster02", "{#PATH}":"/OS/Master02", "{#DESC}": "OpenShift Nodo Master 2" },
  { "{#HOST}": "OSMaster03", "{#PATH}":"/OS/Master03", "{#DESC}": "OpenShift Nodo Master 3" },
  { "{#HOST}": "OSWorker01", "{#PATH}":"/OS/Worker01", "{#DESC}": "OpenShift Nodo Worker 1" },
  { "{#HOST}": "OSWorker02", "{#PATH}":"/OS/Worker02", "{#DESC}": "OpenShift Nodo Worker 2" },
  { "{#HOST}": "OSWorker03", "{#PATH}":"/OS/Worker03", "{#DESC}": "OpenShift Nodo Worker 3" },
  { "{#HOST}": "OSWorker04", "{#PATH}":"/OS/Worker04", "{#DESC}": "OpenShift Nodo Worker 4" },
  { "{#HOST}": "OSWorker05", "{#PATH}":"/OS/Worker05", "{#DESC}": "OpenShift Nodo Worker 5" }
]
EOF
Script: nodos-2.sh 
#!/usr/bin/bash

cat <<EOF
[
  { "{#HOST}": "OSMaster01", "{#PATH}":"/OS/Master01", "{#DESC}": "OpenShift Nodo Master 1" },
  { "{#HOST}": "OSMaster02", "{#PATH}":"/OS/Master02", "{#DESC}": "OpenShift Nodo Master 2" },
  { "{#HOST}": "OSMaster03", "{#PATH}":"/OS/Master03", "{#DESC}": "OpenShift Nodo Master 3" },
  { "{#HOST}": "OSWorker01", "{#PATH}":"/OS/Worker01", "{#DESC}": "OpenShift Nodo Worker 1" },
  { "{#HOST}": "OSWorker02", "{#PATH}":"/OS/Worker02", "{#DESC}": "OpenShift Nodo Worker 2" },
  { "{#HOST}": "OSWorker03", "{#PATH}":"/OS/Worker03", "{#DESC}": "OpenShift Nodo Worker 3" },
  { "{#HOST}": "OSWorker04", "{#PATH}":"/OS/Worker04", "{#DESC}": "OpenShift Nodo Worker 4" },
  { "{#HOST}": "OSWorker05", "{#PATH}":"/OS/Worker05", "{#DESC}": "OpenShift Nodo Worker 5" },
  { "{#HOST}": "OSWorker06", "{#PATH}":"/OS/Worker06", "{#DESC}": "OpenShift Nodo Worker 6" },
  { "{#HOST}": "OSWorker07", "{#PATH}":"/OS/Worker07", "{#DESC}": "OpenShift Nodo Worker 7" },
  { "{#HOST}": "OSWorker08", "{#PATH}":"/OS/Worker08", "{#DESC}": "OpenShift Nodo Worker 8" },
  { "{#HOST}": "OSWorker09", "{#PATH}":"/OS/Worker09", "{#DESC}": "OpenShift Nodo Worker 9" },
  { "{#HOST}": "OSWorker10", "{#PATH}":"/OS/Worker10", "{#DESC}": "OpenShift Nodo Worker 10" }
]
EOF
Script: getStatus.sh 
#!/usr/bin/bash

export PUSAGE=$(/usr/bin/shuf -i 0-100 -n 1)
export STATUS=$([ -f $1/down ] && echo 0 || echo 1;)

echo '{"status":'$STATUS', "pusage": '$PUSAGE'}'


Script: /etc/zabbix/zabbix_agent2.d/ldd_overrides.conf
UserParameter=cluster.discovery,/OS/nodos.sh
UserParameter=cluster.status[*],/OS/getStatus.sh $1
Esctructura de directorios
/OS
├── nodos.sh       <---- LLD que muestra los Nodos del Cluster.
├── nodos-2.sh     <---- LLD que crea nuevos Workers al Cluster.
├── getStatus.sh   <---- Script que simula estado de un nodo UP/DOWN  y el Porcentage de Utilizacion del mismo.  Ej. Respuesta: {"status": 1,"pusage": 35}
├── /OS/Master01
├── /OS/Master02
│   └── /OS/Master02/down       <---- Flag que indica el estado del nodo (DOWN). Si no dice nada esta UP 
├── /OS/Master03
├── /OS/Worker01
├── /OS/Worker02
├── /OS/Worker03
├── /OS/Worker04
├── /OS/Worker05
├── /OS/Worker06
├── /OS/Worker07
├── /OS/Worker08
├── /OS/Worker09
└── /OS/Worker10
Pruebas desde linea de comando
Vamos a verificar que todo este correctamente configurado.

# zabbix_agent2 -t cluster.discovery
# zabbix_agent2 -t cluster.status["/OS/Master01"]
# zabbix_agent2 -t cluster.status["/OS/Master02"]


- Vamos a ver lo mismo pero formateada la salida
# zabbix_get -s 127.0.0.1 -k cluster.discovery | jq
# zabbix_get -s 127.0.0.1 -k cluster.status["/OS/Master01"] | jq
# zabbix_get -s 127.0.0.1 -k cluster.status["/OS/Master02"] | jq

Zabbix utilizando Dockers (Parte 1)

Instalación de Dockers

# dnf update -y
# dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
# dnf list docker-ce
# dnf install docker-ce --nobest -y
# systemctl enable docker --now

Instalación de Docker-Compose

Doc. Oficial: https://docs.docker.com/compose/install/
# curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose
# ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
# docker-compose --version

Instalación de Zabbix

Doc. Oficial: https://www.zabbix.com/documentation/current/manual/installation/containers
Doc. Oficial: https://github.com/zabbix
Blog : https://www.zabbix.com/la/container_images https://blog.zabbix.com/zabbix-docker-containers/7150/
Docker YML: docker-compose.yml


# mkdir /docker
# cd /docker/
# git clone https://github.com/zabbix/zabbix-docker.git
# cd zabbix-docker/
# cp docker-compose_v3_centos_pgsql_latest.yaml docker-compose.yml
# docker-compose up
http://10.0.100.100

Configuración del Environment del Agent

.env_agent 
# ZBX_SOURCEIP=
# ZBX_DEBUGLEVEL=3
# ZBX_ENABLEREMOTECOMMANDS=0 # Deprecated since 5.0.0
# ZBX_LOGREMOTECOMMANDS=0
# ZBX_HOSTINTERFACE= # Available since 4.4.0
# ZBX_HOSTINTERFACEITEM= # Available since 4.4.0
# ZBX_SERVER_HOST=zabbix-server
ZBX_SERVER_HOST=zbx-server <- A donde se tiene que conectar el agente. Internamente en el stack de docker-compose el Zabbix Server tiene este nombre.
# ZBX_PASSIVE_ALLOW=true
# ZBX_PASSIVESERVERS=
# ZBX_ACTIVE_ALLOW=true
# ZBX_ACTIVESERVERS=
# ZBX_LISTENIP=
# ZBX_STARTAGENTS=3
# ZBX_HOSTNAME=
ZBX_HOSTNAME=Zabbix server <- Es el nombre que tiene el Host donde esta instalado el Zabbix Server.
# ZBX_HOSTNAMEITEM=system.hostname
# ZBX_METADATA=
# ZBX_METADATAITEM=
# ZBX_REFRESHACTIVECHECKS=120
# ZBX_BUFFERSEND=5
# ZBX_BUFFERSIZE=100
# ZBX_MAXLINESPERSECOND=20
# ZBX_ALIAS=""
# ZBX_TIMEOUT=3
# ZBX_UNSAFEUSERPARAMETERS=0
# ZBX_LOADMODULE="dummy1.so,dummy2.so,dummy10.so"
# ZBX_TLSCONNECT=unencrypted
# ZBX_TLSACCEPT=unencrypted
# ZBX_TLSCAFILE=
# ZBX_TLSCRLFILE=
# ZBX_TLSSERVERCERTISSUER=
# ZBX_TLSSERVERCERTSUBJECT=
# ZBX_TLSCERTFILE=
# ZBX_TLSKEYFILE=
# ZBX_TLSPSKIDENTITY=
# ZBX_TLSPSKFILE=
# ZBX_DENYKEY=system.run[*]
# ZBX_ALLOWKEY=

Configuración Agente desde Zabbix Frontend

Update DNS Name y Connect to
- Una vez actualizado el zabbix-frontend forzamos el refresh de la configuracion
# docker exec -it zbx-server zabbix_server -R config_cache_reload

Comandos utiles

- Reload de la config cache
# docker exec -it zbx-server zabbix_server -R config_cache_reload
- Acceder a un contenedor utilizando bash
# docker exec -it zbx-server bash
- Ver los logs de un contenedor
# docker logs zbx-server
# docker logs -f zbx-server
# docker logs -f zbx-agent
- Listar los contenedores activos
# docker ps
- Arrancar en Background
# docker-compose up -d
WARNING: The following deploy sub-keys are not supported and have been ignored: resources.reservations.cpus
WARNING: The following deploy sub-keys are not supported and have been ignored: resources.reservations.cpus
WARNING: The following deploy sub-keys are not supported and have been ignored: resources.reservations.cpus
WARNING: The following deploy sub-keys are not supported and have been ignored: resources.reservations.cpus
WARNING: The following deploy sub-keys are not supported and have been ignored: resources.reservations.cpus
Starting zbx-snmptraps                 ... done
Starting zbx-postgres                  ... done
Starting zbx-java-gateway              ... done
Starting zabbix-docker_db_data_pgsql_1 ... done
Starting zbx-server                    ... done
Starting zbx-frontend                  ... done
Starting zbx-agent                     ... done 
Nota: Importante estar parado en el directorio donde esta el YML (docker-compose.yml)
- Matar los contenedores
# docker-compose kill
WARNING: The following deploy sub-keys are not supported and have been ignored: resources.reservations.cpus
WARNING: The following deploy sub-keys are not supported and have been ignored: resources.reservations.cpus
WARNING: The following deploy sub-keys are not supported and have been ignored: resources.reservations.cpus
WARNING: The following deploy sub-keys are not supported and have been ignored: resources.reservations.cpus
WARNING: The following deploy sub-keys are not supported and have been ignored: resources.reservations.cpus
Killing zbx-agent        ... done
Killing zbx-frontend     ... done
Killing zbx-server       ... done
Killing zbx-snmptraps    ... done
Killing zbx-java-gateway ... done
Killing zbx-postgres     ... done 
Nota: Importante estar parado en el directorio donde esta el YML (docker-compose.yml)

Zabbix Agent en Docker (Parte 2)

Version Legacy: https://hub.docker.com/r/zabbix/zabbix-agent
Version Go    : https://hub.docker.com/r/zabbix/zabbix-agent2

Variable de entorno

ZBX_SOURCEIP=
ZBX_DEBUGLEVEL=3
ZBX_ENABLEREMOTECOMMANDS=0 # Deprecated since 5.0.0
ZBX_LOGREMOTECOMMANDS=0
ZBX_HOSTINTERFACE= # Available since 4.4.0
ZBX_HOSTINTERFACEITEM= # Available since 4.4.0
ZBX_SERVER_HOST=zabbix-server
ZBX_PASSIVE_ALLOW=true
ZBX_PASSIVESERVERS=
ZBX_ACTIVE_ALLOW=true
ZBX_ACTIVESERVERS=
ZBX_LISTENIP=
ZBX_STARTAGENTS=3
ZBX_HOSTNAME=
ZBX_HOSTNAMEITEM=system.hostname
ZBX_METADATA=
ZBX_METADATAITEM=
ZBX_REFRESHACTIVECHECKS=120
ZBX_BUFFERSEND=5
ZBX_BUFFERSIZE=100
ZBX_MAXLINESPERSECOND=20
ZBX_ALIAS=""
ZBX_TIMEOUT=3
ZBX_UNSAFEUSERPARAMETERS=0
ZBX_LOADMODULE="dummy1.so,dummy2.so,dummy10.so"
ZBX_TLSCONNECT=unencrypted
ZBX_TLSACCEPT=unencrypted
ZBX_TLSCAFILE=
ZBX_TLSCRLFILE=
ZBX_TLSSERVERCERTISSUER=
ZBX_TLSSERVERCERTSUBJECT=
ZBX_TLSCERTFILE=
ZBX_TLSKEYFILE=
ZBX_TLSPSKIDENTITY=
ZBX_TLSPSKFILE=
ZBX_DENYKEY=system.run[*]
ZBX_ALLOWKEY=

Docker run

# docker run --name zabbix-agent --hostname zbxclient01 -e ZBX_METADATA=7c92f1de9fa60db1f40c537f658bc799 -e ZBX_HOSTNAME="zbxclient01" -e ZBX_SERVER_HOST="10.0.100.100" -v /etc/localtime:/etc/localtime -v /etc/timezone:/etc/timezone -p 10050:10050 --privileged -d zabbix/zabbix-agent2:latest
# docker ps
# docker kill zabbix-agent
# docker rm zabbix-agent

Docker Compose

# mkdir -p /etc/zabbix
# cd /etc/zabbix
# vi docker-compose-agent5.2.1.yml 
version: '3.5'
services:
 zabbix-agent:
   image: zabbix/zabbix-agent:alpine-5.2-latest
   container_name: zabbix-agent
   hostname: zbxclient01
   environment:
    # - ZBX_HOSTNAME=zbxclient01
    - ZBX_SERVER_HOST=10.0.100.100
    - ZBX_PASSIVESERVERS=172.18.0.1/24
    - ZBX_METADATA=7c92f1de9fa60db1f40c537f658bc799
    - ZBX_TIMEOUT=30
    - ZBX_ALLOWKEY=system.run[*]
   ports:
    - "10050:10050"
   volumes:
    - /etc/localtime:/etc/localtime:ro
    - /etc/timezone:/etc/timezone:ro
    - ./docker/etc/zabbix/zabbix_agentd.d:/etc/zabbix/zabbix_agentd.d:ro
    - ./docker/var/lib/zabbix/modules:/var/lib/zabbix/modules:ro
    - ./docker/var/lib/zabbix/enc:/var/lib/zabbix/enc:ro
    - ./docker/var/lib/zabbix/ssh_keys:/var/lib/zabbix/ssh_keys:ro
   privileged: true
   pid: "host"
   stop_grace_period: 5s
   labels:
    com.zabbix.description: "Zabbix agent"
    com.zabbix.company: "Zabbix LLC"
    com.zabbix.component: "zabbix-agentd"
    com.zabbix.os: "alpine"
# docker-compose -f docker-compose-agent5.2.1.yml up

Comando utiles

# docker ps
# docker inspect zabbix-agent
# docker logs zabbix-agent
# docker kill zabbix-agent
# docker exec -it zabbix-agent bash
# docker-compose -f [file.yml] up -d
# docker-compose -f [file.yml] down

Extendiendo las funciones de Zabbix vía API

URLs útiles

https://www.zabbix.com/documentation/current/manual/api
https://www.zabbix.com/la/integrations/python
https://github.com/adubkov/py-zabbix
https://github.com/janssenlima/api-zabbix

Utilidades extras

# dnf install -y curl jq

Llamadas vía Postman

Download: Zabbix API.postman collection.json
Download: Zabbix API.postman collection Environment.json

Llamadas via CURL

[root@zbxclient01 ~]# curl -s -X POST -H 'Content-Type: application/json-rpc' -d '{"jsonrpc":"2.0","method":"apiinfo.version","id":1,"auth":null,"params":{}}' 'http://10.0.100.100/api_jsonrpc.php' | jq '.'
[root@zbxclient01 ~]# curl -s -X POST -H 'Content-Type: application/json-rpc' -d '{ "params": { "user": "Admin", "password": "zabbix" }, "jsonrpc": "2.0", "method": "user.login", "id": 0 }' 'http://10.0.100.100/api_jsonrpc.php' | jq '.'

Llamadas vía PY-ZABBIX

Instalación de py-zabbix
# dnf install -y python3
# python3 -V
# dnf -y groupinstall development # Instalacion de las herramientas de desarrollo de CentOS
# mkdir /environments
# cd /environments
# python3 -m venv py-zabbix
# ls -la py-zabbix/
# source /environments/py-zabbix/bin/activate
# pip install --upgrade pip
# pip install py-zabbix
- Script: demos1.py
#!/environments/py-zabbix/bin/python3

import sys
import logging

from pyzabbix.api import ZabbixAPI


# Create ZabbixAPI class instance
logger = logging.getLogger("pyzabbix")
logger.setLevel(logging.DEBUG)
handler = logging.StreamHandler(sys.stdout)
logger.addHandler(handler)

# Create ZabbixAPI class instance
zapi = ZabbixAPI(url='http://10.0.100.100/', user='Admin', password='zabbix')

# Get all monitored hosts
result1 = zapi.host.get(monitored_hosts=1, output='extend')

# Get all disabled hosts
result2 = zapi.do_request('host.get',
                          {
                              'filter': {'status': 1},
                              'output': 'extend'
                          })

# Filter results
hostnames1 = [host['host'] for host in result1]
hostnames2 = [host['host'] for host in result2['result']]

# Logout from Zabbix
zapi.user.logout()

Synthetic Monitoring

Host sin Interface

Podemos crear Hosts sin Interface, esto nos facilita crear monitorizaciones tipo WEB en la que no necesitamos tener un agente o no necesariamente nos interesa tener acceder por IP.

Synthetic Monitoring / Monitorizacion Sintética

Ver: https://www.zabbix.com/documentation/current/manual/config/items/itemtypes/script 
Ver: https://www.zabbix.com/documentation/current/manual/config/items/preprocessing/javascript/javascript_objects
- Item tipo SCRIPT
 {$CITYID}: 6533961
 {$APIKEY}: 38c34c5ecac040e795b448d5be3d62f4 
try {
  var URL = 'http://api.openweathermap.org/data/2.5/weather?id={$CITYID}&appid={$APIKEY}'; 
  var req = new CurlHttpRequest();
  req.AddHeader('Content-Type: application/json');
  result = req.Get(URL);
  Zabbix.Log(3, 'Host1::Line1::Script: '+result);
  if (req.Status() != 200) {
     throw 'Response code: '+req.Status();
  }
} catch (error) {
  Zabbix.Log(3, 'Host1::Line2::Script: '+error);
  result = {"Error": error};
}
Zabbix.Log(3, 'Host1::Line3::Script: '+JSON.stringify(req.GetHeaders()));
return result;

Integrando Vault de Hashicorp con Zabbix Parte 1 de 3

URLs de interes

Downloads    : https://www.vaultproject.io/downloads
Documentacion: https://www.vaultproject.io/docs
Tutorials    : https://learn.hashicorp.com/vault

Instalación vía Repositorio

$ curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
$ sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
$ sudo apt-get update && sudo apt-get install vault
$ vault

Arrancando el server en modo Desarrollo

Nota: Vault es la única pieza que interactúa entre el Storage y el Backend que en este caso es Zabbix.
Nota: Vault server en modo DEV es un server preconfigurado para poder desarrollar localmente, en memoria 
          y sin TLS, no es un server seguro y no esta recomendado para trabajar en producción, pero nos ayuda 
          a probar rápidamente el producto sin grandes configuraciones.
$ vault server -dev
- Configuramos VAUL_ADDR  que nos permitirá comunicar el cliente de VAULT con el server.
$ export VAULT_ADDR='http://127.0.0.1:8200'
- Guardamos el Unseal Key para utilizarla posteriormente.
Unseal Key: GSX5uoT2LcKcq6fchwMWbDWvwmiYfV5o1jWSoN0V/o0=
$ echo GSX5uoT2LcKcq6fchwMWbDWvwmiYfV5o1jWSoN0V/o0= >> /tmp/unseal.key
- Definimos la variable de entorno con el ROOT Token para utilizarlo luego
$ export VAULT_TOKEN="s.ZY9CuiX3glOk8cAPpcw8r5BI"

- Verificamos el estado del servicio

$ vault status
Key             Value
---             -----
Seal Type       shamir
Initialized     true
Sealed          false <-- Vault esta abierto lo que nos permite consultar secretos. Por defecto Vault arranca cerrado.
Total Shares    1
Threshold       1
Version         1.6.1
Storage Type    inmem
Cluster Name    vault-cluster-65dfa923
Cluster ID      2227808c-66a2-7277-5dc7-25e20a95366f
HA Enabled      false

Secretos

Almacenando el primer secreto
Los secretos son pares de clave/valor que podemos almacenar de forma segura. Lo podemos hacer utilizando la linea de comandos 
o vía la API que es como se comunica en realidad Zabbix.
- Vamos a escribir un secreto en el path secret/hello de clave foo y con valor world 
$ vault kv put secret/hello foo=world
Key              Value
---              -----
created_time     2021-01-07T11:30:39.577565342Z
deletion_time    n/a
destroyed        false
version          1
- Escribimos multiples datos
$ vault kv put secret/hello foo=world excited=yes
Recuperando un secreto
$ vault kv get secret/hello
$ vault kv get -field=excited secret/hello
Eliminando un secreto
$ vault kv delete secret/hello

Engines

Un secret engine es como un virtual filesystem al cual accedemos con operaciones de lectura, escritura y eliminación.
Por default Vault habilita el motor (Engine) KV (Key/Value) con el path secret. Por este motivo en el ejemplo anterior 
creamos el secreto en el path secret/ que es el que se habilita por default, si queremos crear en otro path nos daría 
error.
$ vault kv put zabbix/hello foo=world 
Error making API request.

URL: GET http://127.0.0.1:8200/v1/sys/internal/ui/mounts/zabbix/hello
Code: 403. Errors:

* preflight capability check returned 403, please ensure client's policies grant access to path "zabbix/hello/"
Podemos ver los diferentes secrets engines que tenemos activos en el server con el siguiente comando
$ vault secrets list
- El sys path corresponde al system backend. Este path interactua con Vault y no se recomienda utilizar sin saber que hacemos realmene.
- Hay muchos mas tipos de Engines que nos pueden ser utiles AWS: AWS IAM Access keys, Database: On-demand time-limited credentials.
- Si queremos habilitar un nuevo secret engine KV como podria ser zabbix lo hacemos de la siguiete manera. Por default el path es el nombre del engine.
$ vault secrets enable -path=zabbix kv
Success! Enabled the kv secrets engine at: zabbix/
$ vault kv put zabbix/hello foo=world
Success! Data written to: zabbix/hello
$ vault secrets list
$ vault kv get zabbix/hello
=== Data ===
Key    Value
---    -----
foo    world
Deshabilitar un Engine
$ vault secrets disable zabbix/
Success! Disabled the secrets engine (if it existed) at: zabbix/


Autenticación vía Tokens

La autenticación con tokens esta automáticamente habilitada cuando iniciamos un server en modo desarrollo. Durante el inicio nos muestra
el token de root. Vault CLI lee el token de root vía la variable de entorno VAULT_TOKEN. Este token nos permite realizar operaciones ya que
se le apilan las políticas de root y una de ellas es poder crear nuevos tokens.
Ver métodos de autenticación: https://www.vaultproject.io/docs/auth
Crear un nuevo token
$ vault token create
Key                  Value
---                  -----
token                s.E2iXdMDVnvDSawBolw86jiB6
token_accessor       fh7OrF7ESzMVgX1vvSFY8y1d
token_duration       ∞
token_renewable      false
token_policies       ["root"]
identity_policies    []
policies             ["root"]
Revocar un token
$ vault token revoke s.E2iXdMDVnvDSawBolw86jiB6

Listar los métodos de autenticación

$ vault auth list

Políticas de seguridad

Las políticas controlan el acceso de los usuarios. Vault utiliza el mismo formato para las autorizaciones como para las políticas.
Estas están escritas en formato HLC (Hashicorp Configuration Language) pero son compatibles con el formato JSON.
- Un ejemplo de politica es el siguiente
path "secret/data/*" {
  capabilities = ["create", "update"]
}

path "secret/data/foo" {
  capabilities = ["read"]
}
En este ejemplo podemos ver que el usuario que tenga esta política asignada podrá escribir secretos en secret/data/ pero no en 
secret/data/foo donde solo tiene permisos de lectura. La política por default es DENY, por esto un path no especificado es siempre 
denegado.
Existen algunas políticas pre-definidas que no se pueden eliminar, como son la de root y la default ya que son requeridas por el sistema.
La política por default provee y set de permisos comunes que se aplican a todos los tokens por defecto. 
La política de root da a los tokens de admin permisos similares a los de root en un sistema UNIX/Linux.

Ver la politica por default
$ vault policy read default
Escribir una política
$ vi /tmp/zabbix.hlc
path "zabbix/data/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}
$ vault policy write zabbix /tmp/zabbix.hlc
Success! Uploaded policy: zabbix

IMPORTANTE: El fichero con la politica tiene que estar creado previamente.

Listar las politicas definidas
$ vault policy list
Testear una politica
$ vault secrets enable -path=zabbix kv
$ vault policy write zabbix-ro - << EOF
path "zabbix/data/*" {
  capabilities = ["create", "update"]
}

path "zabbix/data/db" {
  capabilities = ["read"]
}
EOF
$ vault kv put zabbix/data/demo foo=world
$ vault kv put zabbix/data/db user=zabbix password=Z4bb1x
$ vault policy list
$ vault policy read zabbix-ro
$ vault token create -policy=zabbix-ro
Key                  Value
---                  -----
token                s.TSUxMni4P04xSVEuZwB7r1Qm
token_accessor       aCWQuPGmBDZBnMQdn44Zwrna
token_duration       768h
token_renewable      true
token_policies       ["default" "zabbix-ro"]
identity_policies    []
policies             ["default" "zabbix-ro"]
$ export VAULT_TOKEN=s.TSUxMni4P04xSVEuZwB7r1Qm
$ vault kv get zabbix/data/demo
$ vault kv get zabbix/data/db 
$ vault kv put zabbix/data/db user=nuevo password=nueva
$ vault kv put zabbix/data/demo val1=key1 val2=key2 val3=key3 val4=key4

Integración de Zabbix con Vault Parte 2 de 3

Iniciamos Vault

# systemctl enable vault.service --now
# systemctl status vault.service 
# cat /etc/vault.d/vault.hcl

Configuramos TLS

Instalamos Consul (Solo para crear los certificados)
Antes de comenzar la instalación y configuración de Vault, vamos a utilizar una utilidad que nos trae otro producto 
de Hashicorp que es CONSUL. Esta Utilidad nos permitirá crear certificados de server y cliente de forma fácil y rápida.
Como ya tenemos el repositorio de Hashicorp configurado, vamos a instalar consul.
# sudo -i 
# apt-get install consul
Creamos la CA
# cd /opt/vault/tls/
# consul tls ca create -days=3650 -domain=zabbix-es.com.es
Creamos el certificado para el Server
# consul tls cert create -server \
                        -ca ./zabbix-es.com.es-agent-ca.pem \
                        -key ./zabbix-es.com.es-agent-ca-key.pem \
                        -days=3650 \
                        -domain="zabbix-es.com.es" \
                        -additional-dnsname=zbxsrv01 \
                        -additional-dnsname=*.zabbix-es.com.es \
                        -additional-ipaddress=10.0.100.100
==> Saved dc1-server-zabbix-es.com.es-0.pem          <-- Es tls_cert_file
==> Saved dc1-server-zabbix-es.com.es-0-key.pem      <-- Es tls_key_file
# vi /etc/vault.d/vault.hcl
  tls_cert_file = "/opt/vault/tls/dc1-server-zabbix-es.com.es-0.pem"
  tls_key_file  = "/opt/vault/tls/dc1-server-zabbix-es.com.es-0-key.pem"
# chown vault:vault *.pem
# systemctl restart vault
# systemctl status vault
# cp /opt/vault/tls/zabbix-es.com.es-agent-ca.pem /usr/local/share/ca-certificates/vault.crt
# update-ca-certificates --fresh
Nota: en Centos se hace así:
# cp /opt/vault/tls/zabbix-es.com.es-agent-ca.pem /etc/pki/ca-trust/source/anchors/vault.crt
# update-ca-trust extract
Create a certificate for clients
# consul tls cert create -client \
                        -ca ./zabbix-es.com.es-agent-ca.pem \
                        -key ./zabbix-es.com.es-agent-ca-key.pem \
                        -days=3650 \
                        -domain="zabbix-es.com.es" \
                        -additional-dnsname=zbxsrv01 \
                        -additional-dnsname=zabbix-es.com.es \
                        -additional-ipaddress=10.0.100.100
==> Saved dc1-client-zabbix-es.com.es-0.pem
==> Saved dc1-client-zabbix-es.com.es-0-key.pem
Creamos el certificado P12 para el navegador
# openssl pkcs12 -export \
                -out  dc1-client-zabbix-es.com.es.p12 \
                -inkey dc1-client-zabbix-es.com.es-0-key.pem \
                -in  dc1-client-zabbix-es.com.es-0.pem \
                -passout pass:zabbix-es
# cp dc1-client-zabbix-es.com.es.p12 /tmp
# chmod 644 /tmp/*.p12
Desinstalamos Consul
# apt-get remove consul

Inicializamos Vault por primera vez

# vault operator init >> ~/vault.keys
Unseal Key 1: iSAbkHZgwZTzv4XDpcrfIQvOi03LerIGIP2GuX+fUWCq
Unseal Key 2: lVWXx7q3AU8c6es0WwY0tVBuDOiWuwYsKrfFhE6uA7u1
Unseal Key 3: oppxtaLawQa9o189e77SLqml+e4IQlokgZfxDTCRI4DS
Unseal Key 4: kRw9RFfgyX3zNDsXD1aZ/KMb71lIpgBoUBgAoTbm6YcP
Unseal Key 5: J7ytYxQ9EVk51fWtZurhxbDtiC+MevwgrRDRsL3JJP02

Initial Root Token: s.r6MpoIkB3BCm6lKf8OnUSbOx

Vault 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.
IMPORTANTE: Resguardamos las keys.

Realizamos el Unseal. Ejecutamos el comando 3 veces con diferentes Keys, para que sea efectivo

# export VAULT_ADDR=https://127.0.0.1:8200
# export VAULT_TOKEN="s.r6MpoIkB3BCm6lKf8OnUSbOx"
# vault operator unseal 

# vault login
# vault secrets enable -path=zabbix kv-v2
# vault kv put zabbix/database username=zabbix password=Z4bb1x
# vault kv put zabbix/macros macro1=data macro2=data macro3=data
# vault kv get zabbix/macros
# vault kv get zabbix/database
Creamos la Política para el acceso del Zabbix Frontend
# vault policy write zabbix-fe - << EOF
path "zabbix/data/database" {
  capabilities = [ "list", "read" ]
}
EOF
Creamos un token de acceso para el Zabbix Frontend
# vault token create -policy=zabbix-fe
Key                  Value
--                  -----
token                s.aDvcS1U6Q5sV11Trn7wwqcaj
token_accessor       CSyGBqeGWK6vVGkIEGRBaVbJ
token_duration       768h
token_renewable      true
token_policies       ["default" "zabbix-fe"]
identity_policies    []
policies             ["default" "zabbix-fe"]
Creamos la Política para el acceso del Zabbix Server
# vault policy write zabbix-server - << EOF
path "zabbix/data/database" {
   capabilities = [ "list", "read" ]
}
path "zabbix/data/macros" {
   capabilities = [ "list", "read" ]
}
EOF
Creamos un token de acceso para el Zabbix Server
# vault token create -policy=zabbix-server
Key                  Value
---                  -----
token                s.fCfTljeF2iwuQmAEbrHoqK9t
token_accessor       4tckwVS4H12PuJWDvbamRAL9
token_duration       768h
token_renewable      true
token_policies       ["default" "zabbix-server"]
identity_policies    []
policies             ["default" "zabbix-server"]
Seteamos el token del SERVER y hacemos pruebas
# export VAULT_ADDR=https://zbxsrv01:8200
# export VAULT_TOKEN=s.fCfTljeF2iwuQmAEbrHoqK9t
# vault kv get zabbix/database
# vault kv get zabbix/macros
Seteamos el token del FE que no tiene acceso al path zabbix/macros
# export VAULT_TOKEN=s.aDvcS1U6Q5sV11Trn7wwqcaj
# vault kv get zabbix/macros
Error reading zabbix/data/macros: Error making API request.

URL: GET https://zbxsrv01:8200/v1/zabbix/data/macros
Code: 403. Errors:

* 1 error occurred:
        * permission denied

Nos Conectamos vía UI

https://10.0.100.100:8200

Copia de seguridad

En este modelo de instalación, vault utiliza como storage backend el filesystem, con lo cual simplemente tenemos que realizar una copia 
del directorio /opt/vault/data. Es importante destacar que si en el momento de la copia se están actualizando los secretos estos 
no se almacenaran en la misma.
- Un ejemplo de copia podría se el siguiente.
# cd /
# tar zcvf 20210109.Vault.tgz /etc/vault.d/vault.hcl /opt/vault/

Integración de Zabbix con Vault Parte 3 de 3

URLs importantes

Documentación oficial
Keep All Secrets Encrypted and Secure - Video
Keep All Secrets Encrypted and Secure - PDF
Workshop: How to use external Vault with Zabbix
Resumen del Workshop: How to use external Vault with Zabbix

Repaso de lo que ya tenemos que tener en VAULT

# export VAULT_TOKEN=s.I4ITVLlPD8uHJqMlLR7FaTfL <- Token de ROOT
# export VAULT_ADDR=https://zbxsrv01:8200
- Habilitamos el punto de montaje/path "secret/" si no existe. 
  Por default Vault lo habilita. Es muy importante utilizar la version de Engine kv-v2.
$ vault secrets enable -path=zabbix/ kv-v2
- Creamos los secretos con el usuario y la password de la base de datos bajo el punto de montaje "secret/" en el path "secret/zabbix/database"
# vault kv put zabbix/database username=zabbix password=Z4bb1x
# vault kv put zabbix/macros macro1=valor1 macro2=valor2 macro3=valor3
- Creamos las ACLs
# vault policy write zabbix-fe - << EOF
path "zabbix/data/database" {
  capabilities = [ "list", "read" ]
}
EOF
# vault policy write zabbix-server - << EOF
path "zabbix/data/database" {
   capabilities = [ "list", "read" ]
}
path "zabbix/data/macros" {
   capabilities = [ "list", "read" ]
}
EOF
- Verificamos si se creo correctamente leyéndolo.
# vault kv get zabbix/database
# vault kv get zabbix/macros
- Finalmente testeamos desde CURL si podemos acceder a los secretos. 
  Es importante que cuando accedemos via API hay que especificar la versión "v1" antes de secret y "data" después de el.
# curl -s --header "X-Vault-Token: s.oXhWTKrtwKTTBu3qOwdt0GOo" https://127.0.0.1:8200/v1/zabbix/data/database | jq

Configuración de Zabbix Server para que utilice Vault

Ver Documentación oficial: https://zabbix.com/documentation/current/manual/appendix/config/zabbix_server?s[]=vault
- Si queremos utilizar VAULT hay que comentar las opciones DBUser, DBPassword en el zabbix_server.conf
- Nos vamos al final del fichero de configuración e incluimos los siguientes parámetros.
# vi /lib/systemd/system/zabbix-server.service
[Service]
Environment="VAULT_TOKEN=s.DigehEgc2TIrswXeIF1C2204" <-- Token de zabbix-server
NOTA: Es una mejor opción definir el VAULT_TOKEN como una variable de entorno dentro del script de SYSTEMD y comentar la entrada VaultToken.

# systemctl daemon-reload 
# systemctl restart zabbix-server.service
# vi /etc/zabbix/zabbix_server.conf 
# DBUser=zabbix
# DBPassword=Z4bb1x
# VaultToken= <- No hace falta ya que la especificamos como una variable de entorno en el script de systemd.
                 Si no lo especificamos en ninguno de los dos lugares, tendremos un mensaje de error del tipo 
                 ERROR: cannot initialize database credentials from vault: "VaultToken" configuration parameter or "VAULT_TOKEN" environment variable should be defined
                
VaultURL=https://zbxsrv01:8200
VaultDBPath=zabbix/database
# systemctl status zabbix-server.service
# systemctl restart zabbix-server.service
# systemctl status zabbix-server.service 
# tail -f /var/log/zabbix/zabbix_server.log

Configuramos de Zabbix-Frontend para que utilice Vault

Configuración vía GUI
Nota: Podemos tocar los ficheros manualmente o utilizar el GUI de Zabbix-Frontend http://10.0.100.100/setup.php
- Vamos a Configure DB connection
Store credentials in      : Hashicorp Vault
Vault API endpoint        : https://zbxsrv01:8200
Vault secret path         : zabbix/database
Vault authentication token:   
Configuración desde consola
# vi /etc/zabbix/web/zabbix.conf.php
$DB['USER']                     = ;
$DB['PASSWORD']                 = ;
$DB['VAULT_URL']                = 'https://zbxsrv01:8200';
$DB['VAULT_DB_PATH']            = 'zabbix/database';
$DB['VAULT_TOKEN']              = 's.oXhWTKrtwKTTBu3qOwdt0GOo';
# systemctl restart nginx php7.4-fpm
- Por ultimo almacenamos macros secretas en Vault desde el Zabbix Frontend.
 Vamos a un host, Macros y creamos una macro
 Macro         Value
 {$MACRO1}     zabbix/macros:macro1 Tipo Vault Secret
 {$MACRO2}     zabbix/macros:macro2 Tipo Vault Secret
 {$MACRO3}     zabbix/macros:macro3 Tipo Vault Secret
Nota:Hay que crearlas en VAULT en el mismo PATH para luego poder utilizarlas desde Zabbix-FE.
# zabbix_server -R config_cache_reload

Creando Hosts Via la Zabbix API

URLs de importancia

Script addHosts

#!/usr/bin/bash

# Recupera el token post Login
export TOKEN=$(curl -s -H "Content-type: application/json-rpc" -X POST http://localhost/api_jsonrpc.php -d'
{
   "jsonrpc": "2.0",
   "method": "user.login",
   "params": {
      "user": "Admin",
      "password": "zabbix"
   },
   "id": 1
}' | jq -r .result)

# Lee el fichero de Hosts y los crea en zabbix via API
while read line; do
 HOSTNAME="$(cut -d':' -f1 <<< "$line")"
 IPADDR="$(cut -d':' -f2 <<< "$line")"
 DESCRIPCION="$(cut -d':' -f3 <<< "$line")"

 CDATA(){
  cat <<EOF
{
    "jsonrpc": "2.0",
    "method": "host.create",
    "params": {
        "host": "${HOSTNAME}",
        "interfaces": [
            {
                "type": 1,
                "main": 1,
                "useip": 1,
                "ip": "${IPADDR}",
                "dns": "",
                "port": "10050"
            }
        ],
        "groups": [
            {
                "groupid": "5"
            }
        ],
        "tags": [
            {
                "tag": "Host name",
                "value": "${DESCRIPCION}"
            }
        ],
        "templates": [
            {
                "templateid": "10186"
            }
        ]
    },
    "auth": "${TOKEN}",
    "id": 1
}
EOF
}

 # Realiza la llamada para crear los hosts
 curl -s -H "Content-type: application/json-rpc" -X POST http://localhost/api_jsonrpc.php --data "$(CDATA)"
done<listado_hosts
# cat listado_hosts 
host01:192.168.1.10:Incluido por API 01
host02:192.168.1.11:Incluido por API 02
host03:192.168.1.12:Incluido por API 03
host04:192.168.1.13:Incluido por API 04
host05:192.168.1.14:Incluido por API 05
host06:192.168.1.15:Incluido por API 06
host07:192.168.1.16:Incluido por API 07
host08:192.168.1.17:Incluido por API 08
host09:192.168.1.18:Incluido por API 09
host10:192.168.1.19:Incluido por API 10
host11:192.168.1.20:Incluido por API 11
host12:192.168.1.21:Incluido por API 12
host13:192.168.1.22:Incluido por API 13
host14:192.168.1.23:Incluido por API 14
host15:192.168.1.24:Incluido por API 15
host16:192.168.1.25:Incluido por API 16
host17:192.168.1.26:Incluido por API 17
host18:192.168.1.27:Incluido por API 18

Instalación de Agentes en múltiples plataformas

Zabbix Agent Ubuntu

# wget https://repo.zabbix.com/zabbix/5.2/ubuntu/pool/main/z/zabbix-release/zabbix-release_5.2-1+ubuntu20.04_all.deb
# dpkg -i zabbix-release_5.2-1+ubuntu20.04_all.deb
# apt update
# apt install zabbix-agent

Zabbix Agent Raspbian

# wget https://repo.zabbix.com/zabbix/5.2/raspbian/pool/main/z/zabbix-release/zabbix-release_5.2-1+debian10_all.deb
# dpkg -i zabbix-release_5.2-1+debian10_all.deb
# apt update
# apt install zabbix-agent

Zabbix Agent Solaris 11.4

# groupdel zabbix
# useradd -d /etc/zabbix -g zabbix zabbix 
# passwd -l zabbix
# cat /etc/passwd

# cd /var/svc/manifest/site
# vi zabbix-agent.xml
<?xml version='1.0'?>
<!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'>
<service_bundle type='manifest' name='export'>
  <service name='system/zabbix-agent' type='service' version='0'>
    <create_default_instance enabled='true' complete='true'/>
    <single_instance/>
    <dependency name='ns' grouping='require_all' restart_on='none' type='service'>
      <service_fmri value='svc:/milestone/name-services'/>
    </dependency>
    <dependency name='usr' grouping='require_all' restart_on='none' type='service'>
      <service_fmri value='svc:/system/filesystem/local'/>
    </dependency>
    <dependent name='cron_multi-user' restart_on='none' grouping='optional_all'>
      <service_fmri value='svc:/milestone/multi-user'/>
    </dependent>
    <exec_method name='refresh' type='method' exec=':kill -THAW' timeout_seconds='60'/>
    <exec_method name='start' type='method' exec='/lib/svc/method/svc-zabbix-agent' timeout_seconds='60'>
      <method_context>
        <method_credential user='zabbix' group='zabbix' trusted_path='false'/>
      </method_context>
    </exec_method>
    <exec_method name='stop' type='method' exec=':kill' timeout_seconds='60'/>
    <property_group name='general' type='framework'>
      <propval name='action_authorization' type='astring' value='solaris.smf.manage.cron'/>
    </property_group>
    <property_group name='startd' type='framework'>
      <propval name='ignore_error' type='astring' value='core,signal'/>
    </property_group>
    <stability value='Unstable'/>
    <template>
      <common_name>
        <loctext xml:lang='C'>Zabbix agent</loctext>
      </common_name>
    </template>
  </service>
</service_bundle>

# vi /lib/svc/method/svc-zabbix-agent
#!/usr/sbin/sh
#
# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
#

. /lib/svc/share/smf_include.sh

case "$1" in
'start')
        if smf_is_nonglobalzone; then
                smf_method_exit $SMF_EXIT_TEMP_DISABLE local_zone \
                        "$SMF_FMRI is not supported in a local zone"
        fi

        [ ! -x /etc/zabbix/sbin/zabbix_agentd ] && exit $SMF_EXIT_ERR_CONFIG

        /etc/zabbix/sbin/zabbix_agentd -c /etc/zabbix/conf/zabbix_agentd.conf
        err=$?
        if [ $err -ne 0 ]; then
                echo "zabbix-agent failed to start: error $err"
                exit $SMF_EXIT_ERR_FATAL
        fi
        ;;

*)
        echo "Usage: $0 { start }"
        exit $SMF_EXIT_ERR_FATAL
        ;;


esac

exit $SMF_EXIT_OK

# chmod +x /lib/svc/method/svc-zabbix-agent
# svcadm restart svc:/system/manifest-import
# svccfg import zabbix-agent.xml 

Zabbix Agent AMI Linux

# rpm -Uvh https://repo.zabbix.com/zabbix/5.2/rhel/6/x86_64/zabbix-release-5.2-1.el6.noarch.rpm
# yum clean all
# yum install zabbix-agent
# service zabbix-agent restart
# chkconfig --level 35 zabbix-agent on

Zabbix Agent Debian

# wget https://repo.zabbix.com/zabbix/5.2/debian/pool/main/z/zabbix-release/zabbix-release_5.2-1+debian10_all.deb
# dpkg -i zabbix-release_5.2-1+debian10_all.deb
# apt update
# apt install zabbix-agent