◆ ¿Por qué Zabbix 7.0 LTS y no 8.0?
Al 2026-07-01, Zabbix 8.0 sigue en Release Candidate (no ha alcanzado
GA). Instalar RC en producción es aceptable únicamente en un lab; en cualquier cliente
se instala Zabbix 7.0 LTS (7.0.27): soporte activo hasta 2027 y de
seguridad hasta junio 2029. Cuando 8.0 lleve ~6 meses en GA (probable
inicio de 2027), este tutorial se actualizará y se documentará el path de upgrade
7.0 → 8.0 sin pérdida de datos.
ⓘ Contexto arquitectónico — leer antes de la fase 1
Zabbix se compone de cuatro procesos que corren en la misma VM:
- zabbix-server — el motor. Recolecta datos, procesa triggers, dispara alertas. Se conecta a la DB.
- zabbix-agent2 — daemon liviano en cada host monitoreado (incluyendo el propio servidor).
- frontend PHP — la web UI, servida por Nginx + PHP-FPM. Habla con la DB directamente.
- PostgreSQL 16 — persistencia. Todo (config, history, eventos) vive aquí.
En clientes grandes conviene separar la DB en otra VM. Para lab y clientes chicos
(≤ 200 hosts), todo en una sola VM está bien.
FQDN de la VM
zbx.lab.harper.local
Ajusta al DNS del cliente
IP sugerida
192.168.0.230
IP libre en la red del lab
Puertos abiertos (LAN)
22 · 80 · 443 · 10051
10051 = puerto activo del server hacia agents (tráfico entrante)
Puerto del agent
10050 (en cada host)
Solo abierto en hosts monitoreados hacia el server
DB
postgres 16 · db=zabbix · user=zabbix
Contraseña se genera en la fase 4
Web
https://zbx.lab.harper.local/
Certbot en la fase 10; auto-firmado interno mientras tanto
01
Clonar la VM desde la plantilla cloud-init en Proxmox
Meta: tener una VM Ubuntu 24.04 recién nacida con IP fija, hostname, llave SSH del usuario y updates aplicados — lista para instalar servicios.
1.1 Localizar la plantilla base
En el Proxmox del lab ya existe la plantilla ubuntu-24.04-cloudinit
(VMID normalmente 9000). Antes de clonar, confirma que existe y anota su VMID.
Ejecutar enhost: proxmox (SSH root@pve)
qm list | awk 'NR==1 || /template/ || /ubuntu.*24|ubuntu2404|cloudinit/i'
VMID NAME STATUS MEM(MB) BOOTDISK(GB) PID
9000 ubuntu-24.04-cloudinit stopped 2048 10.00 0
1.2 Elegir el VMID nuevo y clonar
Convención Harper: los servicios "core" del lab van en el rango 200–299.
Zabbix quedará como VMID 230. Cambia el nombre si tu convención es otra.
Ejecutar enhost: proxmox
# Clon "linked" (rápido, comparte disco base) desde snapshot de la plantilla.
# Si tu plantilla no tiene snapshot, usa "full" en vez de "linked".
qm clone 9000 230 \
--name zbx-lab \
--description "Zabbix 7.0 LTS server · Ubuntu 24.04 · lab Harper" \
--full 0 --pool lab
⚠ Si el clone falla con "no snapshot found"
La plantilla no tiene snapshot base — usa --full 1 (clon completo,
ocupa disco entero pero funciona sin snapshot). Anótalo en el ticket para que se
añada el snapshot a la plantilla luego.
1.3 Ajustar recursos y arranque
Ejecutar enhost: proxmox
# Recursos: 2 vCPU + 4 GB RAM. Disco a 40 GB (crece si el cliente monitorea muchos hosts).
qm set 230 --cores 2 --sockets 1 --cpu host --memory 4096 --balloon 0
qm resize 230 scsi0 40G
# Configurar el cloud-init (usuario, llave SSH, red estática).
# El password es de emergencia — el acceso real es por llave SSH.
qm set 230 \
--ciuser rbatista \
--sshkeys ~/.ssh/dojo_authorized_keys \
--ipconfig0 ip=192.168.0.230/24,gw=192.168.0.1 \
--nameserver "192.168.0.1 1.1.1.1" \
--searchdomain lab.harper.local
# Regenerar la imagen cloud-init (si no, los cambios no se aplican al primer boot).
qm cloudinit update 230
1.4 Arrancar y esperar el primer boot
Ejecutar enhost: proxmox
# Configurar arranque al boot del host + iniciar.
qm set 230 --onboot 1
qm start 230
# Esperar al agent (cloud-init tarda ~40-60s el primer boot).
until qm agent 230 ping 2>/dev/null; do echo "esperando cloud-init..."; sleep 5; done
qm agent 230 network-get-interfaces | jq -r '.[] | select(.name!="lo").["ip-addresses"][]?."ip-address"'
192.168.0.230
fe80::be24:11ff:fe7f:9d2a
✓ Verificación de la fase
Desde tu máquina, deberías poder hacer SSH sin password (llave ya inyectada por
cloud-init) y ver Ubuntu 24.04 arriba.
Ejecutar enhost: local (tu laptop)
ssh rbatista@192.168.0.230 "hostnamectl; lsb_release -d; ip -brief a; uptime"
Static hostname: zbx-lab
Icon name: computer-vm
Chassis: vm 🖴
Machine ID: 3f2c...
Operating System: Ubuntu 24.04.2 LTS
Kernel: Linux 6.8.0-45-generic
Description: Ubuntu 24.04.2 LTS
lo UNKNOWN 127.0.0.1/8 ::1/128
ens18 UP 192.168.0.230/24 fe80::be24:11ff:fe7f:9d2a/64
08:14:32 up 1 min, 1 user, load average: 0.15, 0.05, 0.02
02
Post-instalación de la VM: hostname, updates, hardening SSH
Meta: la VM queda alineada con el estándar Harper — hostname correcto, sistema actualizado, sudo sin password para el usuario base, SSH sin password ni root login.
2.1 Fijar hostname y timezone
Ejecutar enhost: vm (ssh a zbx-lab)
sudo hostnamectl set-hostname zbx-lab.lab.harper.local
sudo timedatectl set-timezone America/Santo_Domingo
# Verificar
hostnamectl
timedatectl
2.2 Aplicar todas las actualizaciones + kernel
Ejecutar enhost: vm
sudo apt update
sudo DEBIAN_FRONTEND=noninteractive apt -y full-upgrade
sudo apt -y install curl wget gnupg2 lsb-release ca-certificates \
ufw fail2ban unattended-upgrades chrony jq htop net-tools bash-completion
# Si actualizó el kernel: reiniciar.
[ -f /var/run/reboot-required ] && sudo reboot
💡 Buena práctica — updates automáticos de seguridad
unattended-upgrades ya se instaló arriba. Por defecto aplica solo
parches de seguridad todos los días a las 06:00 y reinicia si es indispensable.
Confirma con sudo systemctl status unattended-upgrades.
2.3 Sudo sin password para el usuario base (opcional pero recomendado en lab)
Ejecutar enhost: vm
echo "rbatista ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/90-rbatista
sudo chmod 440 /etc/sudoers.d/90-rbatista
sudo visudo -c # valida sintaxis; debe decir "parsed OK"
2.4 Hardening SSH
Solo llaves, sin root login, límite de intentos. Guardamos los cambios en un archivo
drop-in (/etc/ssh/sshd_config.d/) para no tocar el original de Ubuntu.
Ejecutar enhost: vm
sudo tee /etc/ssh/sshd_config.d/50-harper.conf >/dev/null <<'EOF'
# --- Harper SSH hardening baseline ---
PasswordAuthentication no
PermitRootLogin no
KbdInteractiveAuthentication no
MaxAuthTries 3
LoginGraceTime 30
X11Forwarding no
ClientAliveInterval 300
ClientAliveCountMax 2
EOF
sudo sshd -t && sudo systemctl reload ssh
⚠ Antes de cerrar la sesión SSH actual
Abre una segunda sesión SSH en paralelo y valida que puedes entrar
con tu llave. Si funciona, cierras la primera. Si no, la primera queda como red de
seguridad para revertir.
2.5 Firewall base (UFW)
Todavía no abrimos 80/443/10051; solo dejamos SSH por ahora. Los puertos del stack se abrirán al final, cuando cada componente esté funcionando.
Ejecutar enhost: vm
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw --force enable
sudo ufw status verbose
✓ Verificación
ssh root@192.168.0.230 debe fallar con "Permission denied" antes de pedir password. Un intento por SSH con password debe rechazarse.
03
Instalar PostgreSQL 16 como backend
Meta: PostgreSQL 16 corriendo, escuchando solo en localhost, con parámetros de rendimiento ajustados y timezone en UTC (requisito de Zabbix).
◆ ¿Por qué PostgreSQL y no MySQL/MariaDB?
Zabbix soporta ambas. Elegimos PostgreSQL porque: (1) es la DB recomendada por
Zabbix desde 7.0 y donde ellos concentran las mejoras, (2) integra
TimescaleDB como extensión nativa (hypertables para métricas),
(3) mejor comportamiento con particionado automático de history. En
cliente que ya tenga MariaDB desplegado por otras apps, la ruta MariaDB también es
válida — la doc oficial cubre ambos flujos.
3.1 Instalar PostgreSQL 16 desde el repo oficial de PGDG
Ubuntu 24.04 trae PostgreSQL 16 en sus repos base, pero preferimos el repo
PGDG (PostgreSQL Global Development Group) — recibe minor updates de
seguridad antes que el repo Ubuntu.
Ejecutar enhost: vm
sudo install -d /usr/share/postgresql-common/pgdg
sudo curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc \
--fail https://www.postgresql.org/media/keys/ACCC4CF8.asc
echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] \
https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" | \
sudo tee /etc/apt/sources.list.d/pgdg.list
sudo apt update
sudo apt -y install postgresql-16 postgresql-contrib-16
3.2 Verificar que arrancó y qué versión quedó
Ejecutar enhost: vm
systemctl status postgresql --no-pager
sudo -u postgres psql -c "select version();"
version
--------------------------------------------------------------------------------------------------
PostgreSQL 16.9 (Ubuntu 16.9-1.pgdg24.04+1) on x86_64-pc-linux-gnu, compiled by gcc 13.2.0, 64-bit
3.3 Tuning mínimo para Zabbix
Los defaults de Postgres son conservadores. Ajustamos shared_buffers,
effective_cache_size y work_mem proporcional a la RAM (4 GB).
Si escalas la VM más adelante, recalculas.
Ejecutar enhost: vm
sudo tee /etc/postgresql/16/main/conf.d/50-harper-zabbix.conf >/dev/null <<'EOF'
# --- Harper baseline para Zabbix 7.0 (VM 4 GB RAM) ---
listen_addresses = 'localhost'
shared_buffers = 1GB # ~25% de RAM
effective_cache_size = 3GB # ~75% de RAM
work_mem = 16MB # por operación de sort
maintenance_work_mem = 256MB
wal_buffers = 16MB
checkpoint_completion_target = 0.9
random_page_cost = 1.1 # asumimos SSD
max_connections = 100
timezone = 'UTC' # requisito Zabbix
log_timezone = 'UTC'
EOF
# Debe estar en UTC — Zabbix guarda todo en UTC y convierte en el frontend.
sudo systemctl restart postgresql
sudo -u postgres psql -c "show timezone;"
✓ Verificación
ss -ltnp | grep 5432 debe mostrar Postgres escuchando SOLO en
127.0.0.1:5432. Ningún cliente externo puede conectarse — como debe ser.
04
Crear la base de datos y el usuario de Zabbix
Meta: existe la DB zabbix, el usuario zabbix con password fuerte, y la contraseña queda guardada de forma segura en /root/.zabbix-db-pass.
4.1 Generar el password y guardarlo
Ejecutar enhost: vm
# Generar 32 caracteres random URL-safe.
ZBX_DB_PASS="$(openssl rand -base64 32 | tr -d '=+/' | cut -c1-32)"
# Guardar para uso futuro (backups, upgrades) — solo root.
echo "$ZBX_DB_PASS" | sudo tee /root/.zabbix-db-pass >/dev/null
sudo chmod 600 /root/.zabbix-db-pass
echo "Password guardado en /root/.zabbix-db-pass"
4.2 Crear el usuario y la DB
Zabbix 7.0 requiere la base creada con encoding UTF-8 y locale
C — evitar collation locale-dependant que causa slowdowns.
Ejecutar enhost: vm
sudo -u postgres psql <<EOF
CREATE USER zabbix WITH PASSWORD '$(sudo cat /root/.zabbix-db-pass)';
CREATE DATABASE zabbix
OWNER zabbix
ENCODING 'UTF8'
LC_COLLATE 'C'
LC_CTYPE 'C'
TEMPLATE template0;
GRANT ALL PRIVILEGES ON DATABASE zabbix TO zabbix;
\c zabbix
GRANT ALL ON SCHEMA public TO zabbix;
EOF
✓ Verificación
Ejecutar enhost: vm
PGPASSWORD="$(sudo cat /root/.zabbix-db-pass)" psql -h 127.0.0.1 -U zabbix -d zabbix -c "\l zabbix"
List of databases
Name | Owner | Encoding | Locale Provider | Collate | Ctype | Access privileges
----------+---------+----------+-----------------+---------+-------+---------------------
zabbix | zabbix | UTF8 | libc | C | C | =Tc/zabbix +
| | | | | | zabbix=CTc/zabbix
05
Añadir el repo oficial de Zabbix e instalar el server + frontend + agent
Meta: paquetes de Zabbix 7.0 instalados desde el repositorio oficial (garantiza minor updates automáticos con apt upgrade).
5.1 Añadir el repositorio 7.0 para Ubuntu 24.04
Ejecutar enhost: vm
cd /tmp
wget https://repo.zabbix.com/zabbix/7.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_latest+ubuntu24.04_all.deb
sudo dpkg -i zabbix-release_latest+ubuntu24.04_all.deb
sudo apt update
💡 Anclar la rama 7.0 explícitamente
El paquete zabbix-release añade el repo apuntado a 7.0. Si en el
futuro sale 8.0 LTS y el paquete se actualiza, un apt upgrade
descuidado podría intentar saltar de rama. Confirma la rama con:
apt-cache policy zabbix-server-pgsql | head — debe decir
Version: 1:7.0.x-*.
5.2 Instalar los cinco paquetes
Instalamos: server (con backend PostgreSQL), frontend (PHP), configs de Nginx,
agent2 (versión nueva del agent, en Go), y los scripts SQL para cargar el schema.
Ejecutar enhost: vm
sudo apt -y install \
zabbix-server-pgsql \
zabbix-frontend-php \
php8.3-pgsql \
zabbix-nginx-conf \
zabbix-sql-scripts \
zabbix-agent2 \
zabbix-agent2-plugin-postgresql \
zabbix-agent2-plugin-mongodb
⚠ Si apt se queja de "unable to locate zabbix-frontend-php"
Estás en el repo equivocado. Verifica con
grep -r zabbix /etc/apt/sources.list* — debe apuntar a
zabbix/7.0/ubuntu. Si dice zabbix/8.0, quita ese repo y
reinstala zabbix-release apuntando a 7.0.
5.3 Cargar el schema SQL en la DB
El schema completo pesa ~40 MB (comprimido). Puede tardar 1–3 minutos en aplicarse.
No canceles.
Ejecutar enhost: vm
ZBX_DB_PASS="$(sudo cat /root/.zabbix-db-pass)"
zcat /usr/share/zabbix-sql-scripts/postgresql/server.sql.gz | \
PGPASSWORD="$ZBX_DB_PASS" psql -h 127.0.0.1 -U zabbix -d zabbix
# Verificar: debe haber ~180 tablas.
PGPASSWORD="$ZBX_DB_PASS" psql -h 127.0.0.1 -U zabbix -d zabbix -c "\dt" | tail -5
echo "Tablas creadas: $(PGPASSWORD=$ZBX_DB_PASS psql -h 127.0.0.1 -U zabbix -d zabbix -tAc "select count(*) from pg_tables where schemaname='public';")"
Tablas creadas: 173
✓ Verificación
dpkg -l | grep zabbix debe mostrar los 5 paquetes con versión
1:7.0.x-*. Si ves alguno en ii ... 1:6.0.x — quedó una
instalación previa, hay que remover y reinstalar.
06
Configurar zabbix-server.conf y arrancar el server
Meta: el proceso zabbix-server conecta a la DB, arranca limpio, y los logs muestran "server #0 started" sin errores.
6.1 Editar la config del server
Todo lo importante vive en /etc/zabbix/zabbix_server.conf. Sólo
cambiamos tres cosas: password de la DB, número de workers, y ubicación del log.
Ejecutar enhost: vm
ZBX_DB_PASS="$(sudo cat /root/.zabbix-db-pass)"
# Sed idempotente — funciona la primera vez y las siguientes.
sudo sed -i -E \
-e "s|^# ?DBPassword=.*|DBPassword=$ZBX_DB_PASS|" \
-e "s|^# ?DBHost=.*|DBHost=127.0.0.1|" \
-e "s|^# ?StartPollers=.*|StartPollers=10|" \
-e "s|^# ?StartPingers=.*|StartPingers=4|" \
-e "s|^# ?CacheSize=.*|CacheSize=64M|" \
-e "s|^# ?HistoryCacheSize=.*|HistoryCacheSize=32M|" \
-e "s|^# ?LogSlowQueries=.*|LogSlowQueries=3000|" \
/etc/zabbix/zabbix_server.conf
# Confirmar que el password quedó (sin imprimirlo — grep muestra la línea entera).
sudo grep -E "^(DBHost|DBPassword|StartPollers|CacheSize)" /etc/zabbix/zabbix_server.conf | \
sed 's/DBPassword=.*/DBPassword=[HIDDEN]/'
DBHost=127.0.0.1
DBPassword=[HIDDEN]
StartPollers=10
CacheSize=64M
6.2 Arrancar el server y verificar el log
Ejecutar enhost: vm
sudo systemctl enable --now zabbix-server
sudo journalctl -u zabbix-server -n 30 --no-pager
sudo tail -20 /var/log/zabbix/zabbix_server.log
12345:20260701:081432.010 Starting Zabbix Server. Zabbix 7.0.27 (revision c4a3b1).
12345:20260701:081432.010 ****** Enabled features ******
12345:20260701:081432.010 SNMP monitoring: YES
12345:20260701:081432.010 IPMI monitoring: YES
12345:20260701:081432.010 Web monitoring: YES
12345:20260701:081432.010 VMware monitoring: YES
12345:20260701:081432.010 SMTP authentication: YES
12345:20260701:081432.010 ODBC: YES
12345:20260701:081432.010 SSH support: YES
12345:20260701:081432.010 TLS support: YES
12345:20260701:081432.010 ******************************
12345:20260701:081432.010 server #0 started [main process]
12345:20260701:081432.020 server #1 started [service manager #1]
...
⚠ Si ves "connection to database 'zabbix' failed"
El server no puede autenticarse contra Postgres. Causas más comunes:
- El password en
zabbix_server.conf tiene caracteres especiales
sin escapar — reemplaza el password por uno solo alfanumérico y prueba.
pg_hba.conf tiene el método peer en local — Zabbix
conecta por TCP a 127.0.0.1, no local. Debe estar en md5 o
scram-sha-256. Verifica con:
sudo grep '^host' /etc/postgresql/16/main/pg_hba.conf
- Postgres no reinició tras cambiar
listen_addresses. Reinicia y
reintenta.
✓ Verificación
El proceso escucha en 10051/tcp (puerto del server hacia los agents).
Ejecutar enhost: vm
ss -ltnp | grep 10051
LISTEN 0 256 0.0.0.0:10051 0.0.0.0:* users:(("zabbix_server",pid=12345,fd=8))
07
Configurar Nginx + PHP-FPM para el frontend web
Meta: http://192.168.0.230/ muestra la pantalla de setup de Zabbix.
7.1 Activar el vhost de Nginx
El paquete zabbix-nginx-conf instala la config en
/etc/zabbix/nginx.conf. Ajustamos server_name + listen y la enlazamos.
Ejecutar enhost: vm
sudo sed -i \
-e 's|^#\s*listen\s\+8080;| listen 80;|' \
-e 's|^#\s*server_name.*| server_name zbx-lab.lab.harper.local 192.168.0.230;|' \
/etc/zabbix/nginx.conf
# Enlazar como sitio activo en Nginx.
sudo ln -sf /etc/zabbix/nginx.conf /etc/nginx/conf.d/zabbix.conf
# Deshabilitar el default para no chocar en :80.
[ -e /etc/nginx/sites-enabled/default ] && sudo rm /etc/nginx/sites-enabled/default || true
sudo nginx -t
sudo systemctl reload nginx
7.2 Ajustar PHP-FPM (timezone + memoria)
Zabbix exige date.timezone declarado y post_max_size +
max_execution_time por encima de los defaults (imágenes, imports).
Ejecutar enhost: vm
sudo sed -i -E \
-e 's|^;?\s*date.timezone\s*=.*|date.timezone = America/Santo_Domingo|' \
-e 's|^;?\s*post_max_size\s*=.*|post_max_size = 16M|' \
-e 's|^;?\s*upload_max_filesize\s*=.*|upload_max_filesize = 2M|' \
-e 's|^;?\s*max_execution_time\s*=.*|max_execution_time = 300|' \
-e 's|^;?\s*max_input_time\s*=.*|max_input_time = 300|' \
-e 's|^;?\s*memory_limit\s*=.*|memory_limit = 256M|' \
/etc/php/8.3/fpm/php.ini
sudo systemctl restart php8.3-fpm
sudo systemctl status php8.3-fpm --no-pager | head -8
7.3 Abrir el puerto 80 en UFW y probar en el navegador
Ejecutar enhost: vm
sudo ufw allow 80/tcp
sudo ufw status
✓ Verificación
Desde tu laptop, abre http://192.168.0.230/ — debe salir el asistente
de bienvenida de Zabbix (idioma → check de requisitos → DB → server → resumen).
⚠ Si sale "502 Bad Gateway"
Nginx no puede hablar con PHP-FPM. Verifica que el socket exista:
ls -la /run/php/php8.3-fpm.sock y que Nginx lo apunte con el path
correcto en /etc/zabbix/nginx.conf (buscar
fastcgi_pass). Un típico bug es tener PHP 8.2 en la config y PHP 8.3
instalado.
08
Completar el asistente web de instalación
Meta: primer login como Admin, cambio inmediato de password default, e idioma en español.
8.1 Recorrer las pantallas del wizard
- Welcome → seleccionar Spanish (es_ES) → Next step.
- Check of pre-requisites → todas las líneas deben decir OK. Si alguna
marca Fail vuelve atrás a la fase 7 y corrige el
php.ini.
- Configure DB connection — llenar así:
- Database type:
PostgreSQL
- Database host:
127.0.0.1
- Database port:
5432
- Database name:
zabbix
- User:
zabbix
- Password: el contenido de
/root/.zabbix-db-pass
- TLS encryption: dejar desmarcado (loopback local, no aporta).
- Settings → Zabbix server name:
Harper-LAB. Timezone:
America/Santo_Domingo. Tema default: Blue.
- Summary → confirmar → Finish. Genera el archivo
/etc/zabbix/web/zabbix.conf.php.
💡 El archivo generado por el wizard
/etc/zabbix/web/zabbix.conf.php contiene el password de la DB en claro.
Confirma que quedó en 640 zabbix:www-data:
ls -la /etc/zabbix/web/zabbix.conf.php.
8.2 Primer login
- Usuario:
Admin (con A mayúscula).
- Password default:
zabbix.
- Cambia el password inmediatamente: menú superior derecho →
User settings → Change password. Usa un password fuerte y guárdalo en
la bóveda del cliente.
✓ Verificación
Ve a Monitoring → Hosts — debe haber un host Zabbix server
con "Availability" en rojo/gris (aún no configuramos el agent). Eso es correcto en
esta fase.
09
Configurar zabbix-agent2 para que el server se monitoree a sí mismo
Meta: el host Zabbix server pasa a Available (Zabbix agent) en verde, y los gráficos empiezan a llenarse.
El agent ya está instalado (fase 5). Solo hay que apuntarlo al server local.
9.1 Config mínima del agent
Ejecutar enhost: vm
sudo sed -i -E \
-e 's|^Server=.*|Server=127.0.0.1|' \
-e 's|^ServerActive=.*|ServerActive=127.0.0.1|' \
-e 's|^Hostname=.*|Hostname=Zabbix server|' \
/etc/zabbix/zabbix_agent2.conf
sudo systemctl enable --now zabbix-agent2
sudo systemctl status zabbix-agent2 --no-pager | head -8
⚠ Hostname del agent = Hostname del host en la GUI
El valor Hostname del zabbix_agent2.conf DEBE coincidir
EXACTAMENTE con el nombre del host en la GUI (incluidas mayúsculas y espacios). El
host default que crea Zabbix se llama Zabbix server (con "Z" mayúscula y
un espacio). Si difiere en una letra, el agent responde pero Zabbix no lo asocia.
✓ Verificación (esperar ~90 segundos)
En la GUI Monitoring → Hosts, la columna Availability del host
Zabbix server debe pasar a verde con "Z". Los
primeros datos (CPU, RAM, disco) aparecen en Monitoring → Latest data al
minuto siguiente.
10
TLS en el frontend (Certbot para clientes con dominio público, cert interno en lab)
Meta: https://zbx.lab.harper.local/ funcionando; http:// redirige a HTTPS.
◆ Certbot o certificado interno
Cliente con dominio público (Zabbix accesible por internet):
usar certbot con HTTP-01 (puerto 80 accesible externamente).
Lab / cliente cerrado (solo LAN): usar cert auto-firmado o cert
emitido por la CA interna. En este tutorial documentamos ambos.
10.1 Ruta A · Certbot (dominio público)
Ejecutar enhost: vm
sudo apt -y install certbot python3-certbot-nginx
sudo certbot --nginx \
-d zbx.cliente-ejemplo.com \
--agree-tos \
--email ramces.batista@har-per.com \
--no-eff-email \
--redirect
# Verificar renovación automática (via systemd timer)
sudo systemctl list-timers | grep certbot
10.2 Ruta B · Cert auto-firmado para el lab
Ejecutar enhost: vm
sudo mkdir -p /etc/nginx/ssl
sudo openssl req -x509 -nodes -days 825 -newkey rsa:2048 \
-keyout /etc/nginx/ssl/zbx-lab.key \
-out /etc/nginx/ssl/zbx-lab.crt \
-subj "/C=DO/ST=SDO/L=SantoDomingo/O=Harper/OU=Infra/CN=zbx-lab.lab.harper.local"
# Editar /etc/zabbix/nginx.conf: añadir bloque HTTPS + redirect.
sudo tee /etc/nginx/conf.d/zabbix-ssl.conf >/dev/null <<'EOF'
server {
listen 80;
server_name zbx-lab.lab.harper.local 192.168.0.230;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name zbx-lab.lab.harper.local 192.168.0.230;
ssl_certificate /etc/nginx/ssl/zbx-lab.crt;
ssl_certificate_key /etc/nginx/ssl/zbx-lab.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
include /etc/zabbix/nginx.conf;
}
EOF
# Quitar el /etc/nginx/conf.d/zabbix.conf duplicado (queda dentro del SSL).
sudo mv /etc/nginx/conf.d/zabbix.conf /etc/nginx/conf.d/zabbix.conf.disabled
sudo nginx -t && sudo systemctl reload nginx
sudo ufw allow 443/tcp
✓ Verificación
curl -kI https://192.168.0.230/ debe devolver 200 OK.
El navegador muestra la advertencia de cert auto-firmado (esperado en lab) y al
aceptar carga el login.
11
Añadir el primer host cliente (Ubuntu/Debian) y aplicar template
Meta: un segundo host Linux aparece en verde y recibe métricas cada 1 min.
11.1 En el host a monitorear: instalar el agent
Repetimos el patrón: repo oficial → agent2 → configurar → arrancar. En cliente
Debian/Ubuntu 24.04 es igual que en la VM del server.
Ejecutar enhost: host-cliente (por ejemplo, otro Ubuntu 24.04)
cd /tmp
wget https://repo.zabbix.com/zabbix/7.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_latest+ubuntu24.04_all.deb
sudo dpkg -i zabbix-release_latest+ubuntu24.04_all.deb
sudo apt update
sudo apt -y install zabbix-agent2
# Apuntar al servidor Zabbix (IP LAN de la VM del server).
sudo sed -i -E \
-e 's|^Server=.*|Server=192.168.0.230|' \
-e 's|^ServerActive=.*|ServerActive=192.168.0.230|' \
-e "s|^Hostname=.*|Hostname=$(hostname -f)|" \
/etc/zabbix/zabbix_agent2.conf
sudo systemctl enable --now zabbix-agent2
# Abrir el puerto 10050 SOLO desde la IP del Zabbix server.
sudo ufw allow from 192.168.0.230 to any port 10050 proto tcp
11.2 En la GUI Zabbix: crear el host
- Data collection → Hosts → Create host.
- Host name: exacto igual al
Hostname del agent
(ej. web01.lab.harper.local).
- Templates: añadir
Linux by Zabbix agent (el activo, no el pasivo si
el firewall del cliente bloquea entrantes).
- Host groups:
Linux servers.
- Interfaces: Agent, IP del host, puerto
10050.
- Save.
💡 Template "by Zabbix agent" vs "by Zabbix agent active"
El template active hace que el agent envíe datos (push, sale por 10051
del server) — mejor si el host cliente está detrás de NAT o firewall que no
permite entrantes. El passive hace que el server pregunte (pull, entra por
10050 al cliente). En Harper por defecto usamos active — es más
amigable con firewalls de cliente.
✓ Verificación
Espera 90 segundos. El host aparece con Availability verde y en
Latest data ves CPU utilization, Memory used,
Uptime, etc.
12
Notificaciones por email al equipo de infraestructura
Meta: cuando un trigger de High/Disaster se dispara, llega email a
infra@har-per.com en < 30 segundos.
Necesitas: cuenta SMTP con app-password (Microsoft 365, Google Workspace, cuenta
dedicada del cliente). Nunca reutilizar credenciales personales — usar cuenta de
servicio.
12.1 Configurar el "Media type" Email
- Alerts → Media types → Email (viene desactivado).
- SMTP server:
smtp.office365.com · Port: 587
- SMTP helo:
zbx-lab.lab.harper.local
- SMTP email:
zabbix-alerts@har-per.com (from address).
- Connection security:
STARTTLS.
- Authentication:
Username and password → usuario + app-password.
- Message format:
HTML.
- Enabled: ✓ · Test → enviar a tu email → confirmar que llega.
12.2 Vincular el email al usuario Admin (y crear un usuario "alerts")
- Users → Users → Admin → Media: añadir Email →
infra@har-per.com → Severity: Warning + High + Disaster.
- Alerts → Actions → Trigger actions: crear una acción "Notify Infra" con
condición Trigger severity ≥ High y operación Send message to user
Admin (Email).
✓ Verificación
Detén temporalmente el agent del host cliente
(sudo systemctl stop zabbix-agent2). Tras ~2 minutos debe
llegar el email [PROBLEM] Host unreachable. Arranca el agent de nuevo y
llega [RESOLVED].
13
Backup nocturno de la DB y de /etc/zabbix/
Meta: cada noche a las 03:00 se genera un dump comprimido de la DB + tar de la config, con retención de 14 días.
13.1 Script de backup
Ejecutar enhost: vm
sudo tee /usr/local/sbin/zbx-backup.sh >/dev/null <<'EOF'
#!/usr/bin/env bash
# Backup nocturno de Zabbix — Harper.
# - Dump comprimido de la DB Postgres (schema + datos).
# - Tar de /etc/zabbix (configs).
# - Retención: 14 archivos más recientes de cada tipo.
set -euo pipefail
BACKUP_DIR=/var/backups/zabbix
STAMP=$(date +%F_%H%M)
mkdir -p "$BACKUP_DIR"
# 1) DB
export PGPASSWORD="$(cat /root/.zabbix-db-pass)"
pg_dump -h 127.0.0.1 -U zabbix -Fc zabbix \
| gzip -9 > "$BACKUP_DIR/zabbix-db-$STAMP.dump.gz"
# 2) Configs
tar -C / -czf "$BACKUP_DIR/zabbix-etc-$STAMP.tar.gz" etc/zabbix etc/nginx/conf.d 2>/dev/null
# 3) Retención: dejar 14 más recientes de cada patrón.
ls -1t "$BACKUP_DIR"/zabbix-db-*.dump.gz | tail -n +15 | xargs -r rm --
ls -1t "$BACKUP_DIR"/zabbix-etc-*.tar.gz | tail -n +15 | xargs -r rm --
logger -t zbx-backup "backup OK · $STAMP · $(du -sh $BACKUP_DIR | cut -f1)"
EOF
sudo chmod 700 /usr/local/sbin/zbx-backup.sh
sudo /usr/local/sbin/zbx-backup.sh # test manual
ls -lh /var/backups/zabbix/
13.2 Timer de systemd (03:00 local)
Ejecutar enhost: vm
sudo tee /etc/systemd/system/zbx-backup.service >/dev/null <<'EOF'
[Unit]
Description=Zabbix nightly backup (DB + configs)
After=postgresql.service
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/zbx-backup.sh
EOF
sudo tee /etc/systemd/system/zbx-backup.timer >/dev/null <<'EOF'
[Unit]
Description=Trigger zbx-backup.service cada noche a las 03:00
[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
RandomizedDelaySec=5m
[Install]
WantedBy=timers.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now zbx-backup.timer
sudo systemctl list-timers zbx-backup.timer
💡 Off-site del backup
Los backups locales protegen contra corrupción de DB, no contra pérdida de la VM.
Añade un rclone sync o rsync hacia el servidor de backup
del cliente / OBS de Huawei Cloud. Documentar la política de retención remota en el
ticket de handoff.
14
Documentación de handoff al cliente
Meta: dejar al cliente la información mínima para operar, actualizar y recuperar.
14.1 Ficha de servicio (rellenar y entregar)
| Campo | Valor |
| Cliente | |
| Fecha de entrega | |
| FQDN del server | |
| IP LAN | |
| Versión Zabbix | 7.0.27 LTS |
| URL frontend | |
| User admin creado | |
| Media type email configurado (sí/no) | |
| Cuenta SMTP usada | |
| Ruta de backups (/var/backups/zabbix) | |
| Off-site backup destino | |
| Snapshots Proxmox activados (sí/no) | |
| Firewall abierto (puertos) | |
| Hosts monitoreados al momento de entrega | |
| Contacto técnico Harper | |
| Notas / Excepciones | |
14.2 Checklist de entrega (evaluación final)
- La VM boots limpia, Ubuntu 24.04 actualizado, SSH sin password, UFW activo.
- PostgreSQL 16 escucha solo en
127.0.0.1:5432, timezone UTC.
- La DB
zabbix tiene ≥ 173 tablas cargadas.
zabbix-server arranca sin errores en el log.
- El frontend responde en
https://…/ con cert válido (o auto-firmado documentado en lab).
- Login
Admin con password nuevo (no zabbix).
- El host Zabbix server aparece en verde (agent local funciona).
- Al menos un host cliente monitoreado con template Linux.
- Email de prueba llega desde Zabbix a la lista de alertas.
- Timer de backup
zbx-backup.timer activo y ejecutado al menos una vez.
- Ficha 14.1 rellena y compartida con el cliente.
- Snapshot Proxmox tomado post-entrega ("post-handoff") para rollback rápido.
14.3 Comandos de referencia rápida (cheatsheet)
Diagnóstico y operación diaria
| Qué | Comando |
| Ver estado del server | systemctl status zabbix-server |
| Log del server en vivo | sudo tail -f /var/log/zabbix/zabbix_server.log |
| Reiniciar solo el server | sudo systemctl restart zabbix-server |
| Reiniciar todo el stack web | sudo systemctl restart php8.3-fpm nginx |
| Contar hosts activos | PGPASSWORD=… psql -h 127.0.0.1 -U zabbix -d zabbix -c "select count(*) from hosts where status=0;" |
| Backup manual on-demand | sudo /usr/local/sbin/zbx-backup.sh |
| Ver últimos triggers activos | Monitoring → Problems en la GUI |
| Detectar cola atascada | Reports → Queue |
| Testear agent desde el server | zabbix_get -s IP_HOST -k system.uptime |
💡 Path de upgrade a Zabbix 8.0
Cuando 8.0 LTS lleve ~6 meses en GA: (1) snapshot Proxmox pre-upgrade, (2)
apt install zabbix-release_latest+ubuntu24.04_all.deb apuntado a 8.0,
(3) apt update && apt install --only-upgrade zabbix-server-pgsql zabbix-frontend-php,
(4) el server aplica migrations al arrancar (revisar log), (5) verificar frontend.
Documentaremos el playbook oficial cuando 8.0 esté estable.
✓ Fin del tutorial
Si todos los ítems del checklist 14.2 están marcados, el servidor Zabbix está listo
para producción y este es tu procedimiento canónico para clientes
a partir de hoy. Copia esta página como base de la documentación interna del
cliente.