commit 8c12d1ddeed18434f0dd230e48dd8a47fc6bb82d Author: Asis Ferrer Date: Mon Jun 8 17:04:56 2026 +0200 Initial Zabbix port monitoring template diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..14fac91 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..e2cc0d4 --- /dev/null +++ b/README.md @@ -0,0 +1,111 @@ +# 📦 Zabbix Template: Port Monitoring LLD + +Template para monitorizar de forma dinámica una lista de puertos TCP definida por macro de host. Usa Low Level Discovery (LLD) para crear automáticamente ítems y triggers por cada puerto configurado. + +## 🚀 Características + +- **Dinámico**: agrega o elimina puertos editando la macro `{$PORTS}` del host. +- **Multiplataforma**: incluye UserParameters para Linux y Windows. +- **Eficiente**: el discovery corre cada 1 hora por defecto; los ítems de escucha se consultan cada 30 segundos. +- **Seguro ante entradas inválidas**: los UserParameters solo descubren puertos numéricos entre `1` y `65535`. +- **Alertas**: dispara una alerta de severidad alta si un puerto deja de escuchar durante más de 2 minutos. + +## ✅ Requisitos + +| Sistema | Requisito | +| ------- | ----------------------------------------------------------------------- | +| Zabbix | Zabbix 7.0 o superior | +| Linux | Zabbix Agent y `python3` | +| Windows | Zabbix Agent 2 y PowerShell | +| Red | El servidor/proxy Zabbix debe poder consultar checks pasivos del agente | + +## ✅ Compatibilidad probada + +Probado en entorno controlado con **Zabbix 7.0.26** en hosts **Windows** y **Linux**. + +## 🛠️ 1. Configuración en los hosts + +Para que el discovery funcione, cada agente necesita el UserParameter `port.discovery[*]`. + +### Windows — Zabbix Agent 2 + +1. Crea o edita este archivo: + + ```text + C:\Program Files\Zabbix Agent 2\zabbix_agent2.d\plugins.d\ports.conf + ``` + +2. Copiá el contenido de [`ports_win.conf`](ports_win.conf) en ese archivo. + +3. Reiniciá el servicio **Zabbix Agent 2**. + +### Linux — Zabbix Agent + +1. Crea o edita este archivo: + + ```text + /etc/zabbix/zabbix_agentd.d/ports.conf + ``` + +2. Copia el contenido de [`ports_linux.conf`](ports_linux.conf) en ese archivo. + +3. Reiniciá el servicio: + + ```bash + sudo systemctl restart zabbix-agent + ``` + +## 📥 2. Importación del template + +1. Descarga o clona este repositorio. +2. En Zabbix, entra en **Data collection > Templates**. +3. Haz clic en **Import**. +4. Selecciona [`port_monitoring_template.yaml`](port_monitoring_template.yaml). +5. Vincula el template **Port Monitoring LLD** a tus hosts. + +## ⚙️ 3. Configuración de macros + +Una vez vinculado el template al host, definí o heredá esta macro: + +| Macro | Valor de ejemplo | Descripción | +| ---------- | ------------------- | --------------------------------------------------------------------------------------------- | +| `{$PORTS}` | `21,22,80,443,3389` | Lista de puertos separados por coma. Solo se descubren valores numéricos entre `1` y `65535`. | + +> Los valores inválidos, vacíos o fuera de rango se ignoran durante el discovery. + +## 🔍 4. Verificación + +Prueba que el agente responda con el JSON LLD esperado. + +### Windows PowerShell + +Desde el directorio donde está `zabbix_agent2.exe`: + +```powershell +.\zabbix_agent2.exe -t 'port.discovery["21,22,80,443,3389"]' +``` + +### Linux + +```bash +zabbix_get -s 127.0.0.1 -k 'port.discovery["21,22,80,443,3389"]' +``` + +Resultado esperado: + +```json +{"data":[{"{#PORT}":"21"},{"{#PORT}":"22"},{"{#PORT}":"80"},{"{#PORT}":"443"},{"{#PORT}":"3389"}]} +``` + +## 📊 Estructura del template + +| Componente | Valor | +| ----------------- | ------------------------------------- | +| Discovery rule | `Port discovery` | +| Discovery key | `port.discovery["{$PORTS}"]` | +| Item prototype | `Port {#PORT} listening` | +| Item key | `net.tcp.listen[{#PORT}]` | +| Trigger prototype | `Puerto {#PORT} caído en {HOST.NAME}` | +| Severidad | High | + +> Si agregás un puerto nuevo a la macro, Zabbix lo detectará en el siguiente ciclo de discovery, por defecto cada 1 hora. También puedes forzarlo desde la interfaz con **Execute now** en la regla de discovery del host. diff --git a/port_monitoring_template.yaml b/port_monitoring_template.yaml new file mode 100644 index 0000000..035da94 --- /dev/null +++ b/port_monitoring_template.yaml @@ -0,0 +1,34 @@ +zabbix_export: + version: '7.0' + template_groups: + - uuid: 7df96b18c230490a9a0a9e2307226338 + name: Templates + templates: + - uuid: 8be56e3efd1743afaafe548da825f692 + template: 'Port Monitoring LLD' + name: 'Port Monitoring LLD' + groups: + - name: Templates + macros: + - macro: '{$PORTS}' + value: '21,22,80,443,3389' + discovery_rules: + - uuid: 530db6c3a273484994bd45362fb69d4d + name: 'Port discovery' + type: ZABBIX_PASSIVE + key: 'port.discovery["{$PORTS}"]' + delay: 3600s + item_prototypes: + - uuid: 9a60f075b88942c0b7ea4b9eda36e500 + name: 'Port {#PORT} listening' + type: ZABBIX_PASSIVE + key: 'net.tcp.listen[{#PORT}]' + delay: 30s + history: 7d + trends: 30d + value_type: UNSIGNED + trigger_prototypes: + - uuid: 1b51da0f009e40f39f4819dad39474ee + expression: 'min(/Port Monitoring LLD/net.tcp.listen[{#PORT}],2m)=0' + name: 'Puerto {#PORT} caído en {HOST.NAME}' + priority: HIGH diff --git a/ports_linux.conf b/ports_linux.conf new file mode 100644 index 0000000..80cc919 --- /dev/null +++ b/ports_linux.conf @@ -0,0 +1 @@ +UserParameter=port.discovery[*],printf '%s\n' "$1" | python3 -c "import sys,json; data=[]; [data.append({'{#PORT}': p}) for p in (x.strip() for x in sys.stdin.read().split(',')) if p.isdigit() and 1 <= int(p) <= 65535]; print(json.dumps({'data': data}, separators=(',', ':')))" diff --git a/ports_win.conf b/ports_win.conf new file mode 100644 index 0000000..bbc2e63 --- /dev/null +++ b/ports_win.conf @@ -0,0 +1 @@ +UserParameter=port.discovery[*],powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "$raw = '$1'; $list = foreach($entry in ($raw -split ',')){ $port = $entry.Trim(); $n = 0; if([int]::TryParse($port, [ref]$n) -and $n -ge 1 -and $n -le 65535){ @{ '{#PORT}' = $port } } }; @{ data = @($list) } | ConvertTo-Json -Compress"