{ "meta": { "title": "Fail2Ban | ProxMenux Documentation", "description": "Instala Fail2Ban con tres jails afinados para Proxmox (SSH agresivo, Proxmox UI 8006, ProxMenux Monitor 8008). Incluye el arreglo de journald MaxLevelStore, servicios de log propios para fiabilidad, backend nftables/iptables autodetectado y hardening de SSH MaxAuthTries.", "ogTitle": "Fail2Ban | ProxMenux Documentation", "ogDescription": "Protección contra fuerza bruta para SSH y las UIs web de Proxmox, con arreglos específicos de journald y backend para Proxmox." }, "header": { "title": "Fail2Ban", "description": "Instala Fail2Ban con una configuración específica para Proxmox: tres jails (SSH agresivo, Proxmox UI en puerto 8006, ProxMenux Monitor en puerto 8008 + proxy inverso), un arreglo del nivel de log de journald para que los eventos de autenticación SSH se almacenen de verdad, dos servicios logger journal-a-archivo que rodean un problema conocido del backend systemd de Fail2Ban, backend de firewall autodetectado y hardening de SSH MaxAuthTries.", "section": "Seguridad" }, "intro": { "title": "Qué hace", "body": "Instala Fail2Ban desde los repos de Debian y escribe una configuración completa afinada para Proxmox que protege tres superficies de ataque (SSH, Proxmox UI, ProxMenux Monitor) por defecto. Detecta una instalación existente y ofrece un menú de gestión (reinstalar / eliminar) en lugar de volver a ejecutar el instalador." }, "firstLaunch": { "heading": "Diálogo de primer lanzamiento", "body": "En un host sin Fail2Ban, el script muestra un diálogo de confirmación que resume todo lo que va a instalar y configurar. Cancelar sale sin cambios; confirmar arranca el flujo de instalación.", "imageAlt": "Diálogo de confirmación de instalación de Fail2Ban listando los tres jails, el arreglo de journald y el hardening de SSH" }, "jails": { "heading": "Los tres jails", "headerJail": "Jail", "headerProtects": "Protege", "headerRetries": "Reintentos / Ventana", "headerBan": "Tiempo de ban", "rows": [ { "jail": "[sshd]", "protects": "SSH (modo agresivo — cubre ddos, mode, normal)", "retries": "2 / 60 min", "ban": "9 horas" }, { "jail": "[proxmox]", "protects": "UI web de Proxmox (puerto 8006)", "retries": "3 / 10 min", "ban": "1 hora" }, { "jail": "[proxmenux]", "protects": "ProxMenux Monitor (puerto 8008 + proxy inverso http/https)", "retries": "3 / 10 min", "ban": "1 hora" } ], "outro": "Valores por defecto globales de jail.local: ignoreip = 127.0.0.1/8 ::1, ignoreself = true, bantime = 86400 (fallback de 24h para jails que no lo sobrescriben), maxretry = 2, findtime = 1800." }, "journald": { "heading": "Por qué importa el arreglo de journald", "intro": "Proxmox entrega /etc/systemd/journald.conf con MaxLevelStore=warning. journald descarta cada mensaje de log por debajo de warning antes de almacenarlo. SSH y PAM emiten fallos de autenticación a niveles info / notice, así que:", "diagram": { "sshLabel": "SSH / PAM", "sshDetail": "fallo de autenticación\n(nivel info / notice)", "journaldLabel": "journald", "journaldDetail": "MaxLevelStore=warning\n→ evento descartado en silencio", "fail2banLabel": "Fail2Ban", "fail2banDetail": "no ve nada\n→ nunca banea nada", "arrowLabel": "Proxmox por defecto" }, "afterDiagram": "El instalador detecta esto y escribe un drop-in en /etc/systemd/journald.conf.d/proxmenux-loglevel.conf subiendo MaxLevelStore y MaxLevelSyslog a info:", "code": "[Journal]\nMaxLevelStore=info\nMaxLevelSyslog=info", "outro": "Después reinicia systemd-journald. El drop-in se elimina al desinstalar, restaurando el valor por defecto original de Proxmox." }, "loggers": { "heading": "Por qué dos servicios logger propios", "intro1": "Fail2Ban puede leer directamente del journal de systemd (backend = systemd), pero en Proxmox este backend tiene problemas conocidos de fiabilidad con los procesos worker de pvedaemon (los eventos de autenticación aparecen en el journal pero Fail2Ban no siempre los recoge) e intermitentemente con sshd.", "intro2": "La solución alternativa: ProxMenux crea dos pequeños servicios systemd que hacen journalctl -f de las unidades relevantes y añaden cada línea a un archivo. Fail2Ban entonces lee esos archivos con el sólido como una roca backend = auto (modo archivo):", "headerService": "Servicio", "headerSource": "Unidad origen", "headerOutput": "Archivo de salida", "rows": [ { "service": "proxmox-auth-logger.service", "source": "pvedaemon.service", "output": "/var/log/proxmox-auth.log" }, { "service": "ssh-auth-logger.service", "source": "ssh.service", "output": "/var/log/ssh-auth.log" } ], "outro": "Ambos servicios se declaran PartOf=fail2ban.service para que se reinicien con Fail2Ban y se paren con él. Modo 640 propiedad de root:adm en los archivos de log. El tercer log usado por el jail [proxmenux] (/var/log/proxmenux-auth.log) lo escribe directamente la app Flask del Monitor de ProxMenux — no hace falta servicio logger para ese." }, "backend": { "heading": "Autodetección del backend de firewall", "intro": "El instalador sondea el host: si nft list ruleset funciona, elige nftables como acción de ban. Si no, recae en iptables-multiport / iptables-allports. La elección se escribe en jail.local:", "code": "# nftables host\nbanaction = nftables\nbanaction_allports = nftables[type=allports]\n\n# iptables host (fallback)\nbanaction = iptables-multiport\nbanaction_allports = iptables-allports" }, "hardening": { "heading": "Hardening de SSH: MaxAuthTries", "intro": "El control de Lynis SSH-7408 recomienda MaxAuthTries 3 en sshd_config. Con el maxretry = 2 de Fail2Ban en el jail SSH, un cliente malicioso nunca llega a tres intentos de todas formas — pero el ajuste explícito satisface la auditoría y añade defensa en profundidad (p. ej. si Fail2Ban está parado por mantenimiento).", "installerIntro": "El instalador:", "items": [ "Lee el valor actual de MaxAuthTries (o por defecto 6 si está ausente).", "Lo guarda en /usr/local/share/proxmenux/sshd_maxauthtries_backup.", "Edita sshd_config en sitio — reemplaza la línea existente, descomenta la línea comentada o la añade.", "Recarga sshd (reload, no restart, para mantener vivas las sesiones existentes)." ], "outro": "Al desinstalar, el valor original guardado se restaura y se recarga sshd otra vez." }, "manage": { "heading": "Gestionar una instalación existente", "intro": "Si Fail2Ban ya está instalado cuando abres el menú, el script lo detecta y muestra un menú de gestión en lugar de volver a ejecutar el instalador:", "headerAction": "Acción", "headerWhat": "Qué hace", "rows": [ { "action": "Reinstalar", "what": "Vuelve a ejecutar el instalador completo — reescribe todos los jails con los valores por defecto actuales de ProxMenux. Úsalo cuando una actualización de ProxMenux suba los valores recomendados." }, { "action": "Eliminar", "what": "Para fail2ban y los dos servicios logger, purga el paquete apt, elimina todos los archivos de jail / filtro, borra el drop-in de journald (restaurando el valor por defecto de Proxmox) y restaura el MaxAuthTries SSH original." } ] }, "verify": { "heading": "Verifica que funciona", "intro": "Tras la instalación, comandos útiles desde el host:", "code": "# Service status and version\nsystemctl status fail2ban\nfail2ban-client --version\n\n# All active jails\nfail2ban-client status\n\n# Detail on one jail\nfail2ban-client status sshd\nfail2ban-client status proxmox\nfail2ban-client status proxmenux\n\n# Currently banned IPs in a jail\nfail2ban-client status sshd | grep \"Banned IP\"\n\n# Manually unban an IP (use this if you ban yourself)\nfail2ban-client unban 192.0.2.10\n\n# Tail the auth logs Fail2Ban watches\ntail -f /var/log/ssh-auth.log\ntail -f /var/log/proxmox-auth.log\ntail -f /var/log/fail2ban.log" }, "troubleshoot": { "heading": "Solución de problemas", "neverBansTitle": "Fail2Ban corre pero nunca banea nada", "neverBansBody": "Comprueba que los archivos de log de autenticación reciben entradas de verdad: tail -f /var/log/ssh-auth.log y prueba un intento SSH con contraseña incorrecta desde otra máquina. Si el log se queda vacío, el servicio logger no está corriendo: systemctl status ssh-auth-logger.service. Si está activo pero el log está vacío, comprueba que el drop-in de journald surtió efecto: journalctl --dump-catalog | head — eventos a nivel info deberían ser visibles.", "monitorEmptyTitle": "El jail del Monitor de ProxMenux no tiene entradas ni siquiera tras logins fallidos", "monitorEmptyBody": "El jail [proxmenux] lee /var/log/proxmenux-auth.log, que lo escribe la app Flask del Monitor de ProxMenux — no un logger de journald. Si no usas el Monitor, el archivo se queda vacío y el jail nunca dispara. Eso es lo esperado; la configuración del jail es inocua. Si sí usas el Monitor y el log está vacío, comprueba la configuración de logging de Flask.", "selfBanTitle": "Me he baneado a mí mismo", "selfBanIntro": "Desde una consola / IPMI / iKVM (u otra IP whitelisted):", "selfBanCode": "fail2ban-client unban '<'YOUR_IP'>'\n\n# To prevent it next time, edit /etc/fail2ban/jail.local and add your IP:\nignoreip = 127.0.0.1/8 ::1 192.168.1.0/24 203.0.113.42\n\n# Then reload\nfail2ban-client reload", "aptFailTitle": "apt-get falla: ''Unable to locate package fail2ban''", "aptFailBody": "Al host le faltan los repos de Debian (común en instalaciones de Proxmox a pelo). El instalador detecta esto y escribe /etc/apt/sources.list.d/debian.sources con el codename correcto (bookworm / trixie) antes de reintentarlo. Si sigue fallando, comprueba /etc/os-release en busca de VERSION_CODENAME y confirma que la URL del repo es alcanzable.", "lockoutTitle": "SSH me bloquea el acceso tras la instalación", "lockoutBody": "El instalador establece MaxAuthTries=3. Si tu gestor de contraseñas / agente reintenta múltiples claves, puedes superar ese límite en un único intento de conexión. Limita las claves ofrecidas: ssh -o IdentitiesOnly=yes -i ~/.ssh/specific_key user@host. O sube temporalmente MaxAuthTries en sshd_config mientras depuras." }, "files": { "heading": "Archivos escritos", "code": "/etc/fail2ban/jail.local # global defaults + [sshd]\n/etc/fail2ban/jail.d/proxmox.conf # [proxmox]\n/etc/fail2ban/jail.d/proxmenux.conf # [proxmenux]\n/etc/fail2ban/filter.d/proxmox.conf # auth-failure regex for pvedaemon\n/etc/fail2ban/filter.d/proxmenux.conf # auth-failure regex for Monitor\n/etc/systemd/system/proxmox-auth-logger.service # journal → file (pvedaemon)\n/etc/systemd/system/ssh-auth-logger.service # journal → file (sshd)\n/etc/systemd/journald.conf.d/proxmenux-loglevel.conf # MaxLevelStore=info\n/etc/ssh/sshd_config # MaxAuthTries=3 (in-place edit)\n/var/log/proxmox-auth.log # written by logger service\n/var/log/ssh-auth.log # written by logger service\n/var/log/proxmenux-auth.log # written by Monitor Flask app\n/usr/local/share/proxmenux/sshd_maxauthtries_backup # for restore on uninstall" }, "related": { "heading": "Relacionado", "monitorLabel": "ProxMenux Monitor → pestaña de Seguridad", "monitorTail": " — misma instalación accesible desde el panel, más estado en vivo de los jails, IPs baneadas y ajuste por jail de reintentos / tiempo de ban desde el navegador.", "lynisLabel": "Lynis", "lynisTail": " — ejecuta una auditoría de seguridad antes/después para confirmar que el control SSH-7408 se satisface.", "securityLabel": "Resumen de Seguridad", "securityTail": " — volver al resumen de la sección." } }