Exploring the roots and future of Internet Relay Chat

DNS round-robin y anycast para redes IRC

Cuando montamos el segundo servidor de nuestra red IRC en 2004, el primer problema fue: como hacemos que los usuarios se distribuyan entre ambos? Publicar dos dominios (eu.mired.com y us.mired.com) era posible pero feo — los usuarios no quieren elegir servidor. Quieren conectar a irc.mired.com y que funcione. La solucion mas simple era DNS round-robin. No era perfecta, pero era gratuita, facil de implementar, y funciono durante anos.

El problema: un dominio, multiples servidores

Tu red IRC tiene tres servidores en tres ciudades diferentes. Quieres que los usuarios conecten a irc.tudominio.com y se distribuyan automaticamente entre los tres. Idealmente, cada usuario deberia conectar al servidor mas cercano geograficamente. Si un servidor cae, los usuarios deberian ir a los que quedan.

El protocolo IRC no tiene mecanismo de load balancing. El cliente se conecta a la IP que le da el DNS y punto. No hay redirect, no hay fallback a nivel de protocolo (salvo que el cliente implemente Happy Eyeballs o tenga una lista de servidores). La distribucion tiene que ocurrir en la capa de DNS o de red.

DNS round-robin: lo basico

DNS round-robin es la tecnica mas simple: publicar multiples registros A (y AAAA) para el mismo dominio. Cada consulta DNS devuelve las IPs en orden diferente. Los clientes suelen conectar a la primera IP de la lista, asi que al rotar el orden, los clientes se distribuyen entre servidores.

# Registros DNS para round-robin:
irc.tudominio.com.  300  IN  A  1.2.3.4    ; servidor EU
irc.tudominio.com.  300  IN  A  5.6.7.8    ; servidor US
irc.tudominio.com.  300  IN  A  9.10.11.12 ; servidor AS

; TTL corto (300 = 5 minutos) para que los cambios
; se propaguen rapido si un servidor cae.

; IPv6:
irc.tudominio.com.  300  IN  AAAA  2001:db8::1
irc.tudominio.com.  300  IN  AAAA  2001:db8::2
irc.tudominio.com.  300  IN  AAAA  2001:db8::3

# Consulta 1: devuelve 1.2.3.4, 5.6.7.8, 9.10.11.12
# Consulta 2: devuelve 5.6.7.8, 9.10.11.12, 1.2.3.4
# Consulta 3: devuelve 9.10.11.12, 1.2.3.4, 5.6.7.8
# (El orden de rotacion depende del servidor DNS autoritativo)

La implementacion es trivial: anade registros A en tu zona DNS. No necesitas software especial ni hardware dedicado. Funciona con cualquier proveedor de DNS.

Consejo: Usa un TTL bajo (60-300 segundos) para los registros round-robin. Si un servidor cae y eliminas su registro, un TTL bajo significa que los clientes dejaran de intentar esa IP en minutos. Un TTL de 1 hora es inaceptable para failover.

Limitaciones del round-robin

DNS round-robin es simple pero tiene problemas reales:

  • No hay health checks: Si un servidor cae, el DNS sigue devolviendo su IP. Los clientes que reciben esa IP no pueden conectar. La unica solucion es eliminar manualmente el registro A del servidor caido. Esto puede tardar minutos u horas si no tienes automatizacion.
  • Distribucion desigual: Round-robin no garantiza distribucion uniforme. Los DNS resolvers cachean respuestas. Si el DNS de un ISP grande cachea una respuesta especifica, miles de usuarios de ese ISP iran al mismo servidor.
  • Sin afinidad geografica: Round-robin no sabe donde esta el usuario. Un usuario en Tokio puede recibir la IP del servidor en Madrid. La latencia es inaceptable pero el DNS no lo sabe.
  • Sticky sessions inexistentes: Si un usuario se desconecta y reconecta, puede ir a un servidor diferente. En IRC esto no es un problema grave (el bouncer mantiene la sesion), pero rompe cualquier logica que asuma persistencia de servidor.

Para una red IRC pequena o mediana, estas limitaciones son aceptables. Los clientes IRC suelen intentar todas las IPs de la lista si la primera falla. La distribucion desigual no importa mucho si tus servidores tienen capacidad de sobra. La latencia se compensa con la simplicidad del setup.

GeoDNS: distribucion por ubicacion

GeoDNS (tambien llamado DNS geografico) resuelve el problema de afinidad geografica. Usa la IP del DNS resolver del cliente para determinar su ubicacion aproximada y devuelve la IP del servidor mas cercano.

# Concepto de GeoDNS:
# Usuario en Francia -> DNS resuelve irc.tudominio.com -> IP del servidor EU
# Usuario en EEUU -> DNS resuelve irc.tudominio.com -> IP del servidor US
# Usuario en Japon -> DNS resuelve irc.tudominio.com -> IP del servidor AS

# Implementaciones:
# - Cloudflare DNS (gratis, con reglas de Traffic Steering)
# - AWS Route 53 (geolocation routing)
# - PowerDNS con modulo GeoIP (self-hosted)
# - BIND con views (self-hosted)

# Ejemplo con PowerDNS + GeoIP:
# pdns.conf:
launch=geoip
geoip-database-files=/usr/share/GeoIP/GeoLite2-Country.mmdb

# geo-zones.yaml:
domains:
- domain: tudominio.com
  records:
    irc.tudominio.com:
      - stype: A
        content:
          EU: 1.2.3.4
          NA: 5.6.7.8
          AS: 9.10.11.12
          default: 1.2.3.4

GeoDNS resuelve la afinidad geografica pero sigue sin tener health checks nativos. Si el servidor EU cae, GeoDNS sigue enviando usuarios europeos a una IP muerta. Necesitas combinar GeoDNS con un sistema de health checks que retire servidores caidos de la rotacion.

Servicios como Cloudflare, AWS Route 53, y DigitalOcean DNS ofrecen GeoDNS con health checks integrados. Configuras un health check HTTP o TCP en el puerto 6697, y si el check falla, el servidor se retira automaticamente. Esto es lo mas cercano a un load balancer real que puedes tener con DNS.

Anycast: la solucion de red

Anycast es una tecnica de red donde la misma IP esta anunciada desde multiples ubicaciones via BGP. Cuando un usuario se conecta a esa IP, el routing de Internet lo dirige automaticamente al servidor mas cercano topologicamente.

Anycast es lo que usan los grandes servicios de DNS (Cloudflare 1.1.1.1, Google 8.8.8.8) y CDNs. Para IRC, tiene una ventaja enorme: la distribucion es automatica, basada en routing real, y los health checks son inherentes — si un servidor deja de anunciar la ruta BGP, el trafico fluye a los demas.

El problema: anycast requiere control sobre el routing BGP. Necesitas tu propio bloque de IPs (al menos un /24 IPv4 o /48 IPv6), numeros AS, y acuerdos de peering con proveedores upstream en cada ubicacion. Esto esta fuera del alcance de la mayoria de redes IRC.

Las alternativas accesibles:

  • Cloudflare Spectrum: Proxy TCP con anycast. Tu servidor IRC esta detras de Cloudflare, que tiene anycast global. Los usuarios conectan a la IP anycast de Cloudflare y el trafico se reenvia al servidor IRC mas cercano.
  • Fly.io / Tailscale: Servicios que ofrecen anycast para aplicaciones TCP. Mas complejo de configurar pero funciona.

En la practica: que usan las grandes redes

Las redes IRC grandes usan combinaciones de todo lo anterior:

  • Libera.Chat: DNS round-robin para irc.libera.chat, con multiples servidores detras. Tambien ofrece servidores especificos por region (irc.eu.libera.chat, irc.us.libera.chat).
  • OFTC: Similar a Libera. Round-robin para el dominio principal, servidores especificos por sponsor.
  • EFnet: Cada servidor tiene su propio dominio. No hay round-robin centralizado. Los clientes eligen servidor manualmente o via lista.

La tendencia es hacia GeoDNS con health checks para el dominio principal, mas servidores especificos como fallback. Anycast es raro en IRC porque el coste de infraestructura no se justifica para el tamano de las redes actuales.

Configuracion paso a paso

# Paso 1: Configurar round-robin basico
# En tu panel DNS (ejemplo: Cloudflare, OVH, etc.):
# Anadir 3 registros A para irc.tudominio.com con TTL 300

# Paso 2: Verificar
dig irc.tudominio.com A +short
# Deberia devolver las 3 IPs (en orden variable)

# Paso 3: Probar conexion
for ip in 1.2.3.4 5.6.7.8 9.10.11.12; do
  echo "Testing $ip..."
  echo | openssl s_client -connect $ip:6697 2>/dev/null | head -5
done

# Paso 4: Health check basico (script cron)
#!/bin/bash
# check_irc.sh — ejecutar cada minuto via cron
SERVERS="1.2.3.4 5.6.7.8 9.10.11.12"
DOMAIN="irc.tudominio.com"

for ip in $SERVERS; do
  # Intentar handshake TCP en puerto 6697
  timeout 5 bash -c "echo | openssl s_client -connect $ip:6697" \
    &>/dev/null
  if [ $? -ne 0 ]; then
    echo "$(date): $ip DOWN — eliminar de DNS" >> /var/log/irc_health.log
    # Aqui: llamar API del DNS para eliminar el registro
    # Ejemplo con Cloudflare API:
    # curl -X DELETE "https://api.cloudflare.com/..."
  fi
done

# Paso 5: Subdominios regionales (complementario)
# eu.irc.tudominio.com -> solo IPs europeas
# us.irc.tudominio.com -> solo IPs americanas
# Ofrecer como alternativa en la pagina de conexion

Preguntas frecuentes

DNS round-robin es un load balancer?

No en el sentido estricto. Un load balancer real monitoriza la salud de los backends, distribuye trafico segun carga, y mantiene sesiones. DNS round-robin solo rota IPs — no sabe si un servidor esta vivo, saturado, o caido. Es una distribucion basica, no un balanceo inteligente.

Puedo usar HAProxy o nginx como load balancer para IRC?

Si, para las conexiones de clientes. Configuras HAProxy en modo TCP (layer 4) con health checks y backend servers. El problema: introduces un single point of failure (el proxy) y anade latencia. Para IRC, donde cada milisegundo de latencia se nota, la simplicidad del round-robin suele ser preferible.

El round-robin afecta a los links server-to-server?

No. Los links S2S se configuran con IPs especificas, no con el dominio round-robin. Los servidores se conectan directamente entre si via IPs fijas. El round-robin es solo para los clientes.