Exploring the roots and future of Internet Relay Chat

Protección contra flood en IRC: rate limiting, penalidades y throttling

Era 2001, un sábado por la noche. Administraba un servidor de IRC con 400 usuarios. De repente, los logs empezaron a llenarse a velocidad absurda. Alguien estaba enviando 200 mensajes por segundo a 15 canales simultáneamente. El servidor consumió toda la RAM en 45 segundos y cayó. Reinicié. Volvió a caer. Ese fue el día que aprendí que un servidor IRC sin protección anti-flood es un servidor muerto en espera.

Qué es el flood y por qué existe

Flood en IRC es el envío masivo de datos para desestabilizar un servidor, un canal o un usuario. Puede ser texto repetido, comandos IRC en ráfaga, conexiones y desconexiones masivas, o paquetes malformados diseñados para consumir recursos.

Hay tres tipos principales. El message flood es el más obvio: enviar cientos de líneas por segundo a un canal. Satura el buffer de envío del servidor y de todos los clientes en el canal. El connection flood abre cientos de conexiones TCP simultáneas sin completar el registro IRC, agotando los slots de conexión. El CTCP flood envía miles de peticiones CTCP VERSION o PING que cada cliente intenta responder, creando un efecto amplificador.

¿Por qué existe? Las motivaciones varían. Venganza personal entre usuarios. Guerras entre canales o redes. Aburrimiento puro. He visto ataques de flood que duraron semanas, lanzados por alguien enfadado porque le banearon de un canal. La motivación es irrelevante para el sysadmin — lo que importa es la mitigación.

El protocolo IRC original (RFC 1459) apenas mencionaba el flood control. Se asumía que los usuarios serían razonables. Suposición incorrecta, como la historia demostró repetidamente. Cada generación de ircds ha tenido que inventar sus propias defensas.

El penalty system: la primera defensa

El penalty system es el mecanismo anti-flood más elegante del IRC. Funciona así: cada comando que envías al servidor tiene un coste en "puntos de penalidad". Enviar un PRIVMSG cuesta 1 punto. JOIN cuesta 2. MODE cuesta 1-3 dependiendo de los parámetros. Los puntos se acumulan y se consumen a una tasa fija — generalmente 1 punto por segundo.

Si tus puntos acumulados superan un umbral (típicamente 10-15), el servidor deja de procesar tus comandos hasta que la penalidad baje. No te desconecta inmediatamente — simplemente te ralentiza. Es como un semáforo que se pone rojo cuando vas demasiado rápido.

# Ejemplo de costes de penalidad (UnrealIRCd)
# Estos valores varían por ircd

PRIVMSG/NOTICE  = 1 punto por mensaje
JOIN            = 2 puntos
PART            = 1 punto
KICK            = 1 punto
MODE            = 1-3 puntos (según complejidad)
TOPIC           = 1 punto
WHO             = 1-5 puntos (según amplitud)
LIST            = 5 puntos
NAMES           = 1 punto por canal

# Tasa de consumo: 1 punto/segundo
# Umbral de exceso: 10 puntos
# Umbral de kill: 20 puntos

# Ejemplo de flujo:
# t=0: envías PRIVMSG (1pt) → acumulado=1
# t=0: envías PRIVMSG (1pt) → acumulado=2
# t=0: envías PRIVMSG (1pt) → acumulado=3
# t=1: se consume 1pt → acumulado=2
# t=1: envías JOIN (2pt) → acumulado=4
# ... si llegas a 10, el servidor te frena

Lo bueno del penalty system es que es invisible para el usuario normal. Si chateas a velocidad humana, nunca llegas al umbral. Solo lo notas cuando intentas pegar un bloque de texto grande o ejecutas un script que envía comandos en ráfaga. Es una defensa proporcional: cuanto más rápido envías, más freno recibes.

Rate limiting a nivel de servidor

Más allá del penalty system individual, los ircds modernos implementan rate limiting global. Esto protege contra ataques distribuidos donde muchos clientes envían a velocidad "normal" individualmente pero el volumen agregado es destructivo.

# UnrealIRCd – set::anti-flood (unrealircd.conf)
set {
    anti-flood {
        # Límite de mensajes por usuario
        target-flood {
            channel-privmsg  5:3;    # 5 msgs en 3 segs = flood
            channel-notice   3:3;
            private-privmsg  4:5;
            private-notice   3:5;
        }

        # Qué hacer cuando se detecta flood
        # opciones: block, kill, tempshun, gline
        target-flood-action block;

        # Throttle de conexiones nuevas
        connect-flood 3:60;          # Max 3 conexiones en 60 segs por IP

        # Protección contra nick flood
        nick-flood 3:60;             # Max 3 cambios de nick en 60 segs

        # Protección JOIN/PART
        join-flood 4:30;             # Max 4 JOINs en 30 segs

        # Protección AWAY
        away-flood 3:120;
    }
}

Cada parámetro tiene un formato N:T que significa "máximo N acciones en T segundos". Superar el límite activa la acción configurada. block simplemente ignora los mensajes extra. kill desconecta al usuario. gline banea la IP temporalmente.

La elección de la acción depende de tu contexto. Para un servidor público, block es razonable como primera respuesta. Para un servidor que sufre ataques frecuentes, gline con duración de 1 hora es más apropiado. Nunca pongas kill con umbrales bajos — vas a desconectar a usuarios legítimos que simplemente pegan texto.

Throttling de conexiones

El connection flood es diferente al message flood. No necesitas enviar mensajes — basta con abrir conexiones TCP rápidamente para agotar los recursos del servidor. Cada conexión pendiente consume un slot, un file descriptor, y algo de memoria. Miles de conexiones simultáneas desde botnets pueden tumbar un servidor antes de que ningún usuario llegue a escribir una línea.

# InspIRCd – Protección contra connection flood
# inspircd.conf

# Módulo connectban: banea IPs que fallan conexiones
<module name="connectban">
<connectban threshold="3"
            duration="10m"
            ipv4cidr="32"
            ipv6cidr="128"
            banmessage="Tu IP ha sido baneada por flood de conexiones.">

# Módulo connflood: limita conexiones globales
<module name="connflood">
<connflood maxconns="3"
           timeout="30"
           quitmsg="Throttled"
           bootwait="10">

# Clase de conexión con límites
<connect name="main"
         allow="*"
         maxchans="20"
         limit="3"                 # Max 3 conexiones por IP
         timeout="120"
         pingfreq="120"
         hardsendq="1048576"
         softsendq="524288"
         recvq="8192"
         threshold="10"
         commandrate="1000">      # Milisegundos mín entre comandos

El parámetro recvq es sutil pero vital. Define el tamaño del buffer de recepción por cliente. Si un cliente envía más datos de lo que cabe en el recvq sin que el servidor los procese, la conexión se corta. Un recvq de 8192 bytes es suficiente para uso normal pero impide que alguien envíe un megabyte de texto de golpe.

hardsendq y softsendq controlan el buffer de envío. Si el servidor tiene un millón de bytes pendientes de enviar a un cliente (porque el cliente no lee lo suficientemente rápido), cierra la conexión. Esto previene que un cliente "lento" consuma memoria indefinidamente.

Consejo: Complementa las protecciones del ircd con iptables/nftables a nivel del sistema operativo. Un -m connlimit --connlimit-above 5 por IP impide que el tráfico llegue siquiera al ircd. La defensa en capas siempre es más eficaz que una sola capa, por buena que sea.

Protección a nivel de canal

Los operadores de canal tienen sus propias herramientas anti-flood, independientes de las del servidor.

# Modos de canal anti-flood

# +f [líneas:segundos] – InspIRCd/UnrealIRCd
# Activa automáticamente +m (moderado) si se supera el límite
/mode #canal +f [10:5]
# Si hay 10+ mensajes en 5 segundos, el canal se modera

# +F [líneas:segundos:acción] – UnrealIRCd extendido
/mode #canal +f [10c#C5:5]
# 10 mensajes en 5 segs = canal +C (no colores) por 5 minutos

# +j N:T – Throttle de JOINs
/mode #canal +j 5:30
# Máximo 5 JOINs en 30 segundos, luego bloquea nuevos JOINs

# +m – Moderado manual
# Solo +v (voice) puede hablar
/mode #canal +m

# +R – Solo usuarios registrados
# Filtra la mayoría de bots no registrados
/mode #canal +R

# +K – No KNOCK
# Evita flood de peticiones de entrada
/mode #canal +K

El modo +f es el más potente para defensa automática. Puedes configurar umbrales para texto, joins, CTCP, nicks y kicks. Cada tipo de flood tiene su propia acción. Es como un firewall a nivel de canal.

En la práctica, combino +f con +R en canales que sufren ataques recurrentes. +R requiere que los usuarios estén registrados en NickServ para hablar. Esto elimina el 90% de los bots de flood, porque la mayoría no se molesta en registrar nicks. No es perfecto, pero reduce el ruido drásticamente.

Configuración práctica por ircd

Cada ircd tiene su enfoque. Aquí van configuraciones probadas para los tres más usados.

# ERGO – ircd.yaml (sección throttling)
server:
    ip-limits:
        count: 5               # Max 5 conexiones por IP
        duration: 10m          # Ventana de tiempo

    connection-throttling:
        enabled: true
        cidr-len-ipv4: 32      # Throttle por /32 (IP individual)
        cidr-len-ipv6: 64      # Throttle por /64
        connections-per-period: 12
        period: 1m

    connection-limits:
        cidr-len-ipv4: 32
        cidr-len-ipv6: 64
        ips-per-subnet: 16     # Max 16 IPs por subnet
        exempted:
            - "127.0.0.0/8"
            - "::1/128"

channels:
    registration:
        enabled: true
    default-modes: "+nt"       # No mensajes externos + topic protegido

Ergo tiene la configuración más limpia porque usa YAML. Todo está en un solo archivo, bien documentado. Los valores por defecto son razonables para la mayoría de escenarios. Si administras un servidor pequeño-medio (hasta 1000 usuarios), los defaults de Ergo funcionan sin tocar nada.

Advertencia: No copies configuraciones anti-flood de internet sin entender cada parámetro. Un connect-flood 1:300 (1 conexión cada 5 minutos por IP) puede parecer seguro, pero bloqueará a usuarios legítimos detrás de NAT que comparten IP. Entiende tu base de usuarios antes de ajustar los umbrales.

Ataques reales y cómo se pararon

Voy a describir tres ataques que viví como operador y cómo los resolvimos. Sin nombres de redes ni personas, pero los detalles técnicos son reales.

Caso 1: Clone flood. Alguien conectó 300 clones desde una botnet distribuida. Cada clone entraba a los 10 canales más grandes y enviaba un mensaje cada 3 segundos. Individualmente estaban por debajo del umbral anti-flood. El volumen agregado era devastador: 1000 mensajes por segundo en total. La solución fue activar +R (solo registrados) en todos los canales grandes y un G-line temporal por rango de IP a los subredes más activas. En 20 minutos los clones dejaron de ser efectivos.

Caso 2: CTCP flood amplificado. Un usuario enviaba CTCP VERSION a canales de 500 personas. Cada persona respondía automáticamente. Resultado: 500 respuestas CTCP por cada petición. Efecto multiplicador. El usuario atacante apenas consumía ancho de banda, pero las víctimas saturaban sus propias conexiones respondiendo. Solución: desactivar respuestas CTCP automáticas a canales a nivel de ircd y añadir rate limiting a respuestas CTCP por usuario.

Caso 3: Slowloris IRC. Parecido al ataque Slowloris de HTTP. Cientos de conexiones que iniciaban el handshake TCP pero enviaban datos IRC muy lentamente — un byte cada 10 segundos. Nunca completaban el registro (NICK/USER), así que no contaban como usuarios, pero mantenían slots de conexión ocupados indefinidamente. Solución: reducir el timeout de registro a 30 segundos. Si no completas NICK + USER en 30 segundos, te desconectan. Simple y efectivo.

Cada ataque te enseña algo. Después de 25 años gestionando servidores IRC, mi filosofía es: umbrales conservadores por defecto, monitorización activa para detectar anomalías, y un playbook de respuesta para cada tipo de ataque conocido. No existe la protección perfecta, pero puedes hacer que atacar tu servidor sea tan costoso que no valga la pena.

Preguntas frecuentes

¿Puedo usar fail2ban con IRC?

Sí, y es una combinación excelente. Configura fail2ban para leer los logs del ircd y banear IPs que generen patrones de flood. Por ejemplo, una regla que detecte más de 5 "Excess Flood" kills en 10 minutos desde la misma IP y aplique un ban de 1 hora en iptables. Esto descarga trabajo del ircd al firewall del sistema operativo, que es más eficiente procesando bans.

¿Los bouncers como ZNC causan problemas con el anti-flood?

Pueden. Un bouncer con muchos usuarios conecta desde una sola IP, lo que puede disparar el throttling de conexiones. La solución es añadir la IP del bouncer a la lista de excepciones del ircd. La mayoría de ircds permiten excepciones por IP o por rango CIDR. Documenta estas excepciones para no olvidar por qué existen.

¿Qué valores anti-flood usar para un servidor público nuevo?

Empieza con valores permisivos y ajusta según la actividad real. Sugerencia inicial: 5 mensajes en 3 segundos para message flood, 3 conexiones en 60 segundos por IP, timeout de registro de 60 segundos. Monitoriza los logs durante las primeras semanas y ajusta según lo que veas. Ser demasiado estricto desde el principio espanta a usuarios legítimos.