Exploring the roots and future of Internet Relay Chat

Monitorizar tu red IRC con Prometheus y Grafana

En 2019, la red IRC que administraba perdio un servidor durante 45 minutos. Nos dimos cuenta porque un usuario nos escribio por email preguntando por que no podia conectar. No por nuestro monitoring — porque no teniamos monitoring. Teniamos 800 usuarios y cero visibilidad sobre el estado de nuestra infraestructura. Eso cambio ese mismo dia.

Por que monitorizar IRC

Una red IRC parece simple. Unos servidores, unos servicios, unos usuarios. Pero las cosas que pueden fallar son muchas y silenciosas. Un servidor que pierde conectividad con el hub y se queda aislado con 200 usuarios que no ven a los otros 600. Un proceso de servicios que consume toda la memoria y empieza a rechazar autenticaciones SASL. Un enlace server-to-server que pierde paquetes y la latencia sube a 5 segundos sin que nadie lo note hasta que los usuarios se quejan.

Sin monitoring, tu unica fuente de informacion son las quejas de los usuarios. Y los usuarios no se quejan de latencia — se van. No te dicen que SASL tarda 30 segundos — cambian de red. Tu red se muere lentamente y no lo sabes hasta que es demasiado tarde.

Con monitoring, ves los problemas antes de que los usuarios los noten. Una alerta salta cuando la latencia del link supera 500ms. Otra cuando el uso de memoria de servicios supera el 80%. Otra cuando un servidor pierde la conexion con el hub. Puedes actuar antes de que el problema se convierta en una caida.

El stack: Prometheus + Grafana

Prometheus es un sistema de monitoring basado en metricas. Cada cierto tiempo (por defecto 15 segundos), Prometheus visita endpoints HTTP de tus servicios, recoge metricas numericas, y las almacena en una base de datos de series temporales. Grafana se conecta a Prometheus y crea dashboards visuales con graficos, tablas, y alertas.

Por que este stack y no Nagios, Zabbix, o Datadog? Porque Prometheus es gratuito, corre en cualquier parte, consume pocos recursos, y el modelo de datos (metricas pull) se adapta perfectamente a la monitorizacion de infraestructura IRC. No necesitas instalar agentes en cada servidor — solo un endpoint HTTP que exporte metricas.

# Instalar Prometheus (Debian/Ubuntu):
sudo apt install prometheus

# O descargar el binario:
wget https://github.com/prometheus/prometheus/releases/download/v2.50.0/prometheus-2.50.0.linux-amd64.tar.gz
tar xzf prometheus-*.tar.gz
cd prometheus-*
./prometheus --config.file=prometheus.yml

# Instalar Grafana:
sudo apt install grafana
sudo systemctl enable grafana-server
sudo systemctl start grafana-server
# Accesible en http://tu.servidor:3000 (admin/admin)

El stack completo consume menos de 200 MB de RAM para una red IRC de tamano medio. Prometheus almacena 15 dias de metricas por defecto — ajustable segun tus necesidades de espacio en disco.

Metricas que importan

No todo lo medible es util. Para una red IRC, las metricas clave son:

  • Usuarios conectados (por servidor): Numero total y desglose por servidor. Si un servidor pierde usuarios de golpe, hay un problema.
  • Canales activos: Numero de canales con al menos un usuario. Indicador de salud general de la red.
  • Latencia inter-servidor: Tiempo de round-trip entre servidores. Si sube, los usuarios experimentan lag.
  • Conexiones nuevas por minuto: Tasa de conexiones. Un pico anormal puede indicar un ataque de botnets.
  • Autenticaciones SASL (exito/fallo): Ratio de fallos. Un aumento subito de fallos puede indicar brute-force o un problema con servicios.
  • Uso de CPU y memoria del IRCd: Para detectar leaks de memoria o carga excesiva.
  • Estado del enlace server-to-server: Up/down de cada link. El mas critico de todos.
  • K-lines y bans activos: Indicador de actividad de abuso.
Consejo: Empieza con pocas metricas y anade mas segun las necesites. Monitorizar todo desde el principio genera ruido y dashboards ilegibles. Las cinco metricas mas importantes son: usuarios totales, latencia de links, estado de links, uso de memoria, y tasa de conexiones.

Escribir un exporter IRC

No existe un exporter de Prometheus generico para IRC. Cada red tiene su IRCd y sus particularidades. Lo mas practico es escribir uno propio. Es mas facil de lo que parece — un exporter es un servidor HTTP que responde con metricas en formato texto.

# irc_exporter.py — Exporter basico para UnrealIRCd/InspIRCd
# Usa la conexion oper para obtener metricas via comandos IRC

import socket
import re
import time
from http.server import HTTPServer, BaseHTTPRequestHandler

IRC_SERVER = "127.0.0.1"
IRC_PORT = 6667
OPER_NAME = "monitor"
OPER_PASS = "password_del_oper_monitor"

def get_irc_stats():
    """Conecta al IRCd y recoge estadisticas via /LUSERS y /MAP"""
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.settimeout(10)
    sock.connect((IRC_SERVER, IRC_PORT))
    
    sock.send(b"NICK ircexporter\r\n")
    sock.send(b"USER exporter 0 * :IRC Exporter\r\n")
    time.sleep(2)
    
    # Autenticarse como oper:
    sock.send(f"OPER {OPER_NAME} {OPER_PASS}\r\n".encode())
    time.sleep(1)
    
    # Pedir estadisticas:
    sock.send(b"LUSERS\r\n")
    sock.send(b"MAP\r\n")
    time.sleep(2)
    
    data = b""
    while True:
        try:
            chunk = sock.recv(4096)
            if not chunk:
                break
            data += chunk
        except socket.timeout:
            break
    
    sock.send(b"QUIT\r\n")
    sock.close()
    return data.decode("utf-8", errors="replace")

def parse_metrics(raw):
    """Parsea la salida IRC en metricas Prometheus"""
    metrics = {}
    
    # Usuarios locales y globales (de LUSERS):
    m = re.search(r"(\d+) :Current local users", raw)
    if m:
        metrics["irc_users_local"] = int(m.group(1))
    m = re.search(r"(\d+) :Current global users", raw)
    if m:
        metrics["irc_users_global"] = int(m.group(1))
    
    # Servidores:
    m = re.search(r"(\d+) :servers", raw)
    if m:
        metrics["irc_servers_total"] = int(m.group(1))
    
    # Canales:
    m = re.search(r"(\d+) :channels formed", raw)
    if m:
        metrics["irc_channels_total"] = int(m.group(1))
    
    return metrics

class MetricsHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path != "/metrics":
            self.send_response(404)
            self.end_headers()
            return
        
        try:
            raw = get_irc_stats()
            metrics = parse_metrics(raw)
        except Exception as e:
            metrics = {"irc_exporter_errors_total": 1}
        
        output = ""
        for name, value in metrics.items():
            output += f"{name} {value}\n"
        
        self.send_response(200)
        self.send_header("Content-Type", "text/plain")
        self.end_headers()
        self.wfile.write(output.encode())
    
    def log_message(self, format, *args):
        pass  # Silenciar logs HTTP

if __name__ == "__main__":
    server = HTTPServer(("0.0.0.0", 9100), MetricsHandler)
    print("IRC exporter corriendo en :9100/metrics")
    server.serve_forever()

Este exporter es basico pero funcional. Se conecta al IRCd cada vez que Prometheus lo scrapea, ejecuta LUSERS para obtener contadores globales, y devuelve las metricas en formato Prometheus. Para produccion, anadele: cache de metricas (no conectar al IRCd en cada request), manejo de errores robusto, y metricas adicionales parseando la salida de MAP y STATS.

Para metricas de sistema (CPU, memoria, disco del servidor), usa el Node Exporter estandar de Prometheus. No reinventes la rueda para metricas de sistema operativo.

Configurar Prometheus

# prometheus.yml
global:
  scrape_interval: 30s      # Cada 30 segundos
  evaluation_interval: 30s

scrape_configs:
  # Metricas IRC:
  - job_name: 'irc'
    static_configs:
      - targets:
        - 'hub.tudominio.com:9100'
        - 'leaf1.tudominio.com:9100'
        - 'leaf2.tudominio.com:9100'
        labels:
          network: 'mired'

  # Metricas de sistema (node_exporter):
  - job_name: 'node'
    static_configs:
      - targets:
        - 'hub.tudominio.com:9101'
        - 'leaf1.tudominio.com:9101'
        - 'leaf2.tudominio.com:9101'

  # Metricas de servicios (Anope):
  - job_name: 'services'
    static_configs:
      - targets:
        - 'services.tudominio.com:9102'

# Reglas de alerta (en un archivo separado):
rule_files:
  - 'irc_alerts.yml'

Un scrape_interval de 30 segundos es suficiente para IRC. No necesitas mas resolucion — los eventos IRC relevantes (caidas de servidor, picos de trafico) duran minutos, no segundos. Intervalos mas cortos generan mas datos sin aportar mas visibilidad.

Dashboards en Grafana

Una vez que Prometheus tiene datos, Grafana los visualiza. Anade Prometheus como data source en Grafana (Settings > Data Sources > Add data source > Prometheus, URL: http://localhost:9090) y crea un dashboard.

Los paneles esenciales para un dashboard IRC:

# Queries PromQL para Grafana:

# Usuarios globales (grafico lineal):
irc_users_global

# Usuarios por servidor (grafico apilado):
irc_users_local{job="irc"}

# Tasa de conexiones por minuto:
rate(irc_connections_total[5m]) * 60

# Memoria del IRCd:
process_resident_memory_bytes{job="irc"} / 1024 / 1024

# Estado de links (indicador up/down):
irc_link_up{job="irc"}

# Latencia de links (grafico lineal con threshold):
irc_link_latency_seconds{job="irc"}

# Ratio de fallos SASL:
rate(irc_sasl_failures_total[5m]) / 
  (rate(irc_sasl_successes_total[5m]) + rate(irc_sasl_failures_total[5m]))

Organiza el dashboard en filas: fila de resumen (usuarios, canales, servidores), fila de rendimiento (latencia, memoria, CPU), fila de seguridad (conexiones, SASL, bans). Anade variables de Grafana para filtrar por servidor si tienes mas de tres.

Para equipos que gestionan infraestructura IT mas amplia — no solo IRC sino servidores, redes, aplicaciones — herramientas como las que ofrece PowerITi integran la monitorizacion con la gestion global del parque informatico, lo que simplifica tener visibilidad unificada sobre todos los servicios.

Atencion: No expongas Grafana a Internet sin autenticacion. Por defecto viene con admin/admin. Cambia la contrasena inmediatamente, o mejor, pon Grafana detras de un reverse proxy con autenticacion externa (OAuth, LDAP).

Alertas que salvan la red

# irc_alerts.yml — Reglas de alerta para Prometheus
groups:
  - name: irc
    rules:
      # Alerta si un servidor pierde conexion:
      - alert: IRCServerDown
        expr: up{job="irc"} == 0
        for: 2m
        labels:
          severity: critical
        annotations:
          summary: "Servidor IRC {{ $labels.instance }} caido"
          description: "No responde desde hace 2 minutos."

      # Alerta si usuarios bajan mas de 20% en 5 minutos:
      - alert: IRCUserDrop
        expr: |
          (irc_users_global offset 5m - irc_users_global)
            / irc_users_global offset 5m > 0.2
        for: 1m
        labels:
          severity: warning
        annotations:
          summary: "Caida de usuarios >20% en 5 minutos"

      # Alerta si memoria supera 80%:
      - alert: IRCHighMemory
        expr: |
          process_resident_memory_bytes{job="irc"}
            / node_memory_MemTotal_bytes * 100 > 80
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Memoria alta en {{ $labels.instance }}"

      # Alerta si latencia de link supera 1 segundo:
      - alert: IRCHighLatency
        expr: irc_link_latency_seconds > 1
        for: 3m
        labels:
          severity: warning
        annotations:
          summary: "Latencia alta en link {{ $labels.link }}"

      # Alerta si tasa de conexiones es anormalmente alta:
      - alert: IRCConnectionFlood
        expr: rate(irc_connections_total[2m]) * 60 > 100
        for: 2m
        labels:
          severity: critical
        annotations:
          summary: "Posible flood de conexiones (>100/min)"

Las alertas de Prometheus se envian a Alertmanager, que las rutea a Slack, email, PagerDuty, o cualquier webhook. Para una red IRC pequena, un webhook a un canal de IRC dedicado es lo mas natural — la alerta aparece en #oper-alerts y el equipo la ve inmediatamente.

Preguntas frecuentes

Necesito monitoring si mi red tiene menos de 100 usuarios?

Si. Los problemas de infraestructura no dependen del numero de usuarios. Un servidor que se queda sin disco, un certificado TLS que expira, un enlace que se cae — todo esto pasa independientemente de cuantos usuarios tengas. La complejidad del setup de monitoring si puede simplificarse: un solo Prometheus, un dashboard basico, tres o cuatro alertas.

Puedo monitorizar IRC sin Prometheus?

Si. Un script de Nagios/Icinga que se conecte al IRCd y verifique que responde es mejor que nada. Munin puede graficar metricas basicas. Pero Prometheus + Grafana es el estandar actual y la inversion de tiempo en aprenderlo se amortiza rapidamente.

El exporter necesita ser oper?

Para metricas basicas (LUSERS, MAP) no necesariamente, aunque depende del IRCd. Algunos restringen MAP a opers. Para metricas detalladas (STATS), si. Crea un oper dedicado para monitoring con permisos minimos — solo lectura de estadisticas, sin capacidad de kill o ban.