Módulo SNMP
El módulo snmp proporciona una interfaz completa para el monitoreo y la gestión de dispositivos de red a través del protocolo SNMP (Simple Network Management Protocol). Este módulo es útil para la recopilación de métricas de routers, switches, servidores, impresoras y cualquier dispositivo que soporte SNMP.
-
Soporte para SNMP v1, v2c y v3
-
Operaciones GET, GET BULK y WALK
-
Autenticación y cifrado SNMP v3
-
Configuración flexible de timeout y reintentos
-
Retorno seguro con manejo de errores
Protocolos soportados:
-
SNMP v1: Protocolo básico con comunidad pública/privada
-
SNMP v2c: Mejoras de rendimiento con operaciones BULK
-
SNMP v3: Seguridad avanzada con autenticación y cifrado
Configuración SNMP
Sección titulada «Configuración SNMP»Todas las funciones SNMP requieren un objeto de configuración que define los parámetros de conexión. La configuración es una tabla Lua con los siguientes campos:
Campos de Configuración Básicos:
Sección titulada «Campos de Configuración Básicos:»| Campo | Tipo | Padrão | Descripción |
|---|---|---|---|
address | string | obrigatório | Endereço IP ou hostname do dispositivo |
snmpVersion | número | 1 | Versão SNMP (1=v1, 2=v2c, 3=v3) |
snmpPort | número | 161 | Porta SNMP |
snmpCommunity | string | nil | Comunidade SNMP (v1/v2c) |
snmpTimeout | número | 5 | Timeout em segundos |
snmpRetryCount | número | 3 | Número de retentativas |
snmpMaxBulkItems | número | nil | Máximo de itens por operação BULK |
snmpExponentialBackoff | booleano | false | Habilitar backoff exponencial |
Campos para SNMP v3:
Sección titulada «Campos para SNMP v3:»| Campo | Tipo | Descripción |
|---|---|---|
snmpSecurityLevel | string | Nível de segurança: “NoAuthNoPriv”, “AuthNoPriv”, “AuthPriv” |
snmpAuthProtocol | string | Protocolo de autenticação: “MD5”, “SHA1” |
snmpAuthUser | string | Usuário de autenticação |
snmpAuthPassword | string | Senha de autenticação |
snmpPrivProtocol | string | Protocolo de criptografia: “DES”, “AES” |
snmpPrivPassword | string | Senha de criptografia |
Configuração via Tabela params:
Sección titulada «Configuração via Tabela params:»O ambiente Lua inclui uma tabela predefinida chamada params que contém os detalhes do dispositivo atual. Esta tabela puede ser usada directamente como configuración SNMP, ya que ya posee los campos necesarios en el formato esperado.
Exemplo de uso direto:
-- Usar la tabla device directamente como configuraciónlocal sys_descr = snmp.getex(device, "1.3.6.1.2.1.1.1.0")print("Descrição do dispositivo:", sys_descr)
-- Versión que no lanza errorlocal valor, erro = snmp.get_safe(device, "1.3.6.1.2.1.1.3.0")if not erro then print("Uptime do dispositivo:", valor)endCombinando com configurações adicionais:
-- Crear configuración basada en device con ajusteslocal config = { address = device.address, snmpVersion = device.snmpVersion, snmpCommunity = device.snmpCommunity, snmpTimeout = device.snmpTimeout or 5, -- Usar el valor predeterminado si no está definido snmpRetryCount = 2, -- Sobrescribir valor predeterminado snmpMaxBulkItems = 50 -- Agregar configuración adicional}
-- Usar para operación BULKlocal oids = {"1.3.6.1.2.1.1.1.0", "1.3.6.1.2.1.1.3.0"}local resultados = snmp.get_bulk(config, oids)Ejemplos de Configuración:
Sección titulada «Ejemplos de Configuración:»-- Configuração básica SNMP v2clocal config_v2c = { address = "192.168.1.1", snmpVersion = 2, snmpCommunity = "public", snmpTimeout = 3, snmpRetryCount = 2}
-- Configuração SNMP v3 com autenticação e criptografialocal config_v3 = { address = "10.0.0.254", snmpVersion = 3, snmpSecurityLevel = "AuthPriv", snmpAuthProtocol = "SHA1", snmpAuthUser = "monitor", snmpAuthPassword = "senha123", snmpPrivProtocol = "AES", snmpPrivPassword = "chave456", snmpTimeout = 5}
-- Configuração para dispositivo com porta não padrãolocal config_custom_port = { address = "switch.piso1.local", snmpVersion = 2, snmpCommunity = "internal", snmpPort = 8161, -- Puerto personalizado snmpTimeout = 10 -- Timeout mayor para red lenta}Funções Disponíveis
Sección titulada «Funções Disponíveis»1. snmp.getex(config, oid)
Sección titulada «1. snmp.getex(config, oid)»Realiza una consulta SNMP GET para un OID específico.
Parâmetros:
Sección titulada «Parâmetros:»-
config (tabela): Configuração SNMP (ver seção acima)
-
oid (string): OID a ser consultado (formato numérico ou nomeado)
Retorno:
Sección titulada «Retorno:»- valor: Valor retornado pelo dispositivo SNMP (número, string, etc.)
- Lança erro se o OID não existir ou houver falha na comunicação
Exemplo de Uso:
Sección titulada «Exemplo de Uso:»-- Consultar sysDescr (descripción del sistema)local config = { address = "192.168.1.1", snmpVersion = 2, snmpCommunity = "public"}
local sys_descr = snmp.getex(config, "1.3.6.1.2.1.1.1.0")-- o usando OID nombradolocal sys_descr = snmp.getex(config, ".1.3.6.1.2.1.1.1.0")
print("Descrição do sistema:", sys_descr)-- Ejemplo de salida: "Cisco IOS Software, C3750 Software (C3750-IPSERVICESK9-M), Version 12.2(55)SE10, RELEASE SOFTWARE (fc2)"
-- Consultar uptime del sistemalocal sys_uptime = snmp.getex(config, "1.3.6.1.2.1.1.3.0")print("Uptime:", sys_uptime, "centésimos de segundo")
-- Consultar nombre del hostlocal sys_name = snmp.getex(config, "1.3.6.1.2.1.1.5.0")print("Nome do host:", sys_name)
-- Consultar ubicaciónlocal sys_location = snmp.getex(config, "1.3.6.1.2.1.1.6.0")print("Localização:", sys_location)2. snmp.get_safe(config, oid)
Sección titulada «2. snmp.get_safe(config, oid)»Versión segura de getex que no lanza excepciones, retornando el error como segundo valor.
Parâmetros:
Sección titulada «Parâmetros:»-
config (tabela): Configuração SNMP
-
oid (string): OID a ser consultado
Retorno:
Sección titulada «Retorno:»-
tuple:
(valor, erro)donde:-
valor (qualquer tipo ou nil): Valor retornado se bem-sucedido
-
erro (string ou nil): Mensagem de error se falhar, nil se bem-sucedido
-
Exemplo de Uso:
Sección titulada «Exemplo de Uso:»local config = { address = "192.168.1.1", snmpVersion = 2, snmpCommunity = "public"}
-- Consulta segura que no rompe el script en caso de errorlocal valor, erro = snmp.get_safe(config, "1.3.6.1.2.1.1.1.0")
if erro then log.error("Falha na consulta SNMP:", erro) -- Tomar acción alternativaelse print("Valor obtido:", valor)end
-- Consultar múltiplos OIDs com tratamento de erro individuallocal oids = { "1.3.6.1.2.1.1.1.0", -- sysDescr "1.3.6.1.2.1.1.3.0", -- sysUpTime "1.3.6.1.2.1.1.5.0", -- sysName "1.3.6.1.2.1.1.6.0" -- sysLocation}
local resultados = {}for _, oid in ipairs(oids) do local valor, erro = snmp.get_safe(config, oid) if erro then log.warn("Falha no OID", oid, ":", erro) resultados[oid] = {erro = erro} else resultados[oid] = {valor = valor} endend3. snmp.get_bulk(config, oids)
Sección titulada «3. snmp.get_bulk(config, oids)»Realiza operación SNMP GET BULK para múltiples OIDs a la vez (SNMP v2c/v3).
Parâmetros:
Sección titulada «Parâmetros:»-
config (tabela): Configuração SNMP (deve ser v2 ou v3)
-
oids (array de strings): Lista de OIDs para consulta
Retorno:
Sección titulada «Retorno:»- tabela: Mapa OID → valor para todos los OIDs consultados
Comportamiento:
Sección titulada «Comportamiento:»-
Más eficiente que múltiples llamadas
getexpara muchos OIDs -
Soportado solo en SNMP v2c y v3
-
Usa
snmpMaxBulkItemsde la configuración para limitar tamaño
Exemplo de Uso:
Sección titulada «Exemplo de Uso:»local config = { address = "192.168.1.1", snmpVersion = 2, -- Deve ser v2 ou v3 para GET BULK snmpCommunity = "public", snmpMaxBulkItems = 50 -- Limitar a 50 OIDs por operación}
-- Consultar múltiplas informações do sistema de uma vezlocal oids = { "1.3.6.1.2.1.1.1.0", -- sysDescr "1.3.6.1.2.1.1.3.0", -- sysUpTime "1.3.6.1.2.1.1.5.0", -- sysName "1.3.6.1.2.1.1.6.0", -- sysLocation "1.3.6.1.2.1.1.7.0" -- sysServices}
local resultados = snmp.get_bulk(config, oids)
for oid, valor in pairs(resultados) do print("OID:", oid, "=", valor)end
-- Consultar información de múltiples interfaceslocal function obter_info_interfaces(config, indices) local oids = {} for _, idx in ipairs(indices) do table.insert(oids, "1.3.6.1.2.1.2.2.1.2." .. idx) -- ifDescr table.insert(oids, "1.3.6.1.2.1.2.2.1.3." .. idx) -- ifType table.insert(oids, "1.3.6.1.2.1.2.2.1.5." .. idx) end return snmp.get_bulk(config, oids)end4. snmp.get(oid)
Sección titulada «4. snmp.get(oid)»Versión simplificada de snmp.getex que usa automáticamente la configuración del dispositivo actual (params).
Parâmetros:
Sección titulada «Parâmetros:»- oid (string): OID a ser consultado
Retorno:
Sección titulada «Retorno:»- valor: Valor retornado pelo dispositivo SNMP
Comportamiento:
Sección titulada «Comportamiento:»-
Usa
paramscomo configuração -
Lança erro se o OID não existir ou houver falha na comunicação
Exemplo de Uso:
Sección titulada «Exemplo de Uso:»-- Consulta simplificada usando la configuración del dispositivo actuallocal sys_descr = snmp.get("1.3.6.1.2.1.1.1.0")print("Descrição do sistema:", sys_descr)
-- Consultar múltiplos OIDslocal uptime = snmp.get("1.3.6.1.2.1.1.3.0")local hostname = snmp.get("1.3.6.1.2.1.1.5.0")
print("Uptime:", uptime, "Hostname:", hostname)5. snmp.walk(oid, cache_ttl, enforce_ordering)
Sección titulada «5. snmp.walk(oid, cache_ttl, enforce_ordering)»Realiza una operación SNMP WALK con soporte de caché y ordenamiento.
Parâmetros:
Sección titulada «Parâmetros:»-
oid (string): OID base para el walk
-
cache_ttl (número, opcional): Tiempo de vida del caché en segundos
-
enforce_ordering (booleano, opcional): Forzar ordenación de los resultados (orden natural)
Comportamiento del cache:
Sección titulada «Comportamiento del cache:»- Usa caché cuando
cache_ttles especificado
Exemplo de Uso:
Sección titulada «Exemplo de Uso:»-- Walk con caché de 30 segundoslocal interfaces = snmp.walk("1.3.6.1.2.1.2.2.1.2", 30)for oid, ifname in pairs(interfaces) do print("Interface", oid, ":", ifname)end
-- Walk con ordenación forzada (sin caché)local ordered_interfaces = snmp.walk("1.3.6.1.2.1.2.2.1.2", nil, true)print("Total de interfaces:", #ordered_interfaces)Comportamiento de Ordenação:
Sección titulada «Comportamiento de Ordenação:»El parámetro enforce_ordering controla cómo se estructuran los resultados:
-
Cuando
false(padrão): Los resultados se retornan como una tabla Lua donde cada OID es una clave que mapea a su valor. Esta estructura es eficiente para acceso aleatorio, pero pierde la ordenación natural de los OIDs, ya que las tablas Lua no preservan el orden de inserción de las claves. -
Cuando
true: Los resultados se retornan como una lista de pares (tabla de tablas), donde cada elemento es una tabla conteniendo 2 elementos. Esta estructura preserva el orden natural de los OIDs tal como son retornados por el dispositivo SNMP.
Exemplo de diferença:
-- Com enforce_ordering = false (padrão)local resultado_tabela = snmp.walk("1.3.6.1.2.1.2.2.1.2", nil, false)-- Estrutura: { ["1.3.6.1.2.1.2.2.1.2.1"] = "eth0", ["1.3.6.1.2.1.2.2.1.2.2"] = "eth1" }-- A ordem das chaves não é garantida
-- Com enforce_ordering = truelocal resultado_lista = snmp.walk("1.3.6.1.2.1.2.2.1.2", nil, true)-- Estrutura: { {"1.3.6.1.2.1.2.2.1.2.1", "eth0"},-- {"1.3.6.1.2.1.2.2.1.2.2", "eth1"} }-- A ordem dos elementos é preservadaQuando usar cada modo:
-
Use
enforce_ordering = falsecuando solo necesita acceder valores por OID específico y el orden no importa. -
Use
enforce_ordering = truecuando necesita procesar los resultados en el mismo orden en que fueron retornados por el dispositivo, como para:-
Generar reportes ordenados
-
Procesar secuencias de índices consecutivos
-
Mantener correspondencia con otras listas ordenadas
-
Retorno:
Sección titulada «Retorno:»- tabela: Mapa OID → valor para todos os OIDs encontrados
6. snmp.walkex(device, oid, cache_ttl)
Sección titulada «6. snmp.walkex(device, oid, cache_ttl)»Función extendida de walk con sistema de caché avanzado y prevención de ejecuciones concurrentes.
Parâmetros:
Sección titulada «Parâmetros:»-
device (tabela): Configuração do dispositivo
-
oid (string): OID base para el walk
-
cache_ttl (número, opcional): Tiempo de vida del caché en segundos
Retorno:
Sección titulada «Retorno:»- tabela: Mapa OID → valor para todos los OIDs encontrados
Comportamiento:
Sección titulada «Comportamiento:»-
Implementa caché global compartido entre ejecuciones
-
Previene ejecuciones concurrentes del mismo walk
-
Usa
registrypara coordinar ejecuciones simultáneas
Exemplo de Uso:
Sección titulada «Exemplo de Uso:»-- Walk extendido con caché de 60 segundoslocal device_config = { address = "192.168.1.1", snmpVersion = 2, snmpCommunity = "public"}
local sys_oids = snmp.walkex(device_config, "1.3.6.1.2.1.1", 60)for oid, value in pairs(sys_oids) do print("OID:", oid, "Valor:", value)end7. snmp.count(oid)
Sección titulada «7. snmp.count(oid)»Cuenta el número de ítems retornados por un walk.
Parâmetros:
Sección titulada «Parâmetros:»- oid (string): OID base para contar
Retorno:
Sección titulada «Retorno:»- número: Cantidad de ítems encontrados
Exemplo de Uso:
Sección titulada «Exemplo de Uso:»-- Contar número de interfaceslocal num_interfaces = snmp.count("1.3.6.1.2.1.2.2.1.2")print("Número de interfaces:", num_interfaces)
-- Contar número de procesoslocal num_processes = snmp.count("1.3.6.1.2.1.25.4.2.1.2")print("Número de processos:", num_processes)8. snmp.diff(typ, lhs, rhs)
Sección titulada «8. snmp.diff(typ, lhs, rhs)»Calcula la diferencia entre dos valores, manejando rollover de contadores.
Parâmetros:
Sección titulada «Parâmetros:»-
typ (número): Tipo do contador (32 ou 64 bits)
-
lhs (número): Valor atual
-
rhs (número): Valor anterior
Retorno:
Sección titulada «Retorno:»- número: Diferença entre os valores
Comportamiento:
Sección titulada «Comportamiento:»-
Trata rollover de contadores de 32 y 64 bits
-
Señala
RepeatPrevValuesi la diferencia es negativa
Exemplo de Uso:
Sección titulada «Exemplo de Uso:»-- Calcular diferencia para contador de 32 bitslocal current_bytes = snmp.get("1.3.6.1.2.1.2.2.1.10.1") -- ifInOctets.1local prev_bytes = prev("1.3.6.1.2.1.2.2.1.10.1")local bytes_diff = snmp.diff(32, current_bytes, prev_bytes)
print("Bytes recebidos desde última leitura:", bytes_diff)9. inst(oid)
Sección titulada «9. inst(oid)»Resuelve dinámicamente OIDs de instancias basado en el nombre de la instancia.
Parâmetros:
Sección titulada «Parâmetros:»- oid (string): OID base (sin índice de instancia)
Retorno:
Sección titulada «Retorno:»- string: OID completo con índice de instancia
Comportamiento:
Sección titulada «Comportamiento:»-
Usa
params.InstanceNameeparams.snmpOIDDescpara resolución -
Soporta caché de instancias
-
Lança erro se a instância não for encontrada
Exemplo de Uso:
Sección titulada «Exemplo de Uso:»-- Resolver OID para instância específica-- params.InstanceName = "eth0"-- params.snmpOIDDesc = "1.3.6.1.2.1.2.2.1.2" -- ifDescr
local if_in_octets_oid = inst("1.3.6.1.2.1.2.2.1.10") -- ifInOctetsprint("OID resolvido:", if_in_octets_oid)-- Saída: "1.3.6.1.2.1.2.2.1.10.1" (se eth0 for índice 1)
-- Consultar usando OID resolvidolocal bytes_in = snmp.get(if_in_octets_oid)print("Bytes recebidos na interface eth0:", bytes_in)10. prev(oid)
Sección titulada «10. prev(oid)»Obtiene el valor anterior de un OID almacenado.
Parâmetros:
Sección titulada «Parâmetros:»- oid (string): OID para obtener valor anterior
Retorno:
Sección titulada «Retorno:»- qualquer tipo: Valor anterior almacenado, o 0 se no existir
Comportamiento:
Sección titulada «Comportamiento:»-
Busca valor en
store.get("snmp.value." .. oid) -
Retorna 0 si no encuentra valor almacenado
Exemplo de Uso:
Sección titulada «Exemplo de Uso:»-- Obtener valor anterior para cálculo de tasalocal current_value = snmp.get("1.3.6.1.2.1.2.2.1.16.1") -- ifOutOctets.1local previous_value = prev("1.3.6.1.2.1.2.2.1.16.1")
local bytes_out_diff = current_value - previous_valueprint("Bytes enviados desde última leitura:", bytes_out_diff)11. lapsed(oid)
Sección titulada «11. lapsed(oid)»Obtiene el tiempo transcurrido desde la última lectura de un OID.
Parâmetros:
Sección titulada «Parâmetros:»- oid (string): OID para verificar tiempo transcurrido
Retorno:
Sección titulada «Retorno:»- número: Tiempo en segundos desde la última lectura, o 1 si no hay registro
Exemplo de Uso:
Sección titulada «Exemplo de Uso:»-- Calcular tasa por segundolocal current_counter = snmp.get("1.3.6.1.2.1.2.2.1.10.1") -- ifInOctets.1local previous_counter = prev("1.3.6.1.2.1.2.2.1.10.1")local time_elapsed = lapsed("1.3.6.1.2.1.2.2.1.10.1")
local bytes_per_second = (current_counter - previous_counter) / time_elapsedprint("Taxa de recebimento:", bytes_per_second, "bytes/segundo")Exemplos Completos
Sección titulada «Exemplos Completos»Monitoramento de Interface de Rede:
Sección titulada «Monitoramento de Interface de Rede:»-- Resolver OID da interface eth0local if_index_oid = inst("1.3.6.1.2.1.2.2.1.1") -- ifIndexlocal if_descr_oid = inst("1.3.6.1.2.1.2.2.1.2") -- ifDescr
-- Obtener información de la interfazlocal interface_index = snmp.get(if_index_oid)local interface_name = snmp.get(if_descr_oid)
print("Monitorando interface:", interface_name, "(índice", interface_index, ")")
-- Recopilar estadísticaslocal in_octets = snmp.get(inst("1.3.6.1.2.1.2.2.1.10")) -- ifInOctetslocal out_octets = snmp.get(inst("1.3.6.1.2.1.2.2.1.16")) -- ifOutOctetslocal in_errors = snmp.get(inst("1.3.6.1.2.1.2.2.1.14")) -- ifInErrorslocal out_errors = snmp.get(inst("1.3.6.1.2.1.2.2.1.20")) -- ifOutErrors
-- Calcular diferencias desde la última lecturalocal time_elapsed = lapsed(inst("1.3.6.1.2.1.2.2.1.10"))local prev_in = prev(inst("1.3.6.1.2.1.2.2.1.10"))local prev_out = prev(inst("1.3.6.1.2.1.2.2.1.16"))
local in_rate = (in_octets - prev_in) / time_elapsedlocal out_rate = (out_octets - prev_out) / time_elapsed
print("Taxa de entrada:", in_rate, "bytes/seg")print("Taxa de saída:", out_rate, "bytes/seg")print("Erros de entrada:", in_errors)print("Erros de saída:", out_errors)Inventário de Interfaces com Walk:
Sección titulada «Inventário de Interfaces com Walk:»-- Listar todas las interfaces con walklocal interfaces = snmp.walk("1.3.6.1.2.1.2.2.1.2", 300) -- ifDescr com cache de 5 minutos
print("=== Inventário de Interfaces ===")for oid, ifname in pairs(interfaces) do -- Extraer índice de la interfaz del OID local index = string.match(oid, "(%d+)$")
-- Obtener tipo y estado de la interfaz local iftype = snmp.get("1.3.6.1.2.1.2.2.1.3." .. index) -- ifType local ifstatus = snmp.get("1.3.6.1.2.1.2.2.1.8." .. index) -- ifOperStatus
local status_text = "DOWN" if ifstatus == 1 then status_text = "UP" end
print(string.format("Interface %s: %s (Tipo: %d, Status: %s)", index, ifname, iftype, status_text))end
print("Total de interfaces:", snmp.count("1.3.6.1.2.1.2.2.1.2"))Monitoramento de Uso de CPU com Múltiplas Instâncias:
Sección titulada «Monitoramento de Uso de CPU com Múltiplas Instâncias:»-- Usar walk para obter todas as CPUslocal cpu_oids = snmp.walk("1.3.6.1.2.1.25.3.3.1.2", 30) -- hrProcessorLoad
local total_load = 0local cpu_count = 0
for oid, load in pairs(cpu_oids) do cpu_count = cpu_count + 1 total_load = total_load + load
local cpu_index = string.match(oid, "(%d+)$") print(string.format("CPU %d: %d%%", cpu_index, load))end
if cpu_count > 0 then local avg_load = total_load / cpu_count print(string.format("Média de uso de CPU: %.1f%%", avg_load))end