Puntos ciegos
Existe una gran cantidad de tráfico malicioso en Internet y es imposible bloquearlo todo. Sin embargo, existen herramientas que ayudan a reducir considerablemente la superficie de ataque: proxies como Squid, firewalls como iptables o nftables, sistemas como fail2ban y muchas otras. Hoy hablaremos de Suricata, pero desde una perspectiva diferente.
Se ha escrito mucho sobre este IDS/IPS. Hay excelentes tutoriales sobre su instalación, configuración y reglas, por lo que no profundizaré en esos aspectos. En cambio, hoy abordaré un problema que suele pasar desapercibido en redes LAN pequeñas y medianas, y es cómo aprovechar la capacidad de detección de Suricata sin asumir el costo que implica convertirlo en un IPS. Pero antes, un poco de contexto.
Filtrado DNS y Proxy: Dos versiones del mismo problema
Es común pensar que un proxy o un filtro DNS (como Pi-hole) son suficientes para detener el tráfico malicioso. En realidad, ambos tienen limitaciones estructurales. Por ejemplo, en el caso del proxy Squid podemos bloquear conexiones directas hacia direcciones IP mediante reglas como las siguientes:
# Block: Direct IPv4
acl direct_ipv4 dstdom_regex -n -i ^([0-9]{1,3}\.){3}[0-9]{1,3}$
http_access deny direct_ipv4
# Block: Direct IPv6
acl direct_ipv6 dstdom_regex -n -i ^\[([0-9a-f:]+)\]$
http_access deny direct_ipv6
Estas reglas funcionan correctamente, e impiden que el tráfico malicioso haga peticiones a sus propias IPs y nos permite declarar antes una lista blanca para excluir las IPs que nos interesa antes de cerrar el grifo, pero estas reglas aplican únicamente sobre el tráfico que ya está siendo procesado por el proxy. Si un cliente intenta abrir un
CONNECT 37.17.94.15:443 a través de Squid, será bloqueado, pero Squid jamás verá el tráfico que no pase por el proxy, por ejemplo, conexiones UDP y TCP directas utilizadas por protocolos como BitTorrent DHT o la red TOR. Con el filtrado DNS ocurre exactamente el mismo problema. Herramientas como Pi-hole, OpenDNS o cualquier otro resolver DNS basado en listas negras, bloquean un dominio antes de resolverlo, devolviendo NXDOMAIN o una dirección inexistente. Mientras el cliente dependa del DNS, el mecanismo funciona perfectamente. El problema aparece cuando la aplicación nunca necesita resolver un nombre de dominio. Algunos ejemplos:
- BitTorrent DHT: los clientes descubren otros pares mediante el propio protocolo DHT (Kademlia). Obtienen directamente direcciones IP y puertos de otros nodos, sin realizar consultas DNS.
- TOR: el cliente descarga el documento de consenso con la lista de relays disponibles y establece conexiones directamente hacia esas direcciones IP, sin consultar el DNS para cada conexión.
- Web3 / Blockchain: los nodos de redes como Ethereum o Bitcoin descubren pares mediante su propio protocolo de descubrimiento (Kademlia-like en el caso de Ethereum, gossip de direcciones en Bitcoin), obteniendo IP y puerto directamente de otros nodos, sin depender del DNS para cada conexión.
En los tres casos, el tráfico nunca atraviesa la capa de control del proxy ni del resolver DNS. Este punto ciego es compartido por ambas soluciones.
Nota: no todo el tráfico relacionado con blockchain constituye un punto ciego. Muchos servicios RPC públicos (como Infura, Alchemy o QuickNode) dependen de DNS y HTTPS, por lo que pueden ser bloqueados por un filtro DNS o un proxy. Lo mismo ocurre con malware cuyo C2 utiliza nombres de dominio. Incorporar estas comunicaciones al mecanismo basado en Suricata -que explicaremos más adelante- añade una capa adicional de protección que continúa siendo efectiva si los controles basados en DNS o proxy son eludidos.
¿Qué aporta Suricata?
Suricata no depende de que el cliente utilice un proxy ni un servidor DNS determinado. Analiza una copia del tráfico directamente sobre la interfaz de red, observando todos los paquetes independientemente del protocolo utilizado, del puerto empleado o de si existió una consulta DNS previa. Gracias a ello puede identificar patrones propios de protocolos como BitTorrent DHT, relays TOR, User-Agent sospechosos, indicadores de compromiso y miles de firmas adicionales directamente sobre el contenido de los paquetes. Desde la perspectiva de detección, Suricata elimina los puntos ciegos descritos anteriormente.
Cuello de botella
El costo de esa visibilidad es que Suricata debe inspeccionar todo el tráfico con todo lo que esto implica. En modo IDS (el modo utilizado por la mayoría de las instalaciones), Suricata analiza cada paquete contra miles de firmas y simplemente genera alertas, pero si queremos que bloquee tráfico (modo IPS mediante NFQUEUE), cada paquete debe ser inspeccionado antes de que el kernel decida si continúa o no.
Esto no representa un problema para las grandes empresas con High-End Gateways -que cuentan con aceleración por hardware (ASIC/NPU)-, pero para las pequeñas y medianas empresas con gateways de gama moderada, activar el modo IPS implica un enorme cuello de botella. La inspección profunda de paquetes y el alto volumen de conexiones concurrentes, introducen un nuevo problema: latencia, incremento en el uso de CPU y degradación del rendimiento general de la red.
Workaround
Nuestra propuesta consiste en dejar que cada herramienta haga aquello para lo que fue diseñada. Suricata continúa funcionando como IDS, fuera del camino del paquete, mientras que el firewall sigue siendo el encargado de bloquear. El proceso es sencillo:
- Se selecciona un subconjunto de firmas sobre las cuales realmente interesa actuar y de introducen en un archivo llamado
drop.conf, reduciendo así el ruido y falsos positivos. Esta lista puede ir creciendo con el tiempo, a medida que salen nuevas alertas relevantes. - Suricata continúa inspeccionando el tráfico y registrando alertas sin intervenir en el flujo de los paquetes.
- Un proceso periódico muy liviano -bash script programado preferentemente en
cron- lee únicamente las nuevas entradas del registro de alertas, filtra las correspondientes al subconjunto de firmas dedrop.confy extrae las direcciones IP involucradas. - Esas direcciones IP -de destino, para no penalizar la IP de la LAN por un solo evento- se almacenan en una lista permanente que alimenta un
ipsetbasado enhash:ip. - El firewall (iptables, nftables y similares) consulta ese
ipsetmediante una única regla y descarta cualquier conexión dirigida a esa lista de direcciones IP.
La inspección profunda continúa realizándose únicamente en Suricata, mientras que la decisión de bloqueo recae sobre el firewall mediante una consulta O(1) a un conjunto hash. El costo adicional es mínimo: una lectura incremental del archivo de alertas y unas pocas inserciones en el
ipset. El resultado es una arquitectura que aprovecha la capacidad de detección de Suricata sin convertirlo en un IPS en línea, reemplazando el bloqueo en línea por uno basado en ipset, mucho más eficiente. Los puntos ciegos del proxy y del filtrado DNS siguen desapareciendo, ya que el bloqueo se realiza sobre las direcciones IP detectadas por el IDS, independientemente del protocolo utilizado, del puerto o de si existió una consulta DNS previa.
Cada componente cumple una función específica:
- Suricata detecta.
- El proceso auxiliar transforma las alertas en inteligencia utilizable.
- El firewall aplica el bloqueo mediante
ipsetcon un costo constante y sin introducir inspección profunda en el camino de cada paquete.
Ejemplo:
# SURIDATA
suridatalst="$acl_ipt_path/suridata.txt"
if ! ipset list suridata &>/dev/null; then
ipset create suridata hash:ip -exist
else
ipset flush suridata
fi
if [ -f "$suridatalst" ]; then
for suridataip in $(grep -vE '^\s*#|^\s*$' "$suridatalst" | sort -u 2>/dev/null); do
is_valid_ip "$suridataip" && ipset add suridata "$suridataip" -exist
done
else
log "WARNING: $suridatalst not found -- skipping suridata"
fi
iptables -t mangle -A PREROUTING -i "$lan" -m set --match-set suridata dst -j NFLOG --nflog-prefix "SURIDATA DROP: "
iptables -t mangle -A PREROUTING -i "$lan" -m set --match-set suridata dst -j DROP
Esta arquitectura resulta especialmente adecuada para gateways de redes pequeñas y medianas, donde el rendimiento es tan importante como la capacidad de detección y el mecanismo descrito no depende de un conjunto específico de firmas. En este artículo se utiliza con alertas relacionadas con BitTorrent y TOR, pero puede extenderse a cualquier SID de Suricata que el administrador decida incorporar a
drop.conf -incluidas firmas específicas de blockchain, siempre que exista cobertura real en el ruleset, como se mencionó antes-. A partir de ese momento, las direcciones IP asociadas a dichas alertas pasarán automáticamente a formar parte de las listas de bloqueo del firewall.
Recomendación
La solución descrita en este artículo está orientada a redes LAN pequeñas y medianas donde toda la infraestructura opera sobre IPv4 y el acceso a Internet se realiza exclusivamente mediante este protocolo.
En este escenario, mantener IPv6 habilitado cuando no se utiliza aporta poco valor y, en cambio, introduce una segunda pila de red que debe administrarse y protegerse por separado. Protocolos como NDP (Neighbor Discovery Protocol) reemplazan a ARP, las reglas del firewall deben duplicarse en
ip6tables o su equivalente, y las listas de bloqueo, firmas y controles también deben contemplar direcciones IPv6. Si la organización no tiene previsto utilizar IPv6 a corto o mediano plazo, es recomendable deshabilitarlo tanto en el gateway como en los equipos cliente. De esta forma se reduce la superficie de ataque, se simplifica la administración del firewall y se evita que tráfico IPv6 eluda controles diseñados únicamente para IPv4.
Esta recomendación no implica que IPv6 sea inseguro o deba deshabilitarse de forma general. Si la infraestructura utiliza IPv6 de manera activa, la solución debe extenderse para inspeccionar y aplicar las mismas políticas de seguridad sobre ambos protocolos.
Puede consultar los archivos en nuestro repositorio Vault/Gateproxy.

Post a Comment