NetIX WAF Security
1.8K
Web Application Firewall con Nginx, ModSecurity + OWASP CRS, GeoIP2, ZeroTier y API REST de administración.
| Componente | Descripción |
|---|---|
| Nginx 1.30.2 | Con módulos dinámicos ModSecurity, GeoIP2, headers-more |
| ModSecurity v3 | WAF engine con OWASP CRS v4 (844+ reglas) |
| GeoIP2 | Filtrado de tráfico por país (MaxMind GeoLite2) |
| netix_modsec | Motor de puntuación de amenazas con bloqueo automático vía ipset/iptables |
| waf-api | API REST en Go para administrar toda la configuración (puerto 10000) |
| ZeroTier | Red P2P para gestión remota segura |
| certbot | Certificados SSL automáticos con Let's Encrypt + auto-renovación |
| Error Pages | Página de error empresarial con tema auto dark/light |
| Antivirus | Análisis de archivos enviados vía POST,PUT,PATCH |
docker run -d \
--name netix-waf \
--network host \
--privileged \
--restart unless-stopped \
--pid host \
-e WAF_API_KEY="$(openssl rand -hex 16)" \
-v letsencrypt:/etc/letsencrypt \
-v waf-data:/etc/waf-api \
-v /var/log/nginx:/var/log/nginx \
firebotco/netix-waf:latest
# docker-compose.yml
services:
netix-waf:
image: firebotco/netix-waf:latest
container_name: netix-waf
network_mode: host
privileged: true
restart: unless-stopped
pid: host
environment:
- WAF_API_KEY=${WAF_API_KEY:-00000000000000000000000000000000}
volumes:
- letsencrypt:/etc/letsencrypt
- waf-data:/etc/waf-api
- /var/log/nginx:/var/log/nginx
volumes:
letsencrypt:
waf-data:
# Con API key personalizada
WAF_API_KEY="ea4f6eeba6b9dd8d19c98a1e0a607488" docker-compose up -d
# O sin variable (usa default)
docker-compose up -d
curl -fsSL https://distro.netix.app/install.sh | sudo bash
| Puerto | Servicio |
|---|---|
| 80 | nginx HTTP |
| 443 | nginx HTTPS |
| 10000 | waf-api REST |
Base URL: http://<host>:10000/api/v1
Auth: Header x-api-key: <32-char-hex-key> (configurable en /etc/waf-api/config.yaml)
Documentación completa: GET /api/v1/openapi.yml (importable en Postman, Insomnia, etc.)
| Recurso | Endpoints |
|---|---|
| GeoIP Countries | GET/POST /geoip/countries, GET/PUT/DELETE /geoip/countries/{code} |
| Bot Rules | GET/POST /bots/rules, GET/PUT/DELETE /bots/rules/{id} |
| Rate Limit | GET/POST /ratelimit/zones, GET/PUT/DELETE /ratelimit/zones/{id} |
| Trusted IPs | GET/POST /trusted-ips, DELETE /trusted-ips/{id} |
| ModSecurity Rules | GET/POST /modsec/rules, GET/PUT/DELETE /modsec/rules/{id} |
| CORS Origins | GET/POST /cors/origins, GET/PUT/DELETE /cors/origins/{id} |
| Blacklist | GET/POST /blacklist, DELETE /blacklist/{id} |
| Domains | GET/POST /domains, GET/PUT/DELETE /domains/{domain} |
| Domain Locations | GET/POST /domains/{domain}/locations, GET/PUT/DELETE /domains/{domain}/locations/{id} |
| SSL Certificates | POST /domains/{domain}/ssl, POST /domains/{domain}/ssl/renew, POST /ssl/renew-all |
| ZeroTier | GET/POST /zerotier/networks, GET/PUT/DELETE /zerotier/networks/{id} |
| Metrics | GET /metrics |
| Stats | GET /stats, GET /stats/top-attackers |
# Ver info del API
curl http://localhost:10000/api/v1/
# Listar países permitidos
curl -H "x-api-key: YOUR_KEY" http://localhost:10000/api/v1/geoip/countries
# Crear un dominio proxy inverso
curl -X POST -H "x-api-key: YOUR_KEY" -H "Content-Type: application/json" \
-d '{"domain":"mi.app.com","backend_ip":"127.0.0.1","backend_port":8080}' \
http://localhost:10000/api/v1/domains
# Provisionar SSL
curl -X POST -H "x-api-key: YOUR_KEY" \
http://localhost:10000/api/v1/domains/mi.app.com/ssl
# Ver métricas del sistema
curl -H "x-api-key: YOUR_KEY" http://localhost:10000/api/v1/metrics
# Agregar un location estático al dominio
curl -X POST -H "x-api-key: YOUR_KEY" -H "Content-Type: application/json" \
-d '{"path":"/assets","location_type":"static","root_path":"/var/www/static"}' \
http://localhost:10000/api/v1/domains/mi.app.com/locations
# Unirse a una red ZeroTier
curl -X POST -H "x-api-key: YOUR_KEY" -H "Content-Type: application/json" \
-d '{"network_id":"952c4ef89420eb51","name":"NetIX Security"}' \
http://localhost:10000/api/v1/zerotier/networks
El WAF incluye protección multi-capa:
| Capa | Tecnología |
|---|---|
| WAF | ModSecurity v3 + OWASP CRS v4 — 844 reglas contra SQLi, XSS, RCE, LFI/RFI |
| Bots | Detección por User-Agent (21 reglas) |
| Rate Limit | Límite de peticiones y conexiones por IP (4 zonas) |
| GeoIP | Bloqueo por país (23 países configurados) |
| Custom Rules | 39 reglas ModSecurity para DSpace, Koha, OJS, OMP |
| CORS | Control de orígenes permitidos |
| IP Reputation | Scoring automático con bloqueo permanente/temporal |
| Error Pages | Página de error personalizada con tema auto dark/light, mensajes en español |
| Domain Locations | Múltiples locations por dominio (proxy inverso + static files) |
| SSL Auto-Renewal | Renovación automática de certificados cada 75 días vía certbot |
| GeoIP2 Direct | Consulta directa a base de datos GeoLite2-Country.mmdb vía mmdblookup |
El motor de puntuación incluye 3 fases de protección contra falsos positivos:
| Fase | Protección | Detalle |
|---|---|---|
| 1 | Critical Rule suavizada | 1er hit → TEMP, 2do hit → PERM. +60 rangos CDN/Cloud nunca bloqueados |
| 2 | Time-decay + diferenciación | Eventos antiguos pesan menos. Reglas de protocolo 5pts, ataque 15pts. Cap por detector |
| 3 | Reputación + país | Historial SQLite acelera reincidentes. IPs de países bloqueados +20 base. IPs privadas sin DDoS |
El template de dominio incluye optimizaciones de seguridad y rendimiento:
| Categoría | Mejoras |
|---|---|
| CORS/Seguridad | CORS fuera de if, limit_except métodos, proxy_hide_header |
| Proxy | X-Forwarded-Host/Port, proxy_redirect, proxy_cookie_domain |
| Performance | tcp_nodelay, proxy_buffer_size 128k, proxy_socket_keepalive |
| Timeouts | proxy_next_upstream_tries 2, proxy_next_upstream_timeout 10s |
| WebSocket | location /ws/ con timeout 3600s |
| SSL | ssl_ecdh_curve X25519:prime256v1 sin ML-KEM experimental |
La base de datos usa WAL mode + busy timeout para evitar bloqueos bajo escritura concurrente:
| Parámetro | Valor | Propósito |
|---|---|---|
_journal_mode | WAL | Lectores y escritores no se bloquean entre sí |
_busy_timeout | 5000ms | Espera 5s si hay contención de escritura |
_synchronous | NORMAL | Escritura más rápida |
_cache_size | -20000 | 20MB de caché en RAM |
Al iniciar por primera vez, la BD se precarga desde los archivos de configuración:
| Recurso | Entidades | Archivo origen |
|---|---|---|
| GeoIP | 23 países | geoip_access.conf |
| Bot Rules | 21 reglas | bad_bots.conf |
| Rate Limit | 4 zonas | limit_req.conf |
| Trusted IPs | 1 CIDR | trusted-ips.list |
| ModSec Rules | 39 reglas | custom_rules.conf |
| CORS | 1 origen | cors.conf |
| ZeroTier | 1 red | 952c4ef89420eb51 |
Con network_mode: host, el contenedor comparte la red del host:
127.0.0.1 dentro del contenedor = 127.0.0.1 del hostproxy_pass http://127.0.0.1:8080 alcanza servicios locales del hostproxy_pass http://192.168.1.100:3000 alcanza cualquier IP de la LAN| Volumen | Ruta | Contenido |
|---|---|---|
letsencrypt | /etc/letsencrypt | Certificados SSL |
waf-data | /etc/waf-api | Base de datos SQLite3 (configuración, IPs, dominios) |
| bind mount | /var/log/nginx | Logs de acceso y error |
El contenedor necesita:
--network host — acceso a la red real del host para iptables y proxy inverso--privileged — modificar iptables, crear ipsets, interfaces ZeroTier| Variable | Default | Descripción |
|---|---|---|
WAF_API_CONFIG | /etc/waf-api/config.yaml | Ruta al archivo de configuración del API |
WAF_API_KEY | (config.yaml) | API key de 32 caracteres hex. Generar con openssl rand -hex 16. Se inyecta en config.yaml al iniciar el contenedor |
Desarrollado por: Alexander Rubio Cáceres
Email: [email protected]
WhatsApp: +57 311 508 1919
Content type
Image
Digest
sha256:a8ad18323…
Size
236.4 MB
Last updated
4 months ago
docker pull firebotco/netix-waf