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
| Elemento | Condiciones |
|---|---|
| Servidores a proteger | Linux (systemd) + fail2ban · nftables · sqlite3. amd64 o arm64. Probado en Ubuntu 22.04 · CentOS 8. |
| Servidor de consola | Uno. JDK 21 · Tomcat 11 · PostgreSQL 17. Lo más sencillo es usar Docker. |
| Red | Los 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. |
| Reloj | Sincronice 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. |
| Certificado | Certificado 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 acumulados | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 o más |
|---|---|---|---|---|---|---|---|---|
| Duración del ban | 1 h | 2 h | 4 h | 8 h | 16 h | 32 h | 64 h | 7 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
| Archivo | Uso | Si falta |
|---|---|---|
db_password | Conexión a la base de datos | La consola no arranca |
admin_password | Contraseña de la primera cuenta de administrador, admin | No se crea la cuenta y no podrá iniciar sesión |
console_ed25519.key · .pub | Firma de comandos | Solo podrá ver, no ejecutar |
abuseipdb.key | Clave de API de AbuseIPDB (opcional) | No podrá reportar ni consultar la reputación |
telegram.env | Notificaciones de Telegram (opcional) | No se envían notificaciones |
tls/cert.pem · chain.pem · privkey.pem | Certificado HTTPS de la consola | No 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 entorno | Valor por defecto | Significado |
|---|---|---|
F2B_DB_URL | jdbc:postgresql://…:5432/secumon | Dirección de la base de datos. Use el nombre del contenedor. |
F2B_CANONICAL_HOST | Obligatorio: su propio valor | Dominio de su consola. Las conexiones por HTTP sin cifrar o por otra dirección se redirigen a HTTPS en esta dirección. |
F2B_PROTECTED_CIDRS | Obligatorio: su propio valor | Rangos 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_DAYS | 30 | Duración por defecto del bloqueo de rangos (días). 0 = permanente. |
F2B_AUTO_BLOCK_ENABLED | true | Activa o desactiva el bloqueo automático de reincidentes. |
F2B_AUTO_BLOCK_THRESHOLD | 3 | A partir de cuántos bans se bloquea automáticamente. |
F2B_AUTO_BLOCK_TTL_DAYS | 30 | Duración del bloqueo automático (días). |
F2B_FEED_REFRESH_HOURS | 24 | Intervalo de descarga de las listas de bloqueo públicas · listas de países (horas). |
F2B_BAN_MULTIPLIERS | 1 2 4 8 16 32 64 168 | Debe coincidir exactamente con los multiplicadores de la configuración de jail. |
F2B_ABUSE_DAILY_LIMIT | 1000 | Lí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
- Inicie sesión en la consola como
admin, escriba el nombre del servidor en la pestaña Objetivos y pulse Registrar + emitir token. - 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.
- 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
| Rol | Qué puede hacer |
|---|---|
VIEWER solo lectura | Ver 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
adminy la contraseña del archivoadmin_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.keyen 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íntoma | Causa | Qué hacer |
|---|---|---|
Log del agente 등록되지 않았거나 비활성 상태인 타겟 | Servidor desactivado en la consola | Obtener un nuevo token y volver a registrar |
Log del agente 요청 시각 편차가 허용치를 넘습니다 | El reloj del servidor difiere en más de 60 s | Sincronizar el reloj con NTP |
Log del agente 이미 사용된 nonce | La misma solicitud llegó de nuevo | Es una defensa normal. Si persiste, sospeche de envíos duplicados en la red |
Resultado del comando 거부: 만료된 명령 | El agente no lo recogió en 60 s | Compruebe 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 registrar | Volver 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 detenido | systemctl restart secumon-agent |
| Se activó el bloqueo por país, pero no se refleja en el servidor | Falta 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 vez | Acceso por una dirección que no es HTTPS | Acceda por la dirección HTTPS de la consola |
Para más consultas, escriba a halo@levelupsoft.com.
fail2ban · nftables · AbuseIPDB · Spamhaus · FireHOL · Telegram · Let's Encrypt pertenecen a sus respectivos propietarios; SSem SecuMon no está afiliado a ellos ni cuenta con su respaldo.