|

SIEM doméstico en Linux con ARP y OUI

En pocas palabras: Se monta con un script de Python que hace un ping sweep asíncrono de las 254 IPs de una /24, lee /proc/net/arp, resuelve el fabricante con un diccionario offline de 10 prefijos OUI (como Apple) y corre como servicio systemd. La versión base lista equipos, pero no alerta.

Un SIEM doméstico Linux es un monitor casero que vigila qué dispositivos hay en tu red local. La versión que publicó un autor en dev.to es un script de Python que lee la tabla ARP del kernel, identifica el fabricante por prefijo OUI y corre como servicio systemd.

SIEM (Security Information and Event Management) es una plataforma que junta, guarda y correlaciona eventos de seguridad para generar alertas. En una red casera, la versión mínima es saber qué equipos están conectados y enterarte cuando aparece uno nuevo. Para eso alcanza con la tabla ARP, donde el kernel de Linux asocia cada dirección IP con la MAC del equipo que la usa.

En 30 segundos

  • El script lee /proc/net/arp después de un ping sweep asíncrono de las 254 IPs de una /24 y muestra IP, MAC, interfaz y fabricante.
  • El fabricante sale de un diccionario offline con solo 10 prefijos OUI de muestra. Cualquier otra MAC aparece como “Fabricante Desconocido”.
  • No compara contra una lista de equipos autorizados, no alerta y no guarda eventos. Eso es lo que lo separa de un SIEM de verdad.
  • arpwatch, una herramienta con registro de eventos y aviso por mail, ya cubre la alerta por MAC nueva o cambiada.

¿Por qué conviene leer /proc/net/arp en lugar de correr Nmap todo el tiempo?

Porque el kernel ya guarda esa información y leerla no genera tráfico. Según el artículo de dev.to, Nmap sirve para auditorías puntuales, pero escanear de forma continua mete ruido de broadcast, puede trabar dispositivos IoT sensibles (lámparas y tomas Tuya/Sonoff) y gasta CPU. El autor afirma que leer el archivo consume casi 0% de CPU. Es un dato suyo, no lo medimos.

Ahora bien, la página arp(7) de man7 (Linux man-pages 6.19, febrero de 2026) marca límites que el artículo no menciona. La caché tiene tamaño limitado y el recolector descarta entradas viejas, con umbrales por defecto de 128, 512 y 1024 entradas (gc_thresh1, gc_thresh2 y gc_thresh3). Una entrada se considera vigente por unos 30 segundos (base_reachable_time_ms, 30000 por defecto) salvo que haya tráfico que la renueve.

Mi lectura: el “casi 0%” vale para leer el archivo, no para el ping sweep que el script lanza antes. Y un equipo que estuvo apagado o callado puede no aparecer.

¿Cómo averigua el script el fabricante de cada dispositivo por su MAC?

siem doméstico linux diagrama explicativo

Toma los primeros tres octetos de la MAC (el OUI, que la IEEE asigna a cada fabricante) y los busca en un diccionario de Python. No usa APIs externas. La función resolve_vendor corta los primeros 8 caracteres, por ejemplo AC:D1:B8, y devuelve el nombre o “Fabricante Desconocido” si no lo encuentra. Ya lo cubrimos antes en nuestra guía para desplegar un SIEM desde cero.

El diccionario del ejemplo tiene 10 prefijos: Apple, Samsung, Espressif (Tuya/Sonoff/IoT), Raspberry Pi, Realtek, Intel y alguno más. Es una muestra. No verificamos esos prefijos contra el registro de la IEEE, así que no los tomes como referencia.

Para uso real habría que cargar el registro OUI completo. Mientras tanto, arpwatch ya incluye el campo “ethernet vendor” en sus mails, como muestra el tutorial de Tecmint.

¿Qué le falta al script para ser un SIEM doméstico Linux?

Le falta casi todo lo que define a un SIEM: memoria, comparación y alertas. Lo que el código publicado hace es esto:

  • Ping sweep asíncrono. Lanza ping -c 1 -W 1 contra 192.168.1.1 a 192.168.1.254 con asyncio. El autor dice que tarda menos de 2 segundos (no verificado).
  • Lectura de la tabla ARP. Filtra entradas con flag 0x2 y MAC distinta de cero. Ese flag corresponde a ATF_COM, “lookup complete” en arp(7).
  • Salida por consola. Imprime IP, MAC, interfaz y fabricante, y termina.

Lo que no hace, viendo el código: no compara contra una lista de MACs autorizadas, no dispara alertas y no guarda eventos. El autor dice que la integración con eventos y SQLite WAL está en su artículo completo, que no leímos. Además, la subred 192.168.1 está fija (si tu red es 192.168.0.x, el barrido no encuentra nada), y las 254 tareas arrancan juntas, sin límite de concurrencia, algo a tener en cuenta en una Raspberry Pi vieja.

arpwatch hace otra cosa. Según Wikipedia, nació en el Lawrence Berkeley National Laboratory (primera versión en 1992), tiene licencia BSD y registra cada par IP/MAC con fecha, con aviso opcional por mail. Escucha el tráfico ARP en vez de consultar la caché, y Tecmint muestra que escribe “new station” y “changed station” en el log. Si necesitás un SIEM completo, existen Wazuh, Security Onion, Graylog o ELK, pero las fuentes no los tratan y no los comparo acá.

¿Cómo ejecutar un script de Python como servicio con systemd?

Guardás el script en /opt/network_sentry.py, creás una unidad en /etc/systemd/system/ y la activás con systemctl enable --now. La unidad de la fuente es esta:

[Unit]
Description=EVM Network Sentry SIEM Daemon
After=network.target

[Service]
Type=simple
User=root
ExecStart=/usr/bin/python3 /opt/network_sentry.py
Restart=always
RestartSec=180

[Install]
WantedBy=multi-user.target

Después corrés sudo systemctl daemon-reload y sudo systemctl enable --now network-sentry.service.

Esto se conecta con lo que analizamos en microVMs de Linux para armar laboratorios aislados.

Dos observaciones propias, derivadas del código. Primera: el script corre una vez y termina, así que Restart=always con RestartSec=180 lo relanza cada 3 minutos. Es un escaneo periódico, no un “daemon” continuo. Segunda: la unidad usa root, pero para leer /proc/net/arp no hace falta. Probá con un usuario sin privilegios, que en la mayoría de las distros alcanza para el ping, aunque no hay garantía.

¿Qué hacer cuando aparece un dispositivo desconocido en la red?

Primero confirmá si es tuyo. Un dispositivo nuevo no es un intruso hasta que lo verificás. La fuente propone dos medidas de contención:

  • Aislar el IoT en una VLAN. Separá lámparas, tomas y cámaras de las computadoras de trabajo.
  • Poner en cuarentena el equipo. Bloqueá el reenvío de paquetes de esa IP con reglas de iptables o en un router gestionable (MikroTik, OpenWrt, pfSense).

Ojo con los límites. Bloquear por IP es débil si el equipo cambia de IP, y una MAC se puede falsificar. Mi propuesta editorial de verificación (no viene de la fuente ni la probamos): anotá las MACs de tus equipos, compará con la lista del script o de arp -a, y apagá de a uno lo que no reconozcas hasta ver cuál desaparece de la lista. Relacionado: comparativa entre OrbStack y Multipass para entornos de prueba.

Qué está confirmado y qué no

  • Confirmado en el código y en la documentación: la lectura de /proc/net/arp, el filtro por flag 0x2, el diccionario de 10 prefijos, la unidad systemd y la existencia de arpwatch con alertas por mail.
  • Dato del autor, sin verificar: menos de 2 segundos para barrer una /24 y casi 0% de CPU al leer la tabla.
  • Pendiente: la integración con eventos y SQLite WAL, que está en un artículo que no leímos.

Errores comunes

  • Confiar en “Fabricante Desconocido” como alarma. Con solo 10 prefijos, casi todo sale desconocido. Los teléfonos modernos suelen usar MAC aleatoria por red, así que tampoco coinciden con el registro OUI.
  • Dejar la subred fija. Si tu LAN no es 192.168.1.0/24, el barrido no llena la tabla y la lista sale vacía.
  • Tomar el script por un SIEM. Sin lista de autorizados ni persistencia, te muestra el estado actual y nada más.
  • Dar por buena la unidad systemd tal cual. Corre como root y relanza cada 3 minutos. Revisalo antes de dejarlo en producción.

Preguntas Frecuentes

¿Cómo saber si alguien está conectado a mi red wifi desde Linux?

Corré arp -a para ver la tabla ARP actual, o el script de la fuente después del ping sweep. Comparás las MACs con tus equipos. Los que no reconozcas son candidatos a revisar. Si un equipo estuvo callado, puede no figurar.

¿Qué es el prefijo OUI de una dirección MAC?

El OUI son los primeros tres octetos de la MAC, asignados por la IEEE a cada fabricante. Buscándolo en el registro, sabés si un equipo es Apple, Samsung o Espressif. El script de ejemplo solo trae 10 prefijos.

¿Qué diferencia hay entre arpwatch y un script que lea la tabla ARP?

arpwatch registra los pares IP/MAC con fecha y avisa por mail cuando hay uno nuevo o cambiado. El script de la fuente consulta la caché del kernel y muestra una foto del momento, sin alertas ni historial.

¿Cómo ejecutar un script de Python como servicio con systemd?

Creás un archivo .service en /etc/systemd/system/ con ExecStart apuntando a python3 y tu script, y ejecutás systemctl daemon-reload y systemctl enable --now. Si el script termina solo, Restart=always lo relanza tras RestartSec.

¿Qué hago si detecto un dispositivo desconocido en mi red local?

Verificá primero que no sea tuyo. Si no lo es, bloqueá su tráfico en el router o con iptables y cambiá la clave del wifi. Tené presente que una MAC se puede falsificar y una IP cambiar.

Conclusión

El script es un buen punto de partida para ver tu red sin generar tráfico pesado, pero hoy es un inventario de equipos, no un SIEM. Si querés alertas ya, instalá arpwatch. Si preferís armar lo tuyo, agregá tres cosas: lista de MACs autorizadas, registro de eventos y la tabla OUI completa de la IEEE. Y revisá la unidad systemd antes de dejarla corriendo como root.

Fuentes

Te puede interesar...