Guía gratuita de SSem SecuMon

Desde un solo servidor personal · Actualizada en octubre de 2026

PróximamenteLa distribución del instalador está en preparación.

Esta guía publica primero los requisitos, los pasos de instalación y lo que conviene saber para la operación. Cuando empiece la distribución, indicaremos aquí la dirección de descarga.

1. Requisitos

ElementoCondiciones
Servidores a protegerLinux (systemd) + fail2ban · nftables · sqlite3. amd64 o arm64. Probado en Ubuntu 22.04 · CentOS 8.
Servidor de consolaUno. JDK 21 · Tomcat 11 · PostgreSQL 17. Lo más sencillo es usar Docker.
RedLos servidores deben poder conectarse por HTTPS a la dirección de la consola. No se necesitan puertos de entrada en los servidores. Se recomienda colocar la consola detrás de una VPN o de una red interna.
RelojSincronice con NTP el reloj de todos los servidores y de la consola. Si la hora de la firma difiere en más de 60 segundos, la solicitud se rechaza.
CertificadoCertificado HTTPS para la consola (p. ej., Let's Encrypt). La cookie de sesión solo se envía por HTTPS, así que no podrá iniciar sesión por HTTP sin cifrar.

Instale primero los paquetes en cada servidor que vaya a proteger.

# Debian · Ubuntu
apt-get update && apt-get install -y fail2ban nftables sqlite3
# RHEL · Rocky · CentOS
dnf install -y epel-release && dnf install -y fail2ban nftables sqlite
systemctl enable --now fail2ban

2. Activar el ban exponencial de fail2ban

Configure fail2ban para que una IP que vuelve quede bloqueada cada vez más tiempo. SecuMon usa estos multiplicadores para calcular «en qué nivel está» y «cuánto durará el próximo bloqueo».

# /etc/fail2ban/jail.local
[DEFAULT]
bantime  = 1h
findtime = 10m
maxretry = 5
bantime.increment   = true
bantime.multipliers = 1 2 4 8 16 32 64 168
bantime.maxtime     = 168h
ignoreip = 127.0.0.1/8 ::1 <su rango VPN>

# /etc/fail2ban/fail2ban.local — conserva el historial de reincidencia 60 días (con el valor por defecto, 1 día, al día siguiente cuenta como primera vez)
[DEFINITION]
dbpurgeage = 60d

Con esta configuración, la duración de los bans es la siguiente. fail2ban añade un pequeño tiempo aleatorio, así que los valores reales varían ligeramente.

Bans acumulados12345678 o más
Duración del ban1 h2 h4 h8 h16 h32 h64 h7 días

Añada sin falta su ruta de acceso (rango VPN, etc.) a ignoreip. Así evita que su propio servidor le banee por equivocarse unas cuantas veces de contraseña.

3. Instalar la consola

3-1. Archivos secretos

Los valores secretos no se escriben en el código ni en variables de entorno: se guardan como archivos en una carpeta. El contenedor de la consola monta esta carpeta en /App/secrets en modo de solo lectura.

mkdir -p /srv/secumon/secrets/tls && chmod 700 /srv/secumon
cd /srv/secumon/secrets
openssl rand -hex 24 > db_password
openssl rand -base64 18 > admin_password      # contraseña del primer inicio de sesión (usuario admin)
openssl genpkey -algorithm ed25519 -out console_ed25519.key
openssl pkey -in console_ed25519.key -pubout -out console_ed25519.key.pub
# archivos en 644 para que los lea la cuenta del contenedor — la protección la da la carpeta superior 700
chmod 644 db_password admin_password console_ed25519.key console_ed25519.key.pub
ArchivoUsoSi falta
db_passwordConexión a la base de datosLa consola no arranca
admin_passwordContraseña de la primera cuenta de administrador, adminNo se crea la cuenta y no podrá iniciar sesión
console_ed25519.key · .pubFirma de comandosSolo podrá ver, no ejecutar
abuseipdb.keyClave de API de AbuseIPDB (opcional)No podrá reportar ni consultar la reputación
telegram.envNotificaciones de Telegram (opcional)No se envían notificaciones
tls/cert.pem · chain.pem · privkey.pemCertificado HTTPS de la consolaNo se abre por HTTPS

Con console_ed25519.key se pueden firmar comandos válidos para todos los servidores. No guarde este archivo en repositorios ni unidades compartidas; consérvelo aparte.

3-2. Base de datos

El puerto de la base de datos no se expone al exterior. La consola se conecta por nombre de contenedor dentro de la misma red de Docker.

docker network create secumon-net
docker run -d --name secumon-db --network secumon-net --restart unless-stopped \
  -e POSTGRES_DB=secumon -e POSTGRES_USER=secumon \
  -e POSTGRES_PASSWORD_FILE=/run/secrets/db_password \
  -v /srv/secumon/secrets/db_password:/run/secrets/db_password:ro \
  -v secumon_pgdata:/var/lib/postgresql/data \
  postgres:17

La consola crea por sí sola las tablas y los datos iniciales en su primer arranque. No hace falta cargar el esquema aparte con psql.

3-3. Configuración de la consola

La consola es una aplicación web que se ejecuta sobre Tomcat 11. El modo de ejecución se publicará junto con el paquete de distribución; aquí se resumen primero las variables de entorno que debe definir.

Variable de entornoValor por defectoSignificado
F2B_DB_URLjdbc:postgresql://…:5432/secumonDirección de la base de datos. Use el nombre del contenedor.
F2B_CANONICAL_HOSTObligatorio: su propio valorDominio de su consola. Las conexiones por HTTP sin cifrar o por otra dirección se redirigen a HTTPS en esta dirección.
F2B_PROTECTED_CIDRSObligatorio: su propio valorRangos que nunca se bloquean — su VPN · red interna · IP públicas de los servidores. Las redes privadas · loopback están siempre protegidas, independientemente de este valor.
F2B_BLOCK_TTL_DAYS30Duración por defecto del bloqueo de rangos (días). 0 = permanente.
F2B_AUTO_BLOCK_ENABLEDtrueActiva o desactiva el bloqueo automático de reincidentes.
F2B_AUTO_BLOCK_THRESHOLD3A partir de cuántos bans se bloquea automáticamente.
F2B_AUTO_BLOCK_TTL_DAYS30Duración del bloqueo automático (días).
F2B_FEED_REFRESH_HOURS24Intervalo de descarga de las listas de bloqueo públicas · listas de países (horas).
F2B_BAN_MULTIPLIERS1 2 4 8 16 32 64 168Debe coincidir exactamente con los multiplicadores de la configuración de jail.
F2B_ABUSE_DAILY_LIMIT1000Límite diario de uso de AbuseIPDB.

Tras arrancar, compruebe el estado. Si ve "db":"ok", todo funciona correctamente.

curl -s https://<dirección de la consola>/api/health

4. Registrar servidores — agente

  1. Inicie sesión en la consola como admin, escriba el nombre del servidor en la pestaña Objetivos y pulse Registrar + emitir token.
  2. La pantalla muestra el ID de objetivo y un token de un solo uso. El token solo se muestra esta vez y caduca a los 15 minutos.
  3. En el servidor que quiere proteger, ejecute el script de instalación como root.
# en el servidor a proteger (root)
tar xzf agent-amd64.tgz && cd agent
./install-agent.sh --console https://<dirección de la consola> \
    --target-id <ID de objetivo> --token <token de un solo uso>
journalctl -u secumon-agent -f      # correcto si en 30 s aparece una línea como la de abajo

Si todo va bien, verá una línea como esta secumon-agent: 2026/10/06 16:40:12 전송 완료 — jail 2개, 밴 5건

El script de instalación solo hace lo siguiente. No abre puertos en el firewall.

  • Crea una cuenta dedicada sin inicio de sesión, f2bagent; el agente no se ejecuta como root.
  • Permite por sudo un único wrapper con privilegios de root: /usr/local/sbin/f2b-agent-exec.
  • Genera la clave de firma del agente en ese mismo servidor. La clave privada nunca sale por la red.
  • Tras registrarse en la consola, queda en ejecución permanente como servicio secumon-agent.

No use en la dirección de la consola un nombre de host con guion bajo (_). Tomcat 11 lo rechaza por incumplir el estándar. Compruebe antes con getent hosts <dominio de la consola> que el servidor puede resolver el dominio de la consola.

Si el registro terminó pero falló un paso posterior, corrija la causa y vuelva a ejecutar exactamente el mismo comando. Un agente ya registrado no vuelve a usar el token.

Para retirar un servidor, pulse Desactivar en la consola (las solicitudes de ese agente se rechazan al instante) y ejecute systemctl disable --now secumon-agent en el servidor.

5. Cómo leer la pantalla

  • Panel — bans actuales · bans acumulados · IP reincidentes · tendencias de todos los servidores. Si la «última recepción» de una tarjeta de servidor supera con creces los 30 segundos, revise el agente de ese servidor.
  • Lista de bans — las IP bloqueadas ahora, con nivel de reincidencia · tiempo restante · país. El país se obtiene de una tabla de consulta integrada en la consola.
  • Detalle de IP — servidores donde está bloqueada, historial de bans, duración prevista del próximo ban y reputación en AbuseIPDB.

Los «bans actuales» se leen de la lista que fail2ban está bloqueando realmente, y el «número de reincidencias», por separado, del historial de bans de fail2ban. Así, un ban ya expirado nunca aparece por error como actual.

6. Ban · unban · bloqueo de rangos

  • Ban · unban está disponible a partir del rol de operador. Se puede banear cualquier IP; si no elige jail, se usa sshd.
  • El bloqueo de rangos solo lo puede hacer un administrador. Solo se ejecuta si vuelve a escribir el rango, y se rechaza si es más amplio que IPv4 /16 · IPv6 /48. Por defecto se levanta solo a los 30 días.
  • Puede aplicar varios rangos × varios servidores a la vez. Solo se emite algo si todo supera las comprobaciones, porque un estado aplicado a medias es el más peligroso.
  • El agente del servidor debe recoger el comando en 60 segundos para que se ejecute. Consulte el resultado —completado · fallido · caducado— en el historial de comandos de la pestaña Ejecución.

Si bloqueó algo por error, libérelo en la consola con Ejecución → Desbloquear. Si es tan urgente que no puede entrar en la consola, elimínelo directamente en ese servidor.

# solo un rango
nft delete element inet f2b_console blocklist4 '{ 203.0.113.0/24 }'
# todos los bloqueos añadidos por SecuMon (las reglas de fail2ban están en otra tabla y no se tocan)
nft delete table inet f2b_console

7. Bloqueo automático

Bloqueo automático de reincidentes

Cada 5 minutos selecciona las IP con 3 o más bans acumulados y aplica un bloqueo de 30 días en todos los servidores. Es la única función que modifica el firewall sin aprobación humana; por eso tiene varias capas de protección.

  • Solo bloquea IP individuales (/32 · /128), no rangos.
  • Omite los rangos protegidos. Emite como máximo 20 a la vez.
  • Nunca escala dos veces la misma IP, y todo queda en el registro de auditoría y en Telegram.

Para desactivarlo, pase F2B_AUTO_BLOCK_ENABLED=false a la consola y reiníciela. Para una IP bloqueada por error, primero libérela con Desbloquear y después borre su registro de escalado; así se volverá a evaluar más adelante.

docker exec secumon-db psql -U secumon -d secumon -c "DELETE FROM auto_block WHERE ip = '<IP>'"

Listas de bloqueo públicas

Se activan en la pestaña Feeds de bloqueo. Al principio, ambas están desactivadas.

  • Spamhaus DROP — rangos secuestrados o usados solo para actividades delictivas. No pueden originar tráfico legítimo, así que apenas hay riesgo de falsos positivos.
  • FireHOL level1 — direcciones no asignadas y rangos maliciosos confirmados. También incluye redes privadas, por lo que la consola filtra las entradas que se solapan con los rangos protegidos antes de enviarla.

Se descargan de nuevo una vez al día y, si el contenido no cambia, no se reenvían a los servidores. Los rangos que salen de la lista se desbloquean solos en la siguiente actualización.

8. Bloqueo por país — antes de activarlo

Los servicios que deben ser accesibles desde todo el mundo no se pueden bloquear por país.

  • Servidores DNS autoritativos — sus dominios solo se resuelven si los resolutores de todo el mundo pueden llegar a ellos. SecuMon siempre permite el puerto 53.
  • Recepción de correo (25) · VPN — si los bloquea, el correo se corta y usted no podrá entrar en su propio servidor desde el extranjero. No active el bloqueo por país en esos servidores.
  • Bots de buscadores — si bloquea un país grande, también bloquea los bots de búsqueda y su sitio web puede desaparecer de los resultados.

En la pestaña Bloqueo por país, al elegir un país se muestra primero su número de rangos. Al aplicarlo, la lista se descarga al momento y llega a todos los servidores en menos de 30 segundos; al desactivarlo, se borra la lista de ese país. Un país grande puede llegar a decenas de miles de rangos.

Aunque un país origine muchos ataques, en realidad suelen proceder de unos pocos rangos o de servidores alquilados en ese país. Si los bloquea, se trasladan a servidores de otro país. Considere el bloqueo por país como una medida complementaria, que se usa junto con las listas de bloqueo públicas y el bloqueo automático de reincidentes.

SecuMon permite, al principio de las reglas del firewall, las respuestas de conexiones ya establecidas. Sin esta regla, también se bloquearían las respuestas de las conexiones que su servidor abre hacia servicios de ese país (espejos de paquetes · API de notificaciones · emisión de certificados).

9. AbuseIPDB · Telegram

AbuseIPDB

Se activa al colocar abuseipdb.key en la carpeta de secretos. La clave solo está en el servidor de la consola y nunca sale a la pantalla, la base de datos ni los servidores.

  • Solo puede reportar IP baneadas ahora o en los últimos 30 días; no se puede reportar cualquier IP.
  • No se vuelve a reportar la misma IP en 15 minutos. La propia consola lleva la cuenta del límite diario.
  • La categoría se decide por el nombre de jail: ssh → 18 · 22, web (apache · nginx) → 18 · 21, correo → 18 · 11, otros → 18.

Telegram

# /srv/secumon/secrets/telegram.env
TELEGRAM_TOKEN=<token del bot>
TELEGRAM_CHAT_ID=<ID del chat>

Notifica los bloqueos automáticos de reincidentes y los cambios en las listas públicas. La lista completa se adjunta como archivo. Si no ha cambiado nada, no notifica: si cada día llegara un «sin cambios», acabaría pasando por alto los avisos importantes.

10. Cuentas · autenticación de dos factores

RolQué puede hacer
VIEWER solo lecturaVer panel · lista de bans · detalle de IP · historial de comandos
OPERATOR operador+ ban · unban · reportes a AbuseIPDB y consulta de reputación
ADMIN administrador+ bloqueo de rangos · registro de servidores · feeds de bloqueo · bloqueo por país · usuarios · registro de auditoría
  • El primer inicio de sesión se hace con admin y la contraseña del archivo admin_password. Después, cambie la contraseña en Mi cuenta.
  • En Mi cuenta → Autenticación de dos factores, escanee el código QR con una app de autenticación o introduzca el código a mano. Un mismo código no se puede usar dos veces.
  • Tras 5 contraseñas incorrectas, la cuenta se bloquea 15 minutos, y desde una misma IP solo se permiten 10 intentos por minuto. Tras 30 minutos de inactividad, se cierra la sesión.

Si pierde la app de autenticación, no podrá desactivarla desde la pantalla. Alguien con acceso al servidor de la consola debe desactivarla directamente en la base de datos.

docker exec secumon-db psql -U secumon -d secumon -c \
  "UPDATE app_user SET totp_enabled=false, totp_secret=NULL, totp_last_counter=0 WHERE username='admin';"

11. Copias de seguridad · claves

# base de datos — las contraseñas solo están como hash, y los tokens de registro también
docker exec secumon-db pg_dump -U secumon secumon | gzip > secumon-$(date +%F).sql.gz
# carpeta de secretos — este es el verdadero secreto. Guárdela en un lugar distinto de la copia de la base de datos
tar czf secumon-secrets-$(date +%F).tgz -C /srv/secumon secrets
  • Si cambia la clave de firma de la consola, todos los agentes rechazarán los comandos. Si la cambió, vuelva a registrar cada servidor en este orden: desactivar → emitir un nuevo token → borrar /etc/secumon/agent.json · agent_ed25519.key en el servidor → reinstalar.
  • Qué revisar con regularidad: a diario, el estado de los servidores y los comandos fallidos; cada semana, los rechazos del registro de auditoría y las cuentas sin autenticación de dos factores.

12. Solución de problemas

Los mensajes del agente y de la consola se muestran en coreano. Busque en el log el texto exacto que aparece con formato de código en la tabla de abajo.

SíntomaCausaQué hacer
Log del agente 등록되지 않았거나 비활성 상태인 타겟Servidor desactivado en la consolaObtener un nuevo token y volver a registrar
Log del agente 요청 시각 편차가 허용치를 넘습니다El reloj del servidor difiere en más de 60 sSincronizar el reloj con NTP
Log del agente 이미 사용된 nonceLa misma solicitud llegó de nuevoEs una defensa normal. Si persiste, sospeche de envíos duplicados en la red
Resultado del comando 거부: 만료된 명령El agente no lo recogió en 60 sCompruebe el estado de secumon-agent en el servidor y vuelva a ejecutar el comando
Resultado del comando 거부: 서명이 유효하지 않음Se cambió la clave de firma de la consola sin volver a registrarVolver a registrar con los pasos de la sección 11
La última recepción de la tarjeta del servidor se detuvo · el log se cortóEl agente se ha detenidosystemctl restart secumon-agent
Se activó el bloqueo por país, pero no se refleja en el servidorFalta esta línea en el log del agente: 국가 차단 적용Compruebe que el agente está en la última versión y revise los errores del log
La sesión se cierra una y otra vezAcceso por una dirección que no es HTTPSAcceda por la dirección HTTPS de la consola

Para más consultas, escriba a halo@levelupsoft.com.