DownloadSentinela ? Intelligent Linux Security Framework

> Firewall WAF + IDS/IPS + PHP Dashboard + Telegram Alerts ? todo en Bash, sin dependencias de Node.js o Python.
Architecture
INPUT ? SENTINELA_INPUT ? SENTINELA_NEW ? DROP
| Chain | Purpose |
|-------|---------|
| SENTINELA_INPUT | base rules (loopback, ESTABLISHED, ICMP, anti-spoofing, port scan, SYN flood, ipsets, services) + DROP |
| SENTINELA_NEW | connlimit + rate limit for HTTP/HTTPS NEW connections |
Sentinela never runs iptables -F or iptables -P INPUT DROP. It only creates/manages its own named chains, ensuring SSH access is never accidentally locked out.
Features
Firewall
-
48 iptables rules across `SENTINELA_INPUT` and `SENTINELA_NEW`
-
Anti-spoofing (RFC 1918)
-
Port scan detection (NULL, XMAS, SYN/FIN)
-
SYN flood protection
-
Service-aware rate limiting & connection limiting per IP
-
Automatic SSH session detection and whitelisting (24h timeout)
-
Rollback: applies rules, waits N seconds for confirmation, reverts automatically if no response
IDS (Intrusion Detection)
Scans Apache access logs for:
- SQLi: 40+ patterns (UNION, SLEEP, BENCHMARK, hex encoding, double URL encoding, stacked queries)
- XSS: <script>, onerror, onload, javascript:, event handlers
- LFI/RFI: ../, file://, php://filter, data://, expect://
- Scanners: .env, wp-config, .git/config, phpmyadmin, actuator, xmlrpc
- Malicious User-Agents: sqlmap, nikto, masscan, zgrab, Go-http-client
- DDoS: >100 requests from same IP in last 1000 log lines
- SSH brute force: failed login detection from /var/log/auth.log
- Honeypot: fake URL paths that trap and block scanners
IPS (Intrusion Prevention)
Blocking is temporary via ipset with configurable timeout:
| ipset | Type | Default timeout | Purpose |
|-------|------|-----------------|---------|
| SENTINELA_TRUSTED | hash:ip | 86400s (24h) | Whitelisted IPs (auto: current SSH session) |
| SENTINELA_BLACKLIST | hash:ip | 600s (10 min) | All malicious IPs |
| SENTINELA_DDOS | hash:ip | 600s (10 min) | DDoS-behaving IPs |
| SENTINELA_REPUTATION | hash:net | 86400s (24h) | External blacklists (Spamhaus, Emerging Threats, etc.) |
| SENTINELA_HONEY | hash:ip | 3600s (1h) | Honeypot triggers |
Dashboard
-
PHP + Bootstrap 5 + Chart.js
-
REST API with endpoints: `status`, `stats`, `banned`, `attacks`, `top_ips`, `top_countries`, `geoip`, `ban`, `unban`
-
Auto-refresh every 10 seconds
-
Top 10 attackers with geolocation
-
Block/unblock from web UI
Telegram Alerts
-
HTML-formatted alerts with inline "Unblock IP" button
-
Triggered by: manual ban, IDS detection (SQLi, XSS, scanners, DDoS), honeypot hits
-
Message includes: server, IP, country, ASN, attack type, URI, User-Agent, block duration
Log System Support
Supports both rsyslog (Debian 12, file-based) and systemd-journald (Debian 13+, native):
- rsyslog: reads /var/log/auth.log, /var/log/apache2/access.log via tail -c with byte-position tracking
- journald: reads via journalctl with cursor-based tracking (no files needed)
- SSH auth detection works with both modes
- Apache access log detection works in both modes (Apache typically logs to files; journald mode reads from apache2.service journal)
- Switch by setting LOG_SYSTEM=rsyslog or LOG_SYSTEM=journald in /etc/sentinela/config.conf
Services & Ports (default)
| Service | Port | Access | Rate limit | Connlimit |
|---------|------|--------|------------|-----------|
| SSH | 7890 | WAN | 5/min per IP | 3/IP |
| HTTP | 80 | WAN | 60/min per IP | 30/IP |
| HTTPS | 443 | WAN | 60/min per IP | 30/IP |
| MariaDB | 3306 | localhost only | ? | ? |
| PHP-FPM | 8000-8008 | localhost only | ? | ? |
Requirements
-
OS: Debian 12+ (Bookworm)
-
Kernel: 5.x+ (tested on 6.x)
-
Arch: x86_64
-
Root access: required for iptables, ipset, systemd
-
Web server: Apache 2.4+ with mod_php (for dashboard)
-
PHP 8.x with sqlite3, json, curl extensions
-
Disk: ~200MB for logs, backups, GeoIP databases
Installation
Quick install (from GitHub)
git clone https://github.com/zaer00t/sentinela.git /root/sentinela
cd /root/sentinela
bash install.sh
Options
bash install.sh # Interactive (asks for each step)
bash install.sh --unattended # No prompts, use defaults
bash install.sh --dev # Symlinks instead of copies (for development)
What the installer does
-
Verifies Debian compatibility, root, kernel version
-
Installs dependencies: iptables, ipset, curl, jq, sqlite3, php8.x, apache2, geoip-bin, mmdb-bin, etc.
-
Creates directory structure under `/usr/local/sentinela/`
-
Copies files and creates `/usr/local/bin/sentinela` symlink
-
Configures ipsets (creates all 5 named ipsets)
-
Installs systemd service (`sentinela.service`)
-
Installs cron jobs (IDS scan every 5 min, reputation hourly, backup daily at 3 AM, health check every 10 min)
-
Configures Apache vhost for dashboard (optional)
-
Runs connectivity tests
Post-install
# 1. Edit configuration
nano /etc/sentinela/config.conf
# 2. Set your Telegram bot (recommended)
# TELEGRAM_ENABLE=yes
# TELEGRAM_BOT_TOKEN=...
# TELEGRAM_CHAT_ID=...
# 3. Apply firewall
sentinela apply
# 4. Verify
sentinela status
Configuration
File: /etc/sentinela/config.conf (root:root, chmod 600)
# === Network ===
IFACE=eth0
PORT_SSH=7890
PORT_HTTP=80
PORT_HTTPS=443
PORT_MYSQL=3306
# === Rate Limits ===
SSH_RATE_LIMIT=5
HTTP_RATE_LIMIT=60
HTTPS_RATE_LIMIT=60
SSH_CONNLIMIT=3
HTTP_CONNLIMIT=30
HTTPS_CONNLIMIT=30
# === Blocking ===
BAN_TIME=600
DDOS_BAN_TIME=600
# === Features ===
TELEGRAM_ENABLE=yes
TELEGRAM_BOT_TOKEN=your_bot_token
TELEGRAM_CHAT_ID=your_chat_id
ROLLBACK_ENABLE=yes
ROLLBACK_TIMEOUT=90
REPUTATION_ENABLE=no
LOG_LEVEL=info
# === Services ===
ENABLE_SSH=yes
ENABLE_HTTP=yes
ENABLE_HTTPS=yes
ENABLE_MYSQL=yes
# === System Logger (rsyslog | journald) ===
# Debian 12 uses rsyslog (files), Debian 13+ uses journald by default.
LOG_SYSTEM=rsyslog
# === Logs ===
LOG_DIR=/var/log/sentinela
BACKUP_DIR=/var/backups/sentinela
BACKUP_RETENTION=7
# === IDS ===
IDS_APACHE_LOG=/var/log/apache2/access.log
IDS_SSH_LOG=/var/log/auth.log
Usage
Firewall commands
sentinela apply # Apply firewall rules (with rollback)
sentinela stop # Remove Sentinela chains (safe)
sentinela restart # stop + apply
sentinela status # Show rule count, ipsets, active connections
Blocking
sentinela ban 192.168.1.100 # Block IP (600s by default)
sentinela ban 192.168.1.100 "reason" # Block with reason
sentinela unban 192.168.1.100 # Unblock IP
sentinela flush # Clear all blocked IPs
sentinela banned # List currently banned IPs
IDS
sentinela scan # Scan Apache + SSH logs
sentinela reputation # Update external blacklists
sentinela health # Full system health check
sentinela attacks # Show attack log (last 50)
Whitelist
sentinela whitelist # Show trusted IPs
sentinela trust 1.2.3.4 # Add IP to TRUSTED (24h)
sentinela untrust 1.2.3.4 # Remove from TRUSTED
Logs
sentinela logs # Show general log (last 50 lines)
sentinela logs 100 # Show last 100 lines
sentinela attacks # Show attack detections
Backup
sentinela backup # Create full backup
sentinela restore # Restore from backup
Other
sentinela geoip 8.8.8.8 # GeoIP lookup
sentinela telegram-test # Test Telegram connectivity
sentinela version # Show version
sentinela help # Full command reference
Project Structure
/usr/local/sentinela/
??? cli/
? ??? sentinela.sh # CLI entry point (dispatches all commands)
??? lib/
? ??? common.sh # Core functions, logging, config loading
? ??? rollback.sh # Firewall transaction + automatic rollback
? ??? snapshot.sh # iptables save/restore snapshots
? ??? ssh-session.sh # SSH session detection + TRUSTED ipset
??? firewall/
? ??? firewall.sh # Chain creation, rule orchestration
? ??? ssh.sh # SSH rules
? ??? http.sh # HTTP rules
? ??? https.sh # HTTPS rules
? ??? mysql.sh # MySQL/MariaDB rules
? ??? blacklist.sh # BLACKLIST ipset management
? ??? whitelist.sh # TRUSTED ipset management
? ??? geoip.sh # GeoIP lookup functions
??? ids/
? ??? apache.sh # Main Apache log scanner
? ??? sqli.sh # SQL injection patterns
? ??? xss.sh # XSS patterns
? ??? lfi.sh # LFI patterns
? ??? rfi.sh # RFI patterns
? ??? scanners.sh # Scanner detection + User-Agent check
? ??? ddos.sh # DDoS detection
? ??? ssh.sh # SSH brute force detection
??? ipset/
? ??? manager.sh # ipset create/destroy/list
??? telegram/
? ??? telegram.sh # Telegram alert sender with inline buttons
??? dashboard/
? ??? index.php # Bootstrap 5 + Chart.js frontend
? ??? api/index.php # REST API endpoints
? ??? assets/
? ??? css/dashboard.css
? ??? js/dashboard.js
??? cron/
? ??? cron.sh # Cron task definitions
??? backup/
? ??? restore.sh # Backup creation and restoration
??? systemd/
? ??? sentinela.service # Systemd oneshot unit
??? install.sh # Installer
??? uninstall.sh # Uninstaller
??? update.sh # Update script
/etc/sentinela/
??? config.conf # Configuration (root:root, chmod 600)
/var/log/sentinela/
??? sentinela.log # General log
??? banned.log # Banned IPs
??? attacks.log # Attack detections
/var/www/sentinela/ # Dashboard web root
Systemd Service
The service applies firewall at boot and flushes on stop:
systemctl enable sentinela # Enable at boot
systemctl start sentinela # Apply firewall
systemctl stop sentinela # Remove Sentinela chains
systemctl status sentinela # Check status
Unit file: /etc/systemd/system/sentinela.service
[Unit]
Description=Sentinela ? Intelligent Linux Security Framework
After=network-online.target iptables.service ipset.service
Wants=network-online.target
DefaultDependencies=no
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/sentinela start
ExecStop=/usr/local/bin/sentinela stop
ExecReload=/usr/local/bin/sentinela restart
Cron Tasks
Installed via /etc/cron.d/sentinela:
| Interval | Command | Purpose |
|----------|---------|---------|
| /5 * | sentinela scan | IDS log scanning |
| 0 | sentinela reputation | Update external blacklists |
| 0 3 * | sentinela backup | Daily backup |
| 0 4 * | sentinela cleanup | Rotate logs, clean cache |
| /10 * | sentinela health | System health check |
Log Files
| File | Content |
|------|---------|
| /var/log/sentinela/sentinela.log | All events (INFO, WARN, ERROR, FATAL) |
| /var/log/sentinela/banned.log | Block/unblock events with reason |
| /var/log/sentinela/attacks.log | Detected attacks with full context |
| /var/log/sentinela/dashboard.json | Dashboard stats cache |
Dashboard
Access: https://sen.moit.in/ (or http://<server>:8080 if using default vhost)
Features:
- Firewall status overview (rules, ipsets, active connections)
- Top 10 attacking IPs with geolocation
- Attack timeline (last 24h by type)
- Country distribution map
- Ban/unban IP from web UI
- Real-time auto-refresh every 10 seconds
API Endpoints
| Endpoint | Method | Description |
|----------|--------|-------------|
| /api/ | GET | API status |
| /api?action=status | GET | Firewall status |
| /api?action=stats | GET | Statistics for charts |
| /api?action=banned | GET | Currently banned IPs |
| /api?action=attacks | GET | Recent attacks |
| /api?action=top_ips | GET | Top 10 attackers |
| /api?action=top_countries | GET | Attack distribution by country |
| /api?action=geoip&ip=X.X.X.X | GET | GeoIP lookup |
| /api?action=ban&ip=X.X.X.X | POST | Block an IP |
| /api?action=unban&ip=X.X.X.X | POST | Unblock an IP |
Security Considerations
SSH Protection
-
The script always detects the current SSH session IP before applying rules and adds it to `SENTINELA_TRUSTED` (24h timeout)
-
If no SSH session is detected during interactive use, the apply is cancelled
-
If no SSH session is detected during systemd boot, rules are applied without rollback (no human to confirm)
Rollback
-
Enabled by default (`ROLLBACK_ENABLE=yes`)
-
After `sentinela apply`, you have 90 seconds to confirm
-
If you lose SSH access and don't confirm, rules are automatically reverted
-
Rollback is disabled in non-interactive mode (systemd boot)
What NOT to do
-
Never run `iptables -F` or `iptables -P INPUT DROP` ? this kills all rules including SSH
-
Never modify the script's ipsets with `ipset flush` unless you understand the consequences
-
The `flush` command asks for confirmation before clearing all blocked IPs
Dashboard Security
-
The API runs as `www-data` with sudo access limited to `ipset` and `iptables` via `/etc/sudoers.d/sentinela`
-
The API validates IP format before executing commands
-
Dashboard file ownership: `root:www-data` with 750 permissions
Development
Testing changes
# 1. Edit files in /root/sentinela/
nano /root/sentinela/lib/common.sh
# 2. Sync to installed directory
cp /root/sentinela/lib/common.sh /usr/local/sentinela/lib/common.sh
# 3. Test syntax
bash -n /usr/local/sentinela/lib/common.sh
# 4. Test the command
sentinela apply
Running without install
The CLI can run directly from the source directory:
export SENTINELA_DIR=/root/sentinela
export SENTINELA_CONFIG=/root/sentinela/config.conf
bash /root/sentinela/cli/sentinela.sh status
IDS pattern debugging
To test SQLi detection against a custom log line:
echo 'GET /?id=1%27%20UNION%20SELECT%201,2,3-- HTTP/1.1' >> /tmp/test.log
sed -i 's|IDS_APACHE_LOG=.*|IDS_APACHE_LOG=/tmp/test.log|' /etc/sentinela/config.conf
sentinela scan
Troubleshooting
Firewall blocks everything (locked out)
If you lose SSH access:
# From console/out-of-band management:
sentinela flush
# or
systemctl stop sentinela
Systemd service fails at boot
journalctl -u sentinela.service --no-pager -l
# Most common cause: SSH_CLIENT unbound variable
# Fix: ensure ${SSH_CLIENT:-} uses default value syntax
Telegram alerts not sending
sentinela telegram-test
# Check /var/log/sentinela/sentinela.log for errors
# Verify TELEGRAM_BOT_TOKEN and TELEGRAM_CHAT_ID in config.conf
# Ensure jq is installed: apt-get install -y jq
Dashboard shows no data
# Check Apache error log
tail -50 /var/log/apache2/error.log
# Verify www-data has sudo access
sudo -u www-data sudo -n ipset list SENTINELA_BLACKLIST
# Check dashboard.json exists
cat /var/log/sentinela/dashboard.json
Uninstallation
sentinela uninstall
This removes:
- iptables chains (SENTINELA_INPUT, SENTINELA_NEW)
- All ipsets
- Systemd service
- Cron jobs
- /usr/local/sentinela/
- /usr/local/bin/sentinela
- Logs and backups (prompts for confirmation)
Does not remove:
- Apache configuration
- GeoIP databases
- Packages (iptables, ipset, etc.)
- /etc/sentinela/config.conf (backed up to /etc/sentinela/config.conf.uninstalled)
License
MIT
Sentinela ? because your server deserves better than a default iptables policy.
<hr>
<hr>
<div align="center">
<h1>?? Versión en Español</h1>
</div>
Sentinela ? Framework Inteligente de Seguridad para Linux

> Firewall WAF + IDS/IPS + Panel PHP + Alertas Telegram ? todo en Bash, sin Node.js ni Python.
Arquitectura
INPUT ? SENTINELA_INPUT ? SENTINELA_NEW ? DROP
| Cadena | Propósito |
|--------|-----------|
| SENTINELA_INPUT | reglas base (loopback, ESTABLISHED, ICMP, anti-spoofing, escaneo de puertos, SYN flood, ipsets, servicios) + DROP |
| SENTINELA_NEW | connlimit + rate limit para conexiones HTTP/HTTPS NEW |
Sentinela nunca ejecuta iptables -F ni iptables -P INPUT DROP. Solo crea/administra sus propias cadenas, garantizando que el acceso SSH nunca se pierda accidentalmente.
Características
Firewall
-
48 reglas iptables distribuidas en `SENTINELA_INPUT` y `SENTINELA_NEW`
-
Anti-spoofing (RFC 1918)
-
Detección de escaneo de puertos (NULL, XMAS, SYN/FIN)
-
Protección contra SYN flood
-
Límite de tasa y conexiones por servicio y por IP
-
Detección automática de sesión SSH y whitelisting (timeout 24h)
-
Rollback: aplica reglas, espera N segundos por confirmación, revierte automáticamente si no hay respuesta
IDS (Detección de Intrusos)
Escanea logs de Apache en busca de:
- SQLi: más de 40 patrones (UNION, SLEEP, BENCHMARK, codificación hex, doble URL encoding, consultas apiladas)
- XSS: <script>, onerror, onload, javascript:, manejadores de eventos
- LFI/RFI: ../, file://, php://filter, data://, expect://
- Escáneres: .env, wp-config, .git/config, phpmyadmin, actuator, xmlrpc
- User-Agents maliciosos: sqlmap, nikto, masscan, zgrab, Go-http-client
- DDoS: más de 100 peticiones de la misma IP en las últimas 1000 líneas del log
- Fuerza bruta SSH: detección de intentos de login fallidos desde /var/log/auth.log
- Honeypot: rutas URL falsas que atrapan y bloquean escáneres
IPS (Prevención de Intrusos)
El bloqueo es temporal via ipset con timeout configurable:
| ipset | Tipo | Timeout por defecto | Propósito |
|-------|------|---------------------|-----------|
| SENTINELA_TRUSTED | hash:ip | 86400s (24h) | IPs en lista blanca (automático: sesión SSH actual) |
| SENTINELA_BLACKLIST | hash:ip | 600s (10 min) | Todas las IPs maliciosas |
| SENTINELA_DDOS | hash:ip | 600s (10 min) | IPs con comportamiento DDoS |
| SENTINELA_REPUTATION | hash:net | 86400s (24h) | Listas negras externas (Spamhaus, Emerging Threats, etc.) |
| SENTINELA_HONEY | hash:ip | 3600s (1h) | Disparadores del honeypot |
Panel Web
-
PHP + Bootstrap 5 + Chart.js
-
API REST con endpoints: `status`, `stats`, `banned`, `attacks`, `top_ips`, `top_countries`, `geoip`, `ban`, `unban`
-
Auto-actualización cada 10 segundos
-
Top 10 atacantes con geolocalización
-
Bloquear/desbloquear desde la interfaz web
Alertas Telegram
-
Alertas con formato HTML y botón inline "Desbloquear IP"
-
Activadas por: bloqueo manual, detección IDS (SQLi, XSS, escáneres, DDoS), honeypot
-
El mensaje incluye: servidor, IP, país, ASN, tipo de ataque, URI, User-Agent, duración del bloqueo
Soporte de Sistema de Logs
Soporta rsyslog (Debian 12, basado en archivos) y systemd-journald (Debian 13+, nativo):
- rsyslog: lee /var/log/auth.log, /var/log/apache2/access.log via tail -c con seguimiento por posición de byte
- journald: lee via journalctl con seguimiento por cursor (sin necesidad de archivos)
- La detección de fuerza bruta SSH funciona con ambos modos
- La detección en logs de Apache funciona en ambos modos (Apache normalmente escribe a archivos; el modo journald lee del journal de apache2.service)
- Cambia configurando LOG_SYSTEM=rsyslog o LOG_SYSTEM=journald en /etc/sentinela/config.conf
Servicios y Puertos (por defecto)
| Servicio | Puerto | Acceso | Límite de tasa | Límite de conexiones |
|----------|--------|--------|----------------|---------------------|
| SSH | 7890 | WAN | 5/min por IP | 3/IP |
| HTTP | 80 | WAN | 60/min por IP | 30/IP |
| HTTPS | 443 | WAN | 60/min por IP | 30/IP |
| MariaDB | 3306 | solo localhost | ? | ? |
| PHP-FPM | 8000-8008 | solo localhost | ? | ? |
Requisitos
-
SO: Debian 12+ (Bookworm)
-
Kernel: 5.x+ (probado en 6.x)
-
Arquitectura: x86_64
-
Acceso root: necesario para iptables, ipset, systemd
-
Servidor web: Apache 2.4+ con mod_php (para el panel)
-
PHP 8.x con extensiones sqlite3, json, curl
-
Disco: ~200MB para logs, backups, bases de datos GeoIP
Instalación
Instalación rápida (desde GitHub)
git clone https://github.com/zaer00t/sentinela.git /root/sentinela
cd /root/sentinela
bash install.sh
Opciones
bash install.sh # Interactivo (pregunta en cada paso)
bash install.sh --unattended # Sin preguntas, usa valores por defecto
bash install.sh --dev # Enlaces simbólicos en lugar de copias (para desarrollo)
Qué hace el instalador
-
Verifica compatibilidad con Debian, root, versión del kernel
-
Instala dependencias: iptables, ipset, curl, jq, sqlite3, php8.x, apache2, geoip-bin, mmdb-bin, etc.
-
Crea la estructura de directorios en `/usr/local/sentinela/`
-
Copia archivos y crea el enlace simbólico `/usr/local/bin/sentinela`
-
Configura ipsets (crea los 5 ipsets con nombre)
-
Instala el servicio systemd (`sentinela.service`)
-
Instala tareas cron (escaneo IDS cada 5 min, reputación cada hora, backup diario a las 3 AM, health check cada 10 min)
-
Configura el vhost de Apache para el panel (opcional)
-
Ejecuta pruebas de conectividad
Post-instalación
# 1. Editar configuración
nano /etc/sentinela/config.conf
# 2. Configurar bot de Telegram (recomendado)
# TELEGRAM_ENABLE=yes
# TELEGRAM_BOT_TOKEN=...
# TELEGRAM_CHAT_ID=...
# 3. Aplicar firewall
sentinela apply
# 4. Verificar
sentinela status
Configuración
Archivo: /etc/sentinela/config.conf (root:root, chmod 600)
# === Red ===
IFACE=eth0
PORT_SSH=7890
PORT_HTTP=80
PORT_HTTPS=443
PORT_MYSQL=3306
# === Límites de tasa ===
SSH_RATE_LIMIT=5
HTTP_RATE_LIMIT=60
HTTPS_RATE_LIMIT=60
SSH_CONNLIMIT=3
HTTP_CONNLIMIT=30
HTTPS_CONNLIMIT=30
# === Bloqueo ===
BAN_TIME=600
DDOS_BAN_TIME=600
# === Funcionalidades ===
TELEGRAM_ENABLE=yes
TELEGRAM_BOT_TOKEN=token_de_tu_bot
TELEGRAM_CHAT_ID=tu_chat_id
ROLLBACK_ENABLE=yes
ROLLBACK_TIMEOUT=90
REPUTATION_ENABLE=no
LOG_LEVEL=info
# === Servicios ===
ENABLE_SSH=yes
ENABLE_HTTP=yes
ENABLE_HTTPS=yes
ENABLE_MYSQL=yes
# === Sistema de logging (rsyslog | journald) ===
LOG_SYSTEM=rsyslog
# === Logs ===
LOG_DIR=/var/log/sentinela
BACKUP_DIR=/var/backups/sentinela
BACKUP_RETENTION=7
# === IDS ===
IDS_APACHE_LOG=/var/log/apache2/access.log
IDS_SSH_LOG=/var/log/auth.log
Uso
Comandos del firewall
sentinela apply # Aplicar reglas de firewall (con rollback)
sentinela stop # Eliminar cadenas de Sentinela (seguro)
sentinela restart # stop + apply
sentinela status # Mostrar conteo de reglas, ipsets, conexiones activas
Bloqueo
sentinela ban 192.168.1.100 # Bloquear IP (600s por defecto)
sentinela ban 192.168.1.100 "motivo" # Bloquear IP con motivo
sentinela unban 192.168.1.100 # Desbloquear IP
sentinela flush # Limpiar todas las IPs bloqueadas
sentinela banned # Listar IPs bloqueadas actualmente
IDS
sentinela scan # Escanear logs de Apache + SSH
sentinela reputation # Actualizar listas negras externas
sentinela health # Verificación completa del sistema
sentinela attacks # Mostrar log de ataques (últimos 50)
Lista blanca
sentinela whitelist # Mostrar IPs de confianza
sentinela trust 1.2.3.4 # Agregar IP a TRUSTED (24h)
sentinela untrust 1.2.3.4 # Eliminar de TRUSTED
Logs
sentinela logs # Mostrar log general (últimas 50 líneas)
sentinela logs 100 # Mostrar últimas 100 líneas
sentinela attacks # Mostrar detecciones de ataques
Backup
sentinela backup # Crear backup completo
sentinela restore # Restaurar desde backup
Otros
sentinela geoip 8.8.8.8 # Consulta GeoIP
sentinela telegram-test # Probar conectividad con Telegram
sentinela version # Mostrar versión
sentinela help # Referencia completa de comandos
Estructura del Proyecto
/usr/local/sentinela/
??? cli/
? ??? sentinela.sh # Punto de entrada CLI (despacha todos los comandos)
??? lib/
? ??? common.sh # Funciones principales, logging, carga de configuración
? ??? rollback.sh # Transacción de firewall + rollback automático
? ??? snapshot.sh # Guardado/restauración de snapshots de iptables
? ??? ssh-session.sh # Detección de sesión SSH + ipset TRUSTED
??? firewall/
? ??? firewall.sh # Creación de cadenas, orquestación de reglas
? ??? ssh.sh # Reglas SSH
? ??? http.sh # Reglas HTTP
? ??? https.sh # Reglas HTTPS
? ??? mysql.sh # Reglas MySQL/MariaDB
? ??? blacklist.sh # Gestión del ipset BLACKLIST
? ??? whitelist.sh # Gestión del ipset TRUSTED
? ??? geoip.sh # Funciones de consulta GeoIP
??? ids/
? ??? apache.sh # Escáner principal de logs de Apache
? ??? sqli.sh # Patrones de inyección SQL
? ??? xss.sh # Patrones XSS
? ??? lfi.sh # Patrones LFI
? ??? rfi.sh # Patrones RFI
? ??? scanners.sh # Detección de escáneres + verificación de User-Agent
? ??? ddos.sh # Detección DDoS
? ??? ssh.sh # Detección de fuerza bruta SSH
??? ipset/
? ??? manager.sh # Crear/destruir/listar ipsets
??? telegram/
? ??? telegram.sh # Envío de alertas Telegram con botones inline
??? dashboard/
? ??? index.php # Frontend Bootstrap 5 + Chart.js
? ??? api/index.php # Endpoints de la API REST
? ??? assets/
? ??? css/dashboard.css
? ??? js/dashboard.js
??? cron/
? ??? cron.sh # Definiciones de tareas cron
??? backup/
? ??? restore.sh # Creación y restauración de backups
??? systemd/
? ??? sentinela.service # Unidad oneshot de systemd
??? install.sh # Instalador
??? uninstall.sh # Desinstalador
??? update.sh # Script de actualización
/etc/sentinela/
??? config.conf # Configuración (root:root, chmod 600)
/var/log/sentinela/
??? sentinela.log # Log general
??? banned.log # IPs bloqueadas
??? attacks.log # Detecciones de ataques
/var/www/sentinela/ # Raíz web del panel
Servicio Systemd
El servicio aplica el firewall al inicio y lo limpia al detenerse:
systemctl enable sentinela # Habilitar al inicio
systemctl start sentinela # Aplicar firewall
systemctl stop sentinela # Eliminar cadenas de Sentinela
systemctl status sentinela # Ver estado
Archivo de unidad: /etc/systemd/system/sentinela.service
[Unit]
Description=Sentinela ? Intelligent Linux Security Framework
After=network-online.target iptables.service ipset.service
Wants=network-online.target
DefaultDependencies=no
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/sentinela start
ExecStop=/usr/local/bin/sentinela stop
ExecReload=/usr/local/bin/sentinela restart
Tareas Cron
Instaladas via /etc/cron.d/sentinela:
| Intervalo | Comando | Propósito |
|-----------|---------|-----------|
| /5 * | sentinela scan | Escaneo IDS de logs |
| 0 | sentinela reputation | Actualizar listas negras externas |
| 0 3 * | sentinela backup | Backup diario |
| 0 4 * | sentinela cleanup | Rotar logs, limpiar caché |
| /10 * | sentinela health | Verificación de salud del sistema |
Archivos de Log
| Archivo | Contenido |
|---------|-----------|
| /var/log/sentinela/sentinela.log | Todos los eventos (INFO, WARN, ERROR, FATAL) |
| /var/log/sentinela/banned.log | Eventos de bloqueo/desbloqueo con motivo |
| /var/log/sentinela/attacks.log | Ataques detectados con contexto completo |
| /var/log/sentinela/dashboard.json | Caché de estadísticas del panel |
Panel Web
Acceso: https://sen.moit.in/ (o http://<servidor>:8080 si se usa el vhost por defecto)
Características:
- Resumen del estado del firewall (reglas, ipsets, conexiones activas)
- Top 10 IPs atacantes con geolocalización
- Línea de tiempo de ataques (últimas 24h por tipo)
- Mapa de distribución por país
- Bloquear/desbloquear IP desde la interfaz web
- Auto-actualización en tiempo real cada 10 segundos
Endpoints de la API
| Endpoint | Método | Descripción |
|----------|--------|-------------|
| /api/ | GET | Estado de la API |
| /api?action=status | GET | Estado del firewall |
| /api?action=stats | GET | Estadísticas para gráficos |
| /api?action=banned | GET | IPs bloqueadas actualmente |
| /api?action=attacks | GET | Ataques recientes |
| /api?action=top_ips | GET | Top 10 atacantes |
| /api?action=top_countries | GET | Distribución de ataques por país |
| /api?action=geoip&ip=X.X.X.X | GET | Consulta GeoIP |
| /api?action=ban&ip=X.X.X.X | POST | Bloquear una IP |
| /api?action=unban&ip=X.X.X.X | POST | Desbloquear una IP |
Consideraciones de Seguridad
Protección SSH
-
El script siempre detecta la IP de la sesión SSH actual antes de aplicar reglas y la agrega a `SENTINELA_TRUSTED` (timeout 24h)
-
Si no se detecta una sesión SSH durante el uso interactivo, la aplicación se cancela
-
Si no se detecta una sesión SSH durante el inicio con systemd, las reglas se aplican sin rollback (no hay un humano para confirmar)
Rollback
-
Habilitado por defecto (`ROLLBACK_ENABLE=yes`)
-
Después de `sentinela apply`, tienes 90 segundos para confirmar
-
Si pierdes el acceso SSH y no confirmas, las reglas se revienten automáticamente
-
El rollback está deshabilitado en modo no interactivo (inicio con systemd)
Lo que NO debes hacer
-
Nunca ejecutes `iptables -F` o `iptables -P INPUT DROP` ? esto elimina todas las reglas incluyendo SSH
-
Nunca modifiques los ipsets del script con `ipset flush` a menos que entiendas las consecuencias
-
El comando `flush` pide confirmación antes de limpiar todas las IPs bloqueadas
Seguridad del Panel
-
La API se ejecuta como `www-data` con acceso sudo limitado a `ipset` e `iptables` via `/etc/sudoers.d/sentinela`
-
La API valida el formato de la IP antes de ejecutar comandos
-
Propietario de los archivos del panel: `root:www-data` con permisos 750
Desarrollo
Probando cambios
# 1. Editar archivos en /root/sentinela/
nano /root/sentinela/lib/common.sh
# 2. Sincronizar al directorio de instalación
cp /root/sentinela/lib/common.sh /usr/local/sentinela/lib/common.sh
# 3. Probar sintaxis
bash -n /usr/local/sentinela/lib/common.sh
# 4. Probar el comando
sentinela apply
Ejecutar sin instalar
El CLI puede ejecutarse directamente desde el directorio fuente:
export SENTINELA_DIR=/root/sentinela
export SENTINELA_CONFIG=/root/sentinela/config.conf
bash /root/sentinela/cli/sentinela.sh status
Depuración de patrones IDS
Para probar la detección SQLi con una línea de log personalizada:
echo 'GET /?id=1%27%20UNION%20SELECT%201,2,3-- HTTP/1.1' >> /tmp/test.log
sed -i 's|IDS_APACHE_LOG=.*|IDS_APACHE_LOG=/tmp/test.log|' /etc/sentinela/config.conf
sentinela scan
Solución de Problemas
El firewall bloquea todo (sin acceso)
Si pierdes el acceso SSH:
# Desde la consola o gestión fuera de banda:
sentinela flush
# o
systemctl stop sentinela
El servicio systemd falla al iniciar
journalctl -u sentinela.service --no-pager -l
# Causa más común: variable SSH_CLIENT sin valor
# Solución: asegurarse de usar ${SSH_CLIENT:-} con sintaxis de valor por defecto
Las alertas de Telegram no se envían
sentinela telegram-test
# Revisar /var/log/sentinela/sentinela.log para errores
# Verificar TELEGRAM_BOT_TOKEN y TELEGRAM_CHAT_ID en config.conf
# Asegurar que jq está instalado: apt-get install -y jq
El panel no muestra datos
# Revisar el log de errores de Apache
tail -50 /var/log/apache2/error.log
# Verificar que www-data tiene acceso sudo
sudo -u www-data sudo -n ipset list SENTINELA_BLACKLIST
# Verificar que dashboard.json existe
cat /var/log/sentinela/dashboard.json
Desinstalación
sentinela uninstall
Esto elimina:
- Cadenas de iptables (SENTINELA_INPUT, SENTINELA_NEW)
- Todos los ipsets
- Servicio systemd
- Tareas cron
- /usr/local/sentinela/
- /usr/local/bin/sentinela
- Logs y backups (pide confirmación)
No elimina:
- Configuración de Apache
- Bases de datos GeoIP
- Paquetes (iptables, ipset, etc.)
- /etc/sentinela/config.conf (se respalda como /etc/sentinela/config.conf.uninstalled)
Licencia
MIT
Sentinela ? porque tu servidor merece algo mejor que una política iptables por defecto.
|