first commit

This commit is contained in:
Xavier Rodriguez
2025-12-09 12:45:15 +01:00
commit 7fc616b5c3
44 changed files with 6981 additions and 0 deletions
+163
View File
@@ -0,0 +1,163 @@
# Configuración para Zabbix - Cisco MAC Monitor LLD
# ================================================
## CONFIGURACIÓN DEL JAVASCRIPT EN ZABBIX
### 1. Crear el Script JavaScript en Zabbix
**Administración > Scripts > Crear Script**
- Nombre: `Cisco MAC LLD`
- Tipo: `Script`
- Ejecutar en: `Zabbix server`
- Comandos: [Copiar contenido de zabbix_lld_script.js]
### 2. Configurar Discovery Rule
**Configuración > Hosts > [Tu Host Cisco] > Discovery > Crear regla de descubrimiento**
- Nombre: `Cisco MAC Address Discovery`
- Tipo: `Script`
- Clave: `cisco.mac.discovery`
- Script: `Cisco MAC LLD`
- Intervalo: `1h` (o según necesites)
- Periodo de conservación de elementos perdidos: `7d`
### 3. Configurar Macros del Host
**Configuración > Hosts > [Tu Host Cisco] > Macros**
Crear las siguientes macros:
```
{$CISCO_SERVICE_URL} = https://tu-servidor:8443
{$CISCO_HOST} = {HOST.CONN} # O la IP específica
{$CISCO_USERNAME} = tu_usuario_ssh
{$CISCO_PASSWORD} = tu_contraseña_ssh
{$CISCO_TIMEOUT} = 60
```
### 4. Configurar Item Prototypes
Una vez creada la Discovery Rule, crear los siguientes Item Prototypes:
#### Item 1: Contador de MACs por Puerto
- Nombre: `Port {#PORT_NAME} - MAC Count`
- Tipo: `Dependent item`
- Clave: `cisco.port.mac.count[{#PORT_NAME}]`
- Master item: `cisco.mac.discovery`
- Preprocessing:
- JSONPath: `$.data[?(@['{#PORT_NAME}'] == '{#PORT_NAME}')]['{#MAC_COUNT}'].first()`
#### Item 2: Lista de MACs por Puerto
- Nombre: `Port {#PORT_NAME} - MAC Addresses`
- Tipo: `Dependent item`
- Clave: `cisco.port.mac.addresses[{#PORT_NAME}]`
- Tipo de información: `Text`
- Master item: `cisco.mac.discovery`
- Preprocessing:
- JSONPath: `$.data[?(@['{#PORT_NAME}'] == '{#PORT_NAME}')]['{#MAC_ADDRESSES}'].first()`
#### Item 3: VLANs por Puerto
- Nombre: `Port {#PORT_NAME} - VLANs`
- Tipo: `Dependent item`
- Clave: `cisco.port.vlans[{#PORT_NAME}]`
- Tipo de información: `Text`
- Master item: `cisco.mac.discovery`
- Preprocessing:
- JSONPath: `$.data[?(@['{#PORT_NAME}'] == '{#PORT_NAME}')]['{#VLANS}'].first()`
### 5. Configurar Triggers (Opcional)
#### Trigger 1: Puerto con muchas MACs
- Nombre: `Port {#PORT_NAME} has too many MAC addresses`
- Expresión: `last(/Template/cisco.port.mac.count[{#PORT_NAME}])>50`
- Severidad: `Warning`
#### Trigger 2: Cambio en número de MACs
- Nombre: `MAC count changed on port {#PORT_NAME}`
- Expresión: `change(/Template/cisco.port.mac.count[{#PORT_NAME}])<>0`
- Severidad: `Information`
## CONFIGURACIÓN DEL SERVICIO HTTPS
### Variables de entorno necesarias:
```bash
CISCO_SERVICE_PORT=8443
SSL_CERT_PATH=/path/to/certificate.pem
SSL_KEY_PATH=/path/to/private.key
```
### Comando para generar certificado autofirmado:
```bash
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes \
-subj "/C=ES/ST=Madrid/L=Madrid/O=Organization/CN=cisco-monitor"
```
## ESTRUCTURA ESPERADA DE RESPUESTA JSON
```json
{
"data": [
{
"port": "Gi1/0/1",
"data": {
"count": 2,
"vlans": "600,601",
"addresses": "F0:8E:DB:2E:4D:86 600\nF0:8E:DB:2E:4D:86 601",
"timestamp": 1763048672
}
},
{
"port": "Gi1/0/10",
"data": {
"count": 1,
"vlans": "151",
"addresses": "00:50:56:A6:91:69 151",
"timestamp": 1763048672
}
},
{
"port": "Gi1/0/11",
"data": {
"count": 0,
"vlans": "",
"addresses": "",
"timestamp": 1763048672
}
}
],
"timestamp": "2024-11-13T10:30:00",
"unix_timestamp": 1700000000,
"device_hostname": "cisco-switch",
"total_ports": 24,
"total_macs": 45,
"ports_with_macs": 12,
"ports_without_macs": 12
}
```
## TROUBLESHOOTING
### 1. Verificar logs de Zabbix
```bash
tail -f /var/log/zabbix/zabbix_server.log | grep "Cisco"
```
### 2. Probar el servicio manualmente
```bash
curl -k -X POST https://tu-servidor:8443/mac-monitor \
-H "Content-Type: application/json" \
-d '{
"host": "192.168.1.10",
"username": "admin",
"password": "password"
}'
```
### 3. Verificar conectividad HTTPS desde Zabbix
Usar "Administration > Scripts > Test" en Zabbix con un script simple:
```javascript
var req = new HttpRequest();
var response = req.get("https://tu-servidor:8443/health");
return response;
```
@@ -0,0 +1,60 @@
/**
* Zabbix JavaScript para consulta de datos MAC por puerto
* Compatible con versiones antiguas - Funciona con Zabbix 4.x, 5.x y 6.x
* Formato de respuesta estructurado por puertos
*/
// Configuración mediante macros
var serviceUrl = "{$CISCO_SERVICE_URL}";
var ciscoHost = "{$CISCO_HOST}";
var ciscoUsername = "{$CISCO_USERNAME}";
var ciscoPassword = "{$CISCO_PASSWORD}";
// Validar parámetros requeridos
if (!serviceUrl || !ciscoHost || !ciscoUsername || !ciscoPassword) {
throw "Faltan parámetros: CISCO_SERVICE_URL, CISCO_HOST, CISCO_USERNAME, CISCO_PASSWORD";
}
// Log de inicio
Zabbix.Log(4, "[Cisco MAC] Host: " + ciscoHost);
// Preparar datos para POST
var postData = JSON.stringify({
"host": ciscoHost,
"username": ciscoUsername,
"password": ciscoPassword,
"port": 22,
"timeout": 30
});
// Crear request HTTP (método básico compatible)
var req = new HttpRequest();
req.addHeader('Content-Type: application/json');
try {
// Hacer consulta POST
var response = req.post(serviceUrl , postData);
// Verificar status
if (req.getStatus() !== 200) {
throw "HTTP Error " + req.getStatus();
}
// Parsear respuesta
var jsonData = JSON.parse(response);
// Validar estructura
if (!jsonData.data) {
throw "Invalid response structure";
}
// Log de éxito
Zabbix.Log(4, "[Cisco MAC] Success: " + jsonData.data.length + " ports");
// Retornar datos estructurados por puertos
return JSON.stringify(jsonData);
} catch (error) {
Zabbix.Log(2, "[Cisco MAC] ERROR: " + error);
throw "Cisco MAC query failed: " + error;
}
+140
View File
@@ -0,0 +1,140 @@
/**
* Zabbix JavaScript para Low Level Discovery (LLD)
* Consulta HTTPS al servicio de monitorización de MACs Cisco
*
* Parámetros esperados:
* - {$CISCO_SERVICE_URL}: URL del servicio HTTPS (ej: https://cisco-monitor:8443)
* - {$CISCO_HOST}: IP o hostname del dispositivo Cisco
* - {$CISCO_USERNAME}: Usuario SSH
* - {$CISCO_PASSWORD}: Contraseña SSH
* - {$CISCO_TIMEOUT}: Timeout en segundos (opcional, default: 60)
*
* Uso en Zabbix:
* - Crear un item tipo "Script"
* - Configurar parámetros como macros del host
* - Usar este script en el discovery rule
*/
// Configuración
var serviceUrl = "{$CISCO_SERVICE_URL}";
var ciscoHost = "{$CISCO_HOST}";
var ciscoUsername = "{$CISCO_USERNAME}";
var ciscoPassword = "{$CISCO_PASSWORD}";
var timeout = parseInt("{$CISCO_TIMEOUT}") || 60;
// Validar parámetros requeridos
if (!serviceUrl || !ciscoHost || !ciscoUsername || !ciscoPassword) {
throw new Error("Faltan parámetros requeridos: CISCO_SERVICE_URL, CISCO_HOST, CISCO_USERNAME, CISCO_PASSWORD");
}
// Log de inicio
Zabbix.Log(4, "[Cisco MAC LLD] Iniciando consulta para host: " + ciscoHost);
Zabbix.Log(4, "[Cisco MAC LLD] Service URL: " + serviceUrl);
try {
// Preparar datos para POST
var postData = JSON.stringify({
"host": ciscoHost,
"username": ciscoUsername,
"password": ciscoPassword,
"port": 22,
"timeout": timeout
});
// Configurar request HTTP
var req = new HttpRequest();
// Configurar headers
req.addHeader('Content-Type: application/json');
req.addHeader('Accept: application/json');
req.addHeader('User-Agent: Zabbix-LLD-Script/1.0');
// Configurar timeout (método compatible con versiones anteriores de Zabbix)
if (typeof req.setTimeout === 'function') {
req.setTimeout(timeout * 1000);
} else if (typeof req.setConnectTimeout === 'function') {
req.setConnectTimeout(timeout);
req.setTimeout(timeout);
}
// Log de request
Zabbix.Log(4, "[Cisco MAC LLD] Enviando POST a: " + serviceUrl + "/cisco-mac-monitor");
Zabbix.Log(4, "[Cisco MAC LLD] POST data: " + postData);
// Hacer la consulta HTTPS POST
var response = req.post(serviceUrl + "/cisco-mac-monitor", postData);
// Log de response
Zabbix.Log(4, "[Cisco MAC LLD] Response status: " + req.getStatus());
Zabbix.Log(4, "[Cisco MAC LLD] Response length: " + response.length);
// Verificar código de estado HTTP
if (req.getStatus() !== 200) {
throw new Error("HTTP Error " + req.getStatus() + ": " + response);
}
// Validar que la respuesta no esté vacía
if (!response || response.trim().length === 0) {
throw new Error("Respuesta vacía del servicio");
}
// Intentar parsear JSON
var jsonResponse;
try {
jsonResponse = JSON.parse(response);
} catch (parseError) {
Zabbix.Log(3, "[Cisco MAC LLD] Error parsing JSON: " + parseError.message);
Zabbix.Log(3, "[Cisco MAC LLD] Raw response: " + response.substring(0, 500) + "...");
throw new Error("Error parsing JSON response: " + parseError.message);
}
// Validar estructura de respuesta
if (!jsonResponse.data || !Array.isArray(jsonResponse.data)) {
throw new Error("Respuesta JSON inválida: falta campo 'data' o no es array");
}
// Log de éxito
Zabbix.Log(4, "[Cisco MAC LLD] Éxito: " + jsonResponse.data.length + " elementos descubiertos");
Zabbix.Log(4, "[Cisco MAC LLD] Device: " + (jsonResponse.device_hostname || "unknown"));
Zabbix.Log(4, "[Cisco MAC LLD] Total ports: " + (jsonResponse.total_ports || 0));
Zabbix.Log(4, "[Cisco MAC LLD] Total MACs: " + (jsonResponse.total_macs || 0));
// Preparar respuesta para LLD
var lldResponse = {
"data": jsonResponse.data
};
// Log de algunos elementos de ejemplo para debug
if (jsonResponse.data.length > 0) {
Zabbix.Log(4, "[Cisco MAC LLD] Primer elemento: " + JSON.stringify(jsonResponse.data[0]));
if (jsonResponse.data.length > 1) {
Zabbix.Log(4, "[Cisco MAC LLD] Segundo elemento: " + JSON.stringify(jsonResponse.data[1]));
}
}
// Retornar JSON para LLD
return JSON.stringify(lldResponse);
} catch (error) {
// Log de error detallado
Zabbix.Log(2, "[Cisco MAC LLD] ERROR: " + error.message);
Zabbix.Log(2, "[Cisco MAC LLD] Host: " + ciscoHost);
Zabbix.Log(2, "[Cisco MAC LLD] Service URL: " + serviceUrl);
// En caso de error, retornar estructura vacía para evitar fallos en LLD
// Esto permite que Zabbix no falle completamente si hay problemas temporales
var errorResponse = {
"data": [],
"error": error.message,
"timestamp": new Date().toISOString(),
"host": ciscoHost
};
// Opcionalmente, lanzar error para que Zabbix lo registre
// Comentar la siguiente línea si prefieres que LLD retorne estructura vacía en caso de error
throw new Error("Cisco MAC LLD failed for " + ciscoHost + ": " + error.message);
// Retornar respuesta de error (solo se ejecuta si se comenta el throw anterior)
// return JSON.stringify(errorResponse);
}
+38
View File
@@ -0,0 +1,38 @@
/**
* Zabbix JavaScript Simplificado para Cisco MAC LLD
* Versión minimalista para pruebas rápidas
*/
// Parámetros (configurar según tu entorno)
var serviceUrl = value; // Pasado como parámetro en Zabbix
var ciscoHost = "{HOST.CONN}"; // IP del host de Zabbix
var username = "{$CISCO_USER}";
var password = "{$CISCO_PASS}";
Zabbix.Log(4, "Cisco LLD: Consultando " + ciscoHost);
var req = new HttpRequest();
req.addHeader('Content-Type: application/json');
var postData = JSON.stringify({
"host": ciscoHost,
"username": username,
"password": password,
"timeout": 30
});
try {
var response = req.post(serviceUrl + "/mac-monitor", postData);
if (req.getStatus() !== 200) {
throw "HTTP " + req.getStatus() + ": " + response;
}
var data = JSON.parse(response);
return JSON.stringify({"data": data.data});
} catch (error) {
Zabbix.Log(2, "Cisco LLD Error: " + error);
throw error;
}
+168
View File
@@ -0,0 +1,168 @@
zabbix_export:
version: '7.0'
template_groups:
- uuid: 36bff6c29af64692839d077febfc7079
name: 'Templates/Network devices'
templates:
- uuid: 7dc3e191c7804221b777b7c79944f283
template: 'Template Cisco MAC monitor'
name: 'Template Cisco MAC monitor'
groups:
- name: 'Templates/Network devices'
items:
- uuid: a2d9df39e93d468891e68ba8d16c490b
name: 'Get data'
type: SCRIPT
key: cisco-mac-monitor.get-data
history: 1d
value_type: TEXT
trends: '0'
params: |
/**
* Zabbix JavaScript para LLD - Compatible con versiones antiguas
* Funciona con Zabbix 4.x, 5.x y 6.x
*/
// Configuración mediante macros
var serviceUrl = "{$CISCO_SERVICE_URL}";
var ciscoHost = "{$CISCO_HOST}";
var ciscoUsername = "{$CISCO_USERNAME}";
var ciscoPassword = "{$CISCO_PASSWORD}";
// Validar parámetros requeridos
if (!serviceUrl || !ciscoHost || !ciscoUsername || !ciscoPassword) {
throw "Faltan parámetros: CISCO_SERVICE_URL, CISCO_HOST, CISCO_USERNAME, CISCO_PASSWORD";
}
// Log de inicio
Zabbix.Log(4, "[Cisco LLD] Host: " + ciscoHost);
// Preparar datos para POST
var postData = JSON.stringify({
"host": ciscoHost,
"username": ciscoUsername,
"password": ciscoPassword,
"port": 22,
"timeout": 30
});
// Crear request HTTP (método básico compatible)
var req = new HttpRequest();
req.addHeader('Content-Type: application/json');
try {
// Hacer consulta POST
var response = req.post(serviceUrl , postData);
// Verificar status
if (req.getStatus() !== 200) {
throw "HTTP Error " + req.getStatus();
}
// Parsear respuesta
var jsonData = JSON.parse(response);
// Validar estructura
if (!jsonData.data) {
throw "Invalid response structure";
}
// Log de éxito
Zabbix.Log(4, "[Cisco LLD] Success: " + jsonData.data.length + " items");
// Retornar para LLD
return JSON.stringify({"data": jsonData.data});
} catch (error) {
Zabbix.Log(2, "[Cisco LLD] ERROR: " + error);
throw "Cisco LLD failed: " + error;
}
discovery_rules:
- uuid: 39c0b9d76a1a4118820b13906e1b00ca
name: 'Port discovery'
type: DEPENDENT
key: port.discovery
delay: '0'
item_prototypes:
- uuid: 983b103f825d451db67b4dd938f569fd
name: '{#PORT}: MAC address list'
type: DEPENDENT
key: 'mac.addresses[{#PORT}]'
delay: '0'
value_type: TEXT
trends: '0'
preprocessing:
- type: JSONPATH
parameters:
- '$.data[?(@.port=="{#PORT}")].data.addresses'
- type: TRIM
parameters:
- '[]"'
- type: JAVASCRIPT
parameters:
- 'return value.replace(/\\n/g, String.fromCharCode(10));'
master_item:
key: cisco-mac-monitor.get-data
- uuid: 898b84bc5bb54ed1b261af3ebf54caf0
name: '{#PORT}: MAC address count'
type: DEPENDENT
key: 'mac.count[{#PORT}]'
delay: '0'
trends: '0'
preprocessing:
- type: JSONPATH
parameters:
- '$.data[?(@.port=="{#PORT}")].data.count'
- type: TRIM
parameters:
- '[]'
master_item:
key: cisco-mac-monitor.get-data
- uuid: d2691b9290a84befa03c931c934c5fe1
name: '{#PORT}: VLANs'
type: DEPENDENT
key: 'mac.vlans[{#PORT}]'
delay: '0'
value_type: TEXT
trends: '0'
preprocessing:
- type: JSONPATH
parameters:
- '$.data[?(@.port=="{#PORT}")].data.vlans'
- type: TRIM
parameters:
- '[]"'
- type: STR_REPLACE
parameters:
- ','
- ', '
master_item:
key: cisco-mac-monitor.get-data
master_item:
key: cisco-mac-monitor.get-data
lld_macro_paths:
- lld_macro: '{#ADDRESSES}'
path: $.data.addresses
- lld_macro: '{#COUNT}'
path: $.data.count
- lld_macro: '{#PORT}'
path: $.port
- lld_macro: '{#TIMESTAMP}'
path: $.data.timestamp
- lld_macro: '{#VLANS}'
path: $.data.vlans
preprocessing:
- type: JSONPATH
parameters:
- '$.data[*]'
macros:
- macro: '{$CISCO_HOST}'
value: 10.150.250.2
- macro: '{$CISCO_PASSWORD}'
type: SECRET_TEXT
- macro: '{$CISCO_SERVICE_URL}'
value: 'https://ufrparesb015.nead.danet/mac-monitor'
- macro: '{$CISCO_TIMEOUT}'
value: '20'
- macro: '{$CISCO_USERNAME}'
value: itops