Filtro de Fail2ban para OpenVPN Access Server: real_ip y cárceles
El Access Server escribe su propio formato de registro, así que los filtros estándar no encuentran nada. Ancla en real_ip, separa las cárceles por superficie y comprueba que la dirección no sea un proxy.
Copiaste una cárcel de OpenVPN de una publicación de la comunidad, reiniciaste fail2ban y ninguna dirección se bloquea nunca. La causa casi siempre es el formato del registro: el Access Server no escribe las líneas de fallo de autenticación que espera un filtro estándar. Antes de tocar el filtro, confirma que los registros existen siquiera, porque un patrón no puede coincidir con lo que el servicio nunca registró.
Este es el runbook que sigo en un host con Access Server: confirmar la forma del registro, escribir una expresión anclada, probarla contra el registro real, después separar las cárceles por la superficie atacada y verificar que el bloqueo llega al cortafuegos.
Confirma que el registro de fallo existe
El Access Server escribe sus propias líneas estructuradas en /var/log/openvpnas.log, y la dirección del cliente vive en un campo real_ip entre comillas y no al principio de una línea de syslog. Busca un inicio de sesión fallido que sepas que ocurrió antes de escribir cualquier patrón:
grep -i 'LOG ERR' /var/log/openvpnas.log | tail -20Si no aparece nada, el nivel de registro es el siguiente sospechoso. El Access Server tiene un interruptor de depuración de la base de datos de registro en /usr/local/openvpn_as/etc/as.conf (DEBUG_LOGDB=1), y el servicio debe reiniciarse después de cambiarlo. Trata ese interruptor como un ajuste de diagnóstico que se vuelve a bajar cuando tengas tu patrón, no como una configuración permanente.
Mientras estás en el archivo, fíjate qué superficies escriben en él. Los fallos del portal del cliente, de la interfaz de administración y de la autenticación del túnel acaban en el mismo archivo con marcadores distintos, y ese detalle decide más tarde el diseño de las cárceles.
Ancla un filtro en real_ip
Mantén la expresión estrecha. Un filtro que reclame cualquier línea con una dirección IP bloqueará a gente por desconexiones normales, y en un servidor ocupado el único síntoma es que los usuarios se quejan de haber quedado bloqueados por cerrar un portátil. Reclama el registro de error y captura la dirección entre comillas:
# /etc/fail2ban/filter.d/openvpnaccess.local
[Definition]
failregex = ^ .*LOG ERR.*"real_ip": "<HOST>".*
ignoreregex =El espacio inicial no es cosmético. El Access Server sangra sus registros, y anclarse en él evita que el patrón reclame también líneas que servicios no relacionados escriben en el mismo archivo. Si tus registros llevan en cambio una marca de tiempo al principio, haz coincidir ese prefijo, pero ancla en algo que esté realmente presente en cada registro que pretendas reclamar.
Cuando necesites precisión por superficie, estrecha aún más exigiendo el marcador de superficie (WEB_CLIENT, WEB_ADMIN o VPN) en la misma línea. Un filtro con tres patrones es más fácil de auditar que tres filtros que se diferencian en una palabra.
Prueba la expresión antes de habilitar una cárcel
Nunca habilites un filtro que no hayas ejecutado contra el registro de producción. La prueba documentada pasa el filtro dos veces, una para cargarlo y otra para aplicarlo, y el informe de líneas no detectadas es la parte que merece leerse:
fail2ban-regex --print-all-missed /var/log/openvpnas.log \
/etc/fail2ban/filter.d/openvpnaccess.local \
/etc/fail2ban/filter.d/openvpnaccess.local > missed.txtCompara el número de coincidencias con los fallos que verificaste en el primer paso. Cero coincidencias significa que el patrón está mal; las coincidencias en líneas que no son fallos de autenticación significan que es demasiado amplio. Lee missed.txt hasta que puedas explicar cada línea que decidiste no reclamar.
Haz esta prueba sobre una copia si el registro es grande, y repítela después de cualquier actualización del Access Server. El formato del registro es la interfaz contra la que coincides, y no es una API estable.
Separa las cárceles por superficie, no por demonio
Un Access Server presenta varias superficies de autenticación: interfaces web de cliente y de administración en 943/tcp, y el túnel en 1194/udp o 443/tcp en la mayoría de despliegues. Una sola cárcel que las cubra todas permite que los intentos de adivinar en el túnel bloqueen una dirección que también es tu vía de administración, y oculta qué superficie está realmente bajo ataque. Da a cada superficie su propia cárcel con su propio puerto y umbrales:
# /etc/fail2ban/jail.d/openvpnaccess.local
[openvpnas-web-client]
enabled = true
port = 943
protocol = tcp
filter = openvpnaccess
logpath = /var/log/openvpnas.log
maxretry = 3
findtime = 10m
bantime = 1h
[openvpnas-tunnel]
enabled = true
port = 443
protocol = udp
filter = openvpnaccess
logpath = /var/log/openvpnas.log
maxretry = 5
findtime = 10m
bantime = 1hEmpieza con contadores pequeños y un bloqueo corto, y súbelos cuando hayas observado una semana de tráfico real. Un umbral generoso en una dirección de oficina compartida castiga a todos los usuarios detrás de un NAT, y un bloqueo agresivo en la superficie del túnel desconecta a clientes legítimos cuyas credenciales guardadas caducaron durante la noche.
Verifica el bloqueo, el backend y los daños colaterales
Tras un reinicio, la salida de estado es la confirmación más rápida de que la cárcel existe y está contando:
fail2ban-client status
fail2ban-client status openvpnas-tunnelLuego confirma que el bloqueo llega al cortafuegos que realmente ejecutas, porque una cárcel configurada para un backend que nadie aplica no protege nada. Con la acción de iptables las direcciones aparecen en una cadena con el nombre de la cárcel (f2b-openvpnas-tunnel); con la acción de nftables caen en un conjunto en la tabla propia de fail2ban. Comprueba la que usa tu host en lugar de suponerlo.
Dos comprobaciones colaterales importan más que el propio bloqueo. Primero, verifica que real_ip es la dirección del cliente y no un balanceador de carga o un proxy inverso; detrás de un proxy cada bloqueo cae sobre el proxy y se lleva todo el servicio por delante. Segundo, escribe el procedimiento de desbloqueo, porque la dirección que cruza el umbral a las 02:00 suele pertenecer al ingeniero de guardia: fail2ban-client set openvpnas-tunnel unbanip 203.0.113.24.
Ten presente el límite mientras ajustas. Fail2ban es un limitador de velocidad en una superficie de autenticación, no una capa de control de acceso. No sustituye a MFA, a las restricciones por cuenta ni a mantener la interfaz de administración fuera de internet, y el Access Server tiene sus propios ajustes de autoban que merece la pena revisar antes de apilar dos limitadores de velocidad en el mismo puerto.