Conexiones fantasma en icecast diagnóstico y filtrado

Conexiones Fantasma en Icecast: diagnóstico y filtrado

En este artículo vemos cómo aparecen las Conexiones Fantasma en Icecast y qué hacemos para eliminarlas.
El problema suele surgir de clientes que se quedan colgados sin reproducir audio, pero que siguen ocupando un slot en el servidor.

Diagnóstico de Conexiones Fantasma en Icecast

Si no resolvemos este caso, el número máximo de oyentes se llena con conexiones muertas y la emisión se corta para los usuarios reales.
Los síntomas son fáciles de detectar: en el panel de administración vemos cientos de “listeners” con 0 kbps y “idle” por largos periodos.
Además, el registro de Icecast muestra “client timeout” sin causa aparente.

Qué necesitas antes de empezar

  • Acceso SSH a la VM 111 donde corre Icecast.
  • Credenciales de administrador de Icecast (usuario y contraseña).
  • Paquetes net-tools y jq instalados.
  • iptables o nftables configurado.
  • Un editor de texto como nano o vim.

Paso a paso para detectar y filtrar las Conexiones Fantasma en Icecast

Primero, verificamos cuántas conexiones están activas usando la API de estadísticas de Icecast.
El endpoint devuelve JSON que podemos procesar con jq:

curl -s http://localhost:8000/admin/stats.xml | \
    grep -oP '<connection>[^<]+' | wc -l

Este comando nos da el total de slots ocupados.
Para ver sólo los que no envían datos, usamos netstat y filtramos por el puerto de Icecast (8000).

netstat -anp | grep ':8000' | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr

Los clientes con 0 kbps aparecen como “ESTABLISHED” pero sin tráfico.
Para confirmar, extraemos los IDs de los listeners desde la API y los cruzamos con la lista anterior.

LISTENERS=$(curl -s http://localhost:8000/admin/listclients.xsl | \
    grep -oP 'clientid=\K[0-9]+' )
for ID in $LISTENERS; do
    IP=$(curl -s "http://localhost:8000/admin/listclients.xsl?clientid=$ID" | grep -oP 'IP: \K[0-9.]+')
    echo "$ID $IP"
done

Una vez identificados los sospechosos, los bloqueamos con iptables. Creamos una cadena dedicada para “ghost‑clients” y añadimos una regla que cierre la conexión después de 30 segundos sin tráfico.

iptables -N ghost-clients
iptables -A INPUT -p tcp --dport 8000 -m state --state ESTABLISHED -j ghost-clients
iptables -A ghost-clients -m conntrack --ctstate ESTABLISHED -m recent --name icecast-ghost --set
iptables -A ghost-clients -m recent --name icecast-ghost --update --seconds 30 --hitcount 1 -j DROP

Para que la regla sea persistente, guardamos la configuración en /etc/iptables/rules.v4 y recargamos.

iptables-save > /etc/iptables/rules.v4
systemctl restart netfilter-persistent

Otra opción es usar fail2ban con una cárcel personalizada que examine el log de Icecast y bloquee IPs que generen “client timeout” más de tres veces en 5 min.

[icecast-ghost]
enabled = true
filter = icecast
logpath = /var/log/icecast/access.log
maxretry = 3
bantime = 3600

El filtro icecast.conf contiene la expresión regular que capta la línea “client timeout”.

failregex = client timeout from <HOST>

Con estas reglas, cualquier cliente que deje de enviar datos será expulsado automáticamente y el slot quedará libre para un oyente activo.

Errores que nos costaron tiempo

1. Usar iptables -A INPUT sin una cadena separada.
La regla bloqueó todo el tráfico de Icecast, no solo los fantasma.
Solucionamos creando la cadena “ghost-clients” y enlazándola después de la regla de estado ESTABLISHED.

2. Aplicar netstat sin filtrar por protocolo.
Incluimos también conexiones TCP a otros puertos y confundimos el diagnóstico.
Añadimos “–tcp” al comando y limitamos a “:8000”.

3. Olvidar recargar fail2ban después de crear la cárcel.
El demonio seguía leyendo la configuración antigua y los nuevos baneos no se aplicaban.
Ejecutamos systemctl restart fail2ban y verificamos con fail2ban-client status icecast-ghost.

Cómo saber que funciona

Una vez aplicadas las reglas, volvemos a ejecutar el conteo de conexiones con el primer curl.
El número de slots ocupa ahora solo a oyentes que envían datos.
En el log de Icecast veremos entradas “connection closed (ghost client)” y en iptables -L -v -n aparecerá tráfico contabilizado en la cadena “ghost-clients”.

Qué sigue

El siguiente paso es automatizar la monitorización con un pequeño script Python que envíe una alerta a Telegram cuando el porcentaje de conexiones fantasma supere el 10 % de la capacidad total.
Así evitamos sorpresas nocturnas sin intervención manual.

Detectar y filtrar Conexiones Fantasma en Icecast nos permite mantener la capacidad del servidor y ofrecer una transmisión estable a nuestros oyentes.

Compartir

“Post relacionados”

🤖
Asistente de Fabio Martínez
En línea
¡Hola! 👋 Soy el asistente virtual de
Fabio Martínez
Técnico de Radio · Dev Web · Servidores

¿Cómo te llamás?