Solución al error “ldap: hit reconnection limit” en FreeRADIUS con Active Directory

¿FreeRADIUS deja de autenticar a tus usuarios contra Active Directory y el registro se llena con “ldap: hit reconnection limit”? Este artículo explica en detalle por qué sucede, cómo diagnosticar cada componente de la ruta (servidor, red, módulo LDAP y DC) y qué ajustes aplicar para restaurar la estabilidad sin sacrificar rendimiento ni seguridad.

Índice

Descripción del problema

El mensaje aparece cuando FreeRADIUS agota el número máximo de reintentos configurados para restablecer una sesión LDAP. Suele mostrarse en modo -X justo después de que una autenticación falla:

(0) mschap: ERROR: ldap: hit reconnection limit
(0) ldap: Failed performing search: Can't contact LDAP server

En la mayoría de los casos, el bind de prueba funciona, pero el tráfico real colapsa el pool de conexiones provocando un ciclo de reconexión infinito. Los síntomas típicos son:

  • Retardo de varios segundos en cada autenticación MS‑CHAPv2 o PEAP.
  • Paquetes Access‑Reject intermitentes.
  • Eventos 4771/2887 en el visor de eventos del DC.

Cómo opera FreeRADIUS con Active Directory

Comprender la secuencia ayuda a localizar el cuello de botella:

  1. Inicio de sesión del usuario. Un cliente RADIUS (AP, VPN o switch) envía un Access‑Request.
  2. Mapeo a DN. El módulo ldap transforma el nombre de usuario (NT‑style o UPN) en un DN completo.
  3. Búsqueda LDAP. Se usa la cuenta de servicio (bind DN) para ejecutar la consulta.
  4. Verificación de contraseña. FreeRADIUS llama al helper ntlm_auth (NTLM) o compara sAMAccountName/userAccountControl.
  5. Cierre o reciclado de la conexión. Según la política de pooling, la conexión vuelve al pool o se destruye.

Si cualquiera de estos pasos excede su timeout, FreeRADIUS desecha la sesión, abre otra y consume un intento del contador de reconexiones. Al llegar a retrycount, lanza el error.

Causas más comunes

  • Latencia inusual (≥ 200 ms) o pérdida de paquetes entre FreeRADIUS y el DC.
  • CPU del DC al 95 % o colas de NTDS saturadas.
  • Certificado expirado cuando se usa LDAPS/STARTTLS.
  • Cuenta de servicio forzada a cambiar contraseña o bloqueada por políticas de Lockout.
  • Pool de conexiones demasiado pequeño para la ráfaga de peticiones.
  • Firewall que cierra sesiones inactivas antes de idle_timeout.

Matriz de diagnóstico rápido

PasoQué revisar / hacerPor qué ayuda
Disponibilidad del servidor LDAP/ADVerifica que los DC estén activos y sin sobrecarga.
Usa ldapsearch o Test‑NetConnection para medir latencia y descartar cortes.
El error se dispara cuando FreeRADIUS no recibe respuesta antes de agotar reintentos.
Límites de conexión en ADComprueba en el registro HKLM\System\CurrentControlSet\Services\NTDS\Parameters valores como MaxConnections y MaxConnIdleTime. Ajusta o distribuye carga.Evita que AD rechace nuevos sockets LDAP.
Pool y timeouts en el módulo LDAPEn mods‑available/ldap ajusta:
timeout = 10
retrycount = 5
retrydelay = 30
pool { start = 5  max = 32  spare = 3  idle_timeout = 60 }
Más intentos + pool amplio = menos “reconnection limit”.
Credenciales y DN de enlaceAsegura que la cuenta de servicio no esté bloqueada ni obligada a cambiar contraseña.Cuentas bloqueadas provocan bucles de reconexión.
Puertos y cifradoUsa 389 + STARTTLS o 636 (LDAPS). Verifica certificados y la directiva “Domain controller: LDAP server signing requirements”.Fallos TLS generan reconexiones masivas.
Firewall y dispositivos intermediosConfirma que no haya NAT o filtros que cierren sesiones LDAP prematuramente.Sesiones interrumpidas crean reintentos excesivos.
Registros detalladosLanza freeradius ‑X o habilita debug_level = 3 para ver el ciclo completo.Permite aislar el componente exacto que falla.
Alta concurrencia (opcional)Define varios DC en server = "dc‑1 ad.example.com dc‑2 ad.example.com" o usa un equilibrador LDAP.Reparte sesiones y evita sobrepasar límites por DC.

Análisis detallado paso a paso

Medición de latencia y disponibilidad

Ejecuta desde el host FreeRADIUS:

ldapsearch -x -H ldap://dc1.ad.ejemplo.local -b "DC=ejemplo,DC=local" -s base "objectClass=*"

El tiempo total debe ser < 0,5 s. Si varía o supera el segundo, investiga la red o equilibra peticiones hacia otro DC. PowerShell ofrece Test‑NetConnection -ComputerName dc1 -Port 389 para Windows Server.

Ajuste de registros NTDS

Si los eventos 2887 indican muchos binds anónimos o si MaxConnections está en 5000 y llegas al límite, aumenta el valor en pasos de 1000 y reinicia el servicio NTDS en horario de bajo uso. Documenta el cambio en el libro de operaciones.

Optimización del pool en mods‑available/ldap

Un pool pequeño causa thrashing en entornos con ráfagas, por ejemplo cuando decenas de AP envían consultas de roaming. Un ejemplo robusto:

ldap {
  server = "dc1.ad.ejemplo.local"
  identity = "CN=svc_radius,OU=Serv,DC=ejemplo,DC=local"
  password = ""
  base_dn = "DC=ejemplo,DC=local"
  timeout = 5
  timelimit = 5
  net_timeout = 3
  use_referral = yes
  retrycount = 5
  retrydelay = 20
  pool {
     start = 10
     min = 10
     max = 50
     spare = 5
     uses = 0
     idle_timeout = 120
  }
}

Si los AP envían picos de 150 peticiones por segundo, ajusta max = 100 y aumenta idle_timeout para evitar que el firewall cierre sockets inactivos demasiado pronto.

Supervisión en producción

El comando radmin -e "show stats ldap" devuelve métricas en vivo:

ldap {
  connections = 35
  pending = 1
  free = 7
  used = 27
  sockets_closed = 0
  sockets_error = 3
}

Integra la salida con Prometheus mediante el exporter de texto. Define alertas si used > 0.8 * max durante 5 minutos o si sockets_error ≠ 0. Esto permite reaccionar antes de que los usuarios noten la interrupción.

Solución de problemas de TLS

En entornos que exigen LDAPS, tres errores provocan el reconnection limit:

  • Certificado del DC expirado. Comprueba con openssl s_client -connect dc1:636 -showcerts.
  • Cadena de confianza rota. Instala el certificado raíz en /etc/ssl/certs y ejecuta update‑ca‑certificates.
  • Firma LDAP obligatoria. Si “Domain controller: LDAP server signing requirements” está en Require signing, agrega require_tls = yes en la sección LDAP o la negociación fallará.

Diseño para alta disponibilidad

Para más de 1000 autenticaciones por minuto desde decenas de S‑AP, aplica:

  1. Pool distribuido. Usa 3 DC locales y dos remotos como respaldo.
  2. Balanceo TCP. Si usas F5 o HAProxy con health‑checks LDAP, mantienes una sola IP y descargas la lógica de failover.
  3. Separación de motores. Corre FreeRADIUS en un clúster activo‑activo y usa base de datos compartida (Redis) para el módulo rlm_cache.

Procedimiento de validación

  1. Reinicia FreeRADIUS y limpia los contadores de fallos: radmin -e "stats reset".
  2. Inicia un script de carga con radclient enviando 500 Access‑Requests por minuto durante 10 min.
  3. Supervisa con htop o perf la CPU del DC.
  4. Comprueba que hit reconnection limit no aparece y que el pool mantiene conexiones usadas < 80 %.

Preguntas frecuentes

¿Puedo desactivar el reconnection limit? No es recomendable; actúa como guardarraíl para evitar bucles infinitos y consumo de CPU. ¿FreeRADIUS 4 evita el problema? Las versiones › 3.2 ya introducen caché LDAP y mejoras de pool; la rama 4 añade mejores métricas pero sigue requiriendo buen dimensionamiento. ¿El parámetro idle_timeout afecta a LDAPS? Sí, porque el socket queda inactivo tras la operación bind; si tu firewall corta TLS tras 60 s, pon idle_timeout = 50.

Conclusión

El error “ldap: hit reconnection limit” es una alarma de agotamiento de intentos, no la causa raíz. Abordarlo exige una visión de toda la cadena: rendimiento de la red, capacidad del controlador de dominio, afinado del pool LDAP y verificación de credenciales. Con los ajustes y mejores prácticas anteriores, FreeRADIUS podrá atender cargas elevadas sin perder sesiones y mantendrá la autenticación MS‑CHAPv2/PEAP completamente estable.

Pista rápida: tras cada cambio en la configuración, reinicia FreeRADIUS (systemctl restart freeradius) y valida el pool con radmin para confirmar que los nuevos valores han sido aplicados.

Índice