
maltrail v3.2
Sistema de detección de tráfico malicioso en tiempo real que utiliza listas negras públicas, trazas estáticas de malware y análisis heurístico para identificar amenazas en el tráfico DNS, HTTP e IP.

Maltrail
Maltrail es un sistema de detección de tráfico de red que identifica la comunicación con infraestructura maliciosa conocida y reporta anomalías de tráfico seleccionadas. Compara dominios, URLs, direcciones IP, pares IP:port y valores de User-Agent observados en la red contra un conjunto de indicadores llamados trails.
Una detección se registra como un único evento que contiene el origen, el destino, el protocolo, el trail coincidente, la clasificación y la fuente del trail:```text "2026-08-07 09:14:22.117034" gw 10.13.13.2 57809 1.1.1.1 53 UDP DNS malware.bakewithdavid.com "asyncrat (malware)" (static)
Maltrail está diseñado para la monitorización de red basada en indicadores. Sus detecciones heurísticas complementan
la coincidencia de trails, pero no sustituyen a la telemetría de endpoint ni a un sistema de prevención de intrusiones
de propósito general.
## Características
- Una compilación completa de trails que combina más de 3.000 archivos estáticos incluidos, 42 integraciones de feeds públicos
y trails opcionales proporcionados por el operador.
- Un sensor multihilo en Rust que utiliza libpcap, con workers de captura opcionales de Linux `PACKET_FANOUT`.
- Un servidor en Python que proporciona la interfaz de informes, la ingesta de eventos y la API HTTP.
- Trails personalizados y listas blancas en texto plano que pueden revisarse y controlarse por versiones.
- Heurísticas para escaneos, agotamiento de DNS, búsquedas similares a DGA, descargas sospechosas, sondeos de proxy,
valores de User-Agent sospechosos y actividad de red relacionada.
- Registro local de eventos, registro remoto de Maltrail, CEF sobre syslog y salida JSON de Logstash.
- Validación del despliegue con `maltrail-sensor -T` y métricas opcionales de Prometheus.
## Contenido
- [Arquitectura](#architecture)
- [Interfaz de informes](#reporting-interface)
- [Rendimiento](#performance)
- [Instalación](#installation)
- [Instalador](#installer)
- [Compilación desde el código fuente](#building-from-source)
- [Systemd](#systemd)
- [Docker](#docker)
- [Configuración](#configuration)
- [Trails](#trails)
- [Eventos y API](#events-and-api)
- [Operaciones](#operations)
- [Monitorización](#monitoring)
- [Retención de eventos](#event-retention)
- [Documentación](#documentation)
- [Contribuir](#contributing)
- [Proyecto](#project)
- [Licencia](#license)
- [Mantenedores](#maintainers)
- [Patrocinadores](#sponsors)
- [Presentaciones y publicaciones](#presentations-and-publications)
- [Lista negra derivada](#derived-blacklist)
- [Integraciones de terceros](#third-party-integrations)
- [Agradecimientos](#acknowledgements)
## Arquitectura
Maltrail consta de dos procesos independientes que pueden ejecutarse en el mismo host o en hosts separados:```text
┌──────────┐ events (UDP or file) ┌──────────┐
│ sensor │ ───────────────────────► │ server │ ◄── browser
└──────────┘ └──────────┘
Rust Python
libpcap + PACKET_FANOUT reporting UI + API
trail matching + heuristics
El sensor captura el tráfico, realiza la coincidencia de rastros y el análisis heurístico, y produce eventos.
Puede escribir eventos localmente (LOG_DIR), enviarlos a un servidor Maltrail remoto (LOG_SERVER), o hacer
ambas cosas. También puede emitir CEF sobre syslog (SYSLOG_SERVER) y JSON a Logstash
(LOGSTASH_SERVER).
El servidor recibe y almacena eventos remotos, sirve registros de eventos disponibles localmente, y proporciona la interfaz web y la API.
Interfaz de informes
Maltrail incluye una interfaz de informes basada en navegador para explorar el tráfico detectado, con actualizaciones en vivo, búsqueda por campos, búsqueda retrospectiva, vistas geográficas, triaje, vistas guardadas y exportación.

La interfaz es servida por server.py en HTTP_ADDRESS:HTTP_PORT. Es JavaScript puro con una
única dependencia de terceros en tiempo de ejecución (PapaParse, para el análisis de CSV) y sin paso de compilación. Se
visualiza un día a la vez, seleccionado con un selector de fecha que también funciona como una cuadrícula de densidad de eventos sobre los
registros diarios disponibles. Los eventos se transmiten desde /events y se agregan en el navegador en
amenazas — una fila por cada (source, trail) distinto — mostradas en una cuadrícula ordenable con un panel de detalles.
| Característica | Notas |
|---|---|
| Modo en vivo | Los eventos añadidos se envían a través de Server-Sent Events (/live) y se fusionan en la vista actual. Recurre al sondeo de rangos de bytes del registro diario cuando SSE no está disponible, o para sesiones que el flujo no puede servir. Las nuevas amenazas de alta severidad pueden generar una notificación de escritorio y una alerta sonora; ambas se pueden silenciar |
| Búsqueda | Tokens con ámbito de campo (src: dst: port: proto: type: trail: info: family: tag: uid: sev: dir: status:; family:interlock incluye interlock-1/-2, los fragmentos en los que llega dividido un volcado de feed) combinados con espacio como AND, - para excluir, comodines *, CIDR (src:10.0.0.0/8), y rangos numéricos y comparaciones (port:>1024, count:>=100). Los filtros activos aparecen como chips eliminables |
| Búsqueda retrospectiva | Busca en todos los registros diarios retenidos un indicador (/hunt), no solo en el día en vista. Limitada por un límite de días, un presupuesto de tiempo real y un tope de muestras; un día que el presupuesto interrumpió se informa por separado de los días completados en lugar de contarse como un total finalizado. Un índice sidecar por día (LOG_DIR/index/, USE_EVENT_INDEX) permite que el barrido omita cada línea que no coincida y hace que /counts sea exacto |
| Mapa mundial | Densidad de eventos por país para el día seleccionado (/geo), situando el endpoint externo de cada evento. Los eventos que no se pueden atribuir a una dirección externa se informan como no mapeados en lugar de adivinarse. Establezca HOME_LAT / HOME_LON para dibujar arcos de origen |
| Triaje | Estado por amenaza (nueva / en investigación / resuelta / falso positivo), notas de texto libre, etiquetas y ocultación. Las reglas de lista blanca y los pivotes OSINT están disponibles desde el menú contextual de la fila |
| Vistas guardadas | Presets de filtros con nombre |
| Exportación | La vista filtrada actual como CSV, JSON o indicadores defanged |
| Apariencia | Temas oscuro y claro, y pasos discretos de tamaño de texto |
El estado de triaje, las vistas guardadas, las etiquetas y la configuración de apariencia se almacenan en el navegador
(localStorage), no en el servidor: son por navegador y por origen, y no se comparten
entre analistas.
Las sesiones restringidas con un filtro de red solo ven eventos de sus propias redes, y esa restricción se aplica a los endpoints de recuentos, mapa y lista negra, así como a la lista de eventos.
El enriquecimiento de país y ASN para direcciones individuales se consulta en stat.ripe.net por el
servidor, que almacena en caché los resultados y los sirve a la interfaz desde su propio endpoint /ripe;
el navegador no habla con nada más que Maltrail. Establezca DISABLE_RIPE_LOOKUPS para desactivar
por completo las consultas salientes. Sin ellas — o en un host sin acceso a internet — las banderas provienen
de la tabla RIR local en su lugar y todo lo demás en la interfaz funciona sin conexión.
Rendimiento
El rendimiento depende del procesador, la composición del tráfico, el tamaño del conjunto de rastros, el controlador de captura y la interfaz de red. Las cifras a continuación miden la ruta de procesamiento de paquetes del sensor de forma aislada; no son mediciones de captura en vivo de extremo a extremo.
Mediciones representativas en un AMD Ryzen 7 PRO 4750U con heurísticas habilitadas y un conjunto de rastros de 1,5 millones de filas:
| Tráfico | Tiempo por paquete |
|---|---|
| ICMP echo, 58 bytes | 101 ns |
| TCP SYN, 70 bytes | 302 ns |
| TLS masivo, 1.473 bytes | 402 ns |
| Consulta DNS con caché caliente, 93 bytes | 452 ns |
| Tráfico mixto, promedio de 866 bytes | 552 ns |
| Solicitud HTTP, 169 bytes | 602 ns |
| Consulta DNS con un nombre único, 93 bytes | 1.102 ns |
Las ejecuciones de comparación sin conexión utilizando la misma captura generada, configuración y conjunto de rastros midieron un
costo por paquete en estado estacionario de 14 a 37 veces menor que el sensor Python retirado en los sistemas probados.
Esas cifras separan el tiempo de todo el proceso del estado estacionario, porque la carga de rastros domina una
reproducción corta. La detección en sí se verifica por separado, mediante el corpus de 42 casos en
sensor/tests/replay.rs.
Mídalo en el sistema objetivo con:```bash cargo bench --manifest-path sensor/Cargo.toml --bench hotpath
Un worker de captura se utiliza por defecto. Workers adicionales pueden aumentar la capacidad de captura, pero el hashing de flujos de Linux divide el estado por origen entre workers y, por lo tanto, reduce la sensibilidad de algunas heurísticas de escaneo. En la prueba documentada, el 91% de las alertas heurísticas con un solo worker se mantuvieron con dos workers, el 86% con cuatro y el 65% con ocho. La coincidencia exacta de rastros no cambió. Aumente `CAPTURE_FANOUT` solo cuando las métricas de pérdida de captura muestren que es necesario.
La metodología de benchmark, los resultados de hardware, la salida del profiler, las mediciones de memoria y las comprobaciones de fanout en vivo están documentadas en [`sensor/docs/REPORT.md`](https://github.com/stamparm/maltrail/blob/master/sensor/docs/REPORT.md).
## Instalación
### Instalador
El instalador está verificado en doce distribuciones de Linux — Debian, Ubuntu, Fedora, Rocky, AlmaLinux, Arch, openSUSE Leap y Tumbleweed, y Alpine — además de FreeBSD y macOS, en cada versión, con el resultado completo registrado en [`docs/compat`](https://github.com/stamparm/maltrail/blob/master/docs/compat). Raspberry Pi OS y otros sistemas ARM de 64 bits utilizan la compilación `aarch64`; ARM de 32 bits no tiene sensor precompilado y debe compilarlo desde el código fuente.```bash
curl -fsSL https://raw.githubusercontent.com/stamparm/maltrail/master/install.sh | sudo sh
Instala las dependencias, crea una copia de trabajo gestionada en /opt/maltrail, verifica la suma de comprobación
del sensor precompilado, crea una cuenta maltrail sin privilegios, instala las unidades de systemd, prepara
los directorios de logs y de estado, e inicia el sensor y el servidor. Volver a ejecutar el instalador actualiza
la copia de trabajo gestionada.
Revisa el script antes de ejecutarlo con privilegios elevados. Desde una copia de trabajo existente, la ejecución en seco muestra los comandos sin modificar el sistema:```bash sh install.sh --dry-run
Opciones comunes del instalador:```bash
sh install.sh --role sensor # Install only the sensor
sh install.sh --ref 3.1.2 # Install a release tag instead of master
sh install.sh --no-service # Install without changing systemd
sh install.sh --dry-run # Print commands without applying them
sh install.sh --uninstall # Remove the managed installation; keep logs and state
El panel de control está disponible en http://127.0.0.1:8338 después de la instalación. Ten en cuenta que el HTTP_ADDRESS incluido es 0.0.0.0, por lo que es accesible en todas las interfaces, no solo en loopback — y las credenciales predeterminadas son admin / changeme!. Cambia USERS y establece HTTP_ADDRESS en 127.0.0.1 (o coloca el servidor detrás de un proxy inverso con TLS), antes de que el host esté en una red no confiable.
La compilación inicial del trail puede tardar varios minutos. El sensor no detecta coincidencias de trail hasta que haya un conjunto de trails válido disponible. La unidad systemd ejecuta la validación -T del sensor antes del inicio, de modo que la falta de privilegios, un directorio de logs no escribible o un conjunto de trails inválido provoquen que el inicio falle de forma visible.
El arnés de pruebas del instalador cubre doce distribuciones, y "se instaló" no es la aserción: en cada una se inicia el servidor y se le solicita /ping, se pide al sensor que se valide a sí mismo con -T, se comprueban las unidades en busca de rutas que resuelvan, se vuelve a ejecutar el instalador para demostrar que una actualización conserva la configuración del operador, y se ejecuta --uninstall. Cada resultado se registra por plataforma en docs/compat, y la página allí se genera a partir de esas filas en lugar de escribirse a mano.
Alpine y otros sistemas musl obtienen una compilación del sensor -musl. Antes se les decía que el binario precompilado estaba enlazado con glibc y que compilaran el suyo propio; el sensor se compila y se ejecuta de forma nativa en musl, por lo que eso era un artefacto faltante en lugar de una limitación de la plataforma.
Compilación desde el código fuente
El sensor requiere Rust 1.74 o posterior, los encabezados de desarrollo de libpcap y las herramientas de capacidades del sistema. El servidor y el actualizador de trails requieren Python 3.6 o posterior.
Instala los paquetes de la distribución:```bash
Debian / Ubuntu / Raspberry Pi OS
sudo apt-get install cargo libpcap-dev libcap2-bin python3
RHEL / Fedora
sudo dnf install cargo libpcap-devel libcap python3
openSUSE / SLES
sudo zypper install cargo rust libpcap-devel libcap-progs python311
Luego construye y valida el sensor:```bash
git clone --depth 1 https://github.com/stamparm/maltrail.git
cd maltrail
cargo build --release --manifest-path sensor/Cargo.toml
sudo setcap cap_net_raw,cap_net_admin=eip \
sensor/target/release/maltrail-sensor
sudo install -d -o "$USER" -g "$(id -gn)" -m 750 /var/log/maltrail
sensor/target/release/maltrail-sensor -T
sensor/target/release/maltrail-sensor
Inicie el servidor en otra terminal o en otro host:```bash python3 server.py
Los binarios precompilados del sensor se adjuntan a las versiones actuales con sumas de verificación SHA-256: Linux `x86_64`
y `aarch64` tanto para glibc como para musl, macOS en Apple silicon e Intel, FreeBSD `amd64`, y
Windows `x86_64`.
Las compilaciones para glibc enlazan libpcap de forma estática y tienen como objetivo glibc 2.28, por lo que la biblioteca C es lo único que
necesitan — nada que instalar, tanto en RHEL 8+, Debian 10+, Ubuntu 18.04+ como en Leap 15.x. Las compilaciones
para musl son totalmente estáticas, por lo que Alpine no necesita nada en absoluto. La compilación para Windows es de 64 bits y necesita Windows 10 o posterior además de
[Npcap](https://npcap.com) instalado antes de que pueda iniciarse — `wpcap.dll` es una dependencia de tiempo de carga,
por lo que sin él el cargador rechaza el ejecutable en lugar de fallar en la captura. El archivo también lo dice.
Los binarios de **3.1.1 y anteriores** no lo hacían: enlazaban libpcap de forma dinámica y la solicitaban por
el nombre que usa su host de compilación AlmaLinux. Debian y Ubuntu distribuyen la biblioteca idéntica bajo el
nombre más antiguo `libpcap.so.0.8`, por lo que esos binarios se detienen antes de arrancar —```
./maltrail-sensor: error while loading shared libraries: libpcap.so.1: cannot open shared object file
— en una máquina que tenga libpcap instalado. install.sh enlaza el nombre faltante por ti. Manualmente:```bash
adjust the directory for your architecture: aarch64-linux-gnu, or /usr/lib64 on RPM distributions
sudo ln -sf /usr/lib/x86_64-linux-gnu/libpcap.so.0.8 /usr/lib/x86_64-linux-gnu/libpcap.so.1 sudo ldconfig
### Systemd
Las unidades proporcionadas en `packaging/systemd/` ejecutan ambos procesos como el
usuario sin privilegios `maltrail`. Systemd crea `/var/log/maltrail` y `/var/lib/maltrail`, restringe
el acceso al sistema de archivos y otorga al sensor `CAP_NET_RAW` y `CAP_NET_ADMIN`.
El instalador configura estas unidades automáticamente. Para una instalación desde código fuente existente, siga
el procedimiento manual del servicio en [`sensor/docs/INSTALL.md`](https://github.com/stamparm/maltrail/blob/master/sensor/docs/INSTALL.md).
Compruebe el estado del servicio y los registros con:```bash
systemctl status maltrail-sensor maltrail-server
journalctl -u maltrail-sensor -f
Docker
Inicie el despliegue de Compose proporcionado con:```bash docker compose -f docker/docker-compose.yml up -d
La configuración del contenedor, el almacenamiento, los privilegios y las comprobaciones de estado se documentan en
[`docker/README.md`](https://github.com/stamparm/maltrail/blob/master/docker/README.md).
## Configuración
Maltrail lee `maltrail.conf`, que contiene ajustes separados de `[Sensor]` y `[Server]`. El
instalador coloca la configuración gestionada en `/etc/maltrail.conf`.
Las opciones de sensor de uso frecuente incluyen:
| Opción | Propósito |
| --- | --- |
| `MONITOR_INTERFACE` | Interfaz o interfaces de captura; `any` selecciona todas las interfaces compatibles |
| `CAPTURE_FILTER` | Filtro de captura BPF |
| `CAPTURE_FANOUT` | Número de sockets de captura de Linux; por defecto uno |
| `CAPTURE_WORKERS` | Workers de captura, un socket cada uno; por defecto `CAPTURE_FANOUT`, por lo que uno a menos que se establezca cualquiera de los dos |
| `LOG_DIR` | Directorio local del registro de eventos |
| `TRAILS_FILE` | Base de datos de trails generada |
| `LOG_SERVER` | Servidor remoto de eventos de Maltrail |
| `SYSLOG_SERVER` | Destino o destinos de syslog CEF |
| `LOGSTASH_SERVER` | Destino o destinos de Logstash JSON |
| `STATS_ADDRESS` | Escucha de métricas de Prometheus; deshabilitado a menos que se configure |
| `UPDATE_PERIOD` | Intervalo de actualización de trails |
| `STATIC_TRAILS_URL` | De dónde se obtiene el conjunto de trails estáticos ensamblado; fíjalo a una versión con fecha para controlar cuándo llega contenido nuevo |
| `USER_WHITELIST` | Indicadores gestionados por el operador que no deberían generar alertas |
| `CUSTOM_TRAILS_DIR` | Directorio de trails gestionado por el operador |
| `STATIC_TRAILS_DIR` | Checkout opcional del repositorio de trails; solo se usa para mostrar la cita de origen de un trail en la interfaz |
`PROCESS_COUNT` se aplica al sensor Python retirado y al limitador de registro de eventos heredado; **no**
establece el número de workers del sensor Rust. Configura los workers de captura con `CAPTURE_FANOUT` o
`CAPTURE_WORKERS` en su lugar.
Ejecuta la comprobación de despliegue después de cambiar la configuración:```bash
sensor/target/release/maltrail-sensor -T
La comprobación valida la configuración, los trails, las entradas de la lista blanca, el filtro de captura, los privilegios, el almacenamiento de registros, el soporte de actualizaciones y la configuración de los workers. Una comprobación exitosa incluye recuentos positivos de trails y de la lista blanca en lugar de limitarse a confirmar que los archivos existen.
Trails
Un trail es un indicador —un dominio, URL, dirección IP, par IP:port, User-Agent, huella JA3/JA4 o hash de certificado— junto con lo que significa y de dónde proviene. El actualizador fusiona cuatro fuentes en TRAILS_FILE, en este orden:
| fuente | de dónde proviene |
|---|---|
| Feeds | feeds/*.py, obtenidos directamente por tu despliegue desde cada publicador |
| Custom | CUSTOM_TRAILS_DIR y CUSTOM_TRAILS_URL, tus propios indicadores |
| Static | el conjunto ensamblado de stamparm/trails, obtenido desde STATIC_TRAILS_URL; con licencia separada |
| Engine lists | data/mass_scanner*.txt, incluidos aquí porque cambian con poca frecuencia |
Los trails estáticos viven en su propio repositorio. El contenido de detección cambia decenas de veces al día; el motor no, y mantenerlos juntos significaba que actualizar la detección requería descargar código y hacía inutilizable el historial de este repositorio. STATIC_TRAILS_URL apunta al conjunto publicado más reciente:```text
STATIC_TRAILS_URL https://github.com/stamparm/trails/releases/latest/download/trails.csv.gz
Apúntalo a una versión específica `content-YYYYMMDD-HHMM` para fijar una versión, de modo que una publicación defectuosa no sea inmediatamente global. El conjunto se almacena en caché junto a `TRAILS_FILE`, que es lo que hace posible una reconstrucción sin conexión o en un entorno aislado; el `sha256` publicado se verifica antes de la descarga, por lo que un despliegue que se actualiza con más frecuencia de la que cambia el contenido transfiere 65 bytes en lugar de 11 MB, y una carga útil que no coincide con su digest se rechaza en favor de la caché.
`update_trails()` publica un nuevo `TRAILS_FILE` de forma atómica y solo tras una compilación exitosa. Los feeds que no devuelven nada se reportan por nombre, de modo que un despliegue no depende silenciosamente de una fuente que se ha retirado discretamente.
Añade tus propios indicadores en `CUSTOM_TRAILS_DIR`, y cualquier cosa que nunca deba generar un evento en `USER_WHITELIST`. Mantén ambos fuera del directorio de instalación para que una actualización no pueda sobrescribirlos.
Las contribuciones de trails estáticos van a [stamparm/trails](https://github.com/stamparm/trails); los nuevos feeds van aquí. En cualquier caso, un indicador necesita una clasificación y una fuente que alguien pueda verificar — consulta [Contributing](#contributing).
## Events and API
Maltrail registra un evento separado por espacios en blanco por cada detección, usando comillas CSV cuando un valor contiene espacios:```text
"<time>" <sensor> <src_ip> <src_port> <dst_ip> <dst_port> <proto> <type> <trail> "<info>" <reference>
El campo type identifica qué coincidió, incluyendo DNS, IP, IPORT, URL, PATH, HTTP,
UA, PORT, CERT, JA3 y JA4. El campo info contiene la clasificación del rastro, y
reference identifica la lista estática, el feed, la fuente personalizada o la heurística que lo produjo. Los
tipos JA3/JA4 se activan con las huellas TLS del cliente: la pila TLS de un implante sobrevive a cada
rotación de dirección y dominio, por lo que su hash de hello sigue coincidiendo después de que todo lo demás se haya quemado
(publicado por el feed JA3 de abuse.ch SSLBL).
Búsqueda de indicadores
Use /check para consultar un dominio, una dirección IP o una URL:```bash
curl 'http://127.0.0.1:8338/check?q=www.sub.evil.example'
| `-s` | `--server` | Server URL (default: `http://localhost:8080`) |
| `-t` | `--token` | Authentication token |
| `-o` | `--output` | Output file path |
| `-f` | `--format` | Output format: `json`, `yaml`, `table` |
| `-v` | `--verbose` | Enable verbose logging |
| `-q` | `--quiet` | Suppress non-error output |
| `-h` | `--help` | Show help message |
| `-V` | `--version` | Show version information |
### Examples
```bash
# Basic scan
scanner scan --target example.com
# Scan with custom output format
scanner scan --target example.com --format json --output results.json
# Authenticated scan
scanner scan --target example.com --token "your-api-token"
# Verbose mode
scanner scan --target example.com --verbose
Configuration
The scanner can be configured using a configuration file or environment variables.
Configuration File
Create a config.yaml file in the current directory:
server:
url: "http://localhost:8080"
timeout: 30
scan:
threads: 10
timeout: 60
user_agent: "Scanner/1.0"
output:
format: "json"
verbose: false
Environment Variables
| Variable | Description | Default |
|---|---|---|
SCANNER_SERVER_URL | Server URL | http://localhost:8080 |
SCANNER_TOKEN | Authentication token | - |
SCANNER_THREADS | Number of threads | 10 |
SCANNER_TIMEOUT | Request timeout (seconds) | 30 |
SCANNER_OUTPUT_FORMAT | Output format | json |
SCANNER_VERBOSE | Enable verbose logging | false |
API Reference
Authentication
All API requests require an authentication token passed in the Authorization header:
Authorization: Bearer <token>
Endpoints
GET /api/v1/health
Returns the health status of the server.
Response:
{
"status": "healthy",
"version": "1.0.0",
"uptime": 3600
}
POST /api/v1/scan
Initiates a new scan.
Request Body:
{
"target": "example.com",
"options": {
"threads": 10,
"timeout": 60
}
}
Response:
{
"scan_id": "abc123",
"status": "running",
"created_at": "2024-01-15T10:30:00Z"
}
GET /api/v1/scan/{scan_id}
Retrieves the status and results of a scan.
Response:
{
"scan_id": "abc123",
"status": "completed",
"results": {
"vulnerabilities": [],
"findings": []
}
}
DELETE /api/v1/scan/{scan_id}
Cancels or deletes a scan.
Response:
{
"message": "Scan deleted successfully"
}
Troubleshooting
Common Issues
Connection refused:
Error: dial tcp 127.0.0.1:8080: connect: connection refused
Ensure the server is running and the URL is correct.
Authentication failed:
Error: 401 Unauthorized
Verify your token is valid and not expired.
Timeout errors:
Error: context deadline exceeded
Increase the timeout value or check network connectivity.
Debug Mode
Enable debug mode for detailed logging:
scanner scan --target example.com --verbose --debug
Logs
Logs are written to ~/.scanner/logs/ by default. Use the --log-file flag to specify a custom location.
Contributing
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
Development Setup
# Clone the repository
git clone https://github.com/example/scanner.git
cd scanner
# Install dependencies
go mod download
# Build the project
go build -o scanner ./cmd/scanner
# Run tests
go test ./...
Code Style
- Follow standard Go formatting (
gofmt) - Write meaningful commit messages
- Include tests for new features
- Update documentation as needed
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Thanks to all contributors
- Inspired by similar security tools
- Built with Go
Support
- Documentation
- Issue Tracker
- Discussions```json { "query": "www.sub.evil.example", "found": true, "trail": "evil.example", "info": "asyncrat (malware)", "reference": "(static)", "confidence": 100 }
El campo `confidence` (0-100, o `null` cuando no está disponible) indica con qué fuerza respaldan las fuentes el listado: 40 para un único feed, +15 por cada feed adicional que coincida de forma independiente hasta 100, y la puntuación completa para las entradas personalizadas y estáticas del propio operador. Se calcula en el momento de la actualización del trail a partir de la coincidencia de feeds en un sidecar `trails.confidence` junto a `trails.csv`; un servidor que obtiene trails de un `UPDATE_SERVER` no tiene procedencia que puntuar y reporta `null`. Úsalo para priorizar el triaje: un listado de un solo feed con 40 merece una segunda revisión antes de ganarse una regla de firewall.
Una búsqueda de subdominio puede coincidir con su padre listado. Las búsquedas de URL comprueban `host/path` antes de comprobar solo el host. El servidor lee la base de datos de trails mapeada en memoria y observa las actualizaciones de trails sin reiniciarse.
Los trails estáticos públicos y de feeds están disponibles sin autenticación, de forma coherente con el endpoint `/trails` usado por los sensores remotos. Los trails personalizados requieren una sesión autorizada; una búsqueda no autorizada de solo personalizados se reporta como un fallo. Los datos de eventos siguen autenticados.
## Operaciones
### Monitorización
Usa `maltrail-sensor -T` como puerta de despliegue y configuración. La unidad systemd proporcionada lo ejecuta como `ExecStartPre`.
Para confirmar que la detección en sí funciona — no solo que los procesos arrancan — ejecuta:```bash
python3 server.py --detect-test
Reproduce un pcap elaborado de tráfico malicioso emulado (aciertos de trail en una consulta DNS, una IP, un
IP:port, una ruta URL y una cabecera Host, además de las heurísticas de inyección SQL, traversal, RCE, XSS, sonda de proxy,
sinkhole, Host ausente y escaneo de puertos/web/infección) a través del sensor instalado
y verifica que cada detección esperada se dispare. No necesita root, ni interfaz, ni un conjunto de trails propio. Una instalación saludable imprime 20/20 detection(s) fired.
Cuando STATS_ADDRESS está configurado, monitoriza al menos estas métricas de Prometheus:
| Métrica | Significado operativo |
|---|---|
maltrail_up == 0 | No hay ningún worker de captura en ejecución |
maltrail_capture_dropped_total en aumento | El anillo de captura está descartando paquetes |
maltrail_local_log_errors_total en aumento | Se produjeron eventos pero no se pudieron escribir localmente |
maltrail_remote_log_errors_total en aumento | Los eventos no se pudieron entregar a un sink remoto; con DISABLE_LOCAL_LOG_STORAGE se pierden |
maltrail_trail_generation sin avanzar | El conjunto de trails activo no se está refrescando |
maltrail_log_dir_free_bytes | Capacidad restante para el almacenamiento local de eventos |
maltrail_state_saturations_total en aumento | Se alcanzó un límite de estado de una heurística |
maltrail_throttle_evictions_total en aumento | La tabla de limitación de eventos está en su tope, por lo que los eventos se agregan antes de lo configurado |
La saturación de estado afecta a la heurística correspondiente; la coincidencia exacta de trails permanece activa.
Envía SIGHUP o usa systemctl reload maltrail-sensor para solicitar una recarga de trails. Los archivos de trails
actualizados por otro proceso se detectan automáticamente y se publican a los workers sin reiniciar
el sensor.
El almacén observable condensado (USE_CONDENSED_STORAGE, meta.sqlite) da soporte a las vistas de
novedad y retro-hunt del servidor. El índice sidecar del registro de eventos por día (USE_EVENT_INDEX,
LOG_DIR/index/*.sqlite, aproximadamente el doble del tamaño del log en disco) es lo que hace que /counts sea exacto y
/hunt rápido; se mantiene de forma incremental a partir de los propios logs y se puede reconstruir con
server.py --rebuild-index. La compatibilidad con el sensor retirado está documentada en
sensor/docs/COMPATIBILITY.md.
Retención de eventos
Maltrail no rota ni elimina los registros de eventos. Los operadores son responsables de definir la retención, el archivado y la eliminación según los requisitos de almacenamiento y la política organizativa.
Prácticas recomendadas:
- Envía la copia duradera de los eventos a un servidor Maltrail remoto o a un SIEM con
LOG_SERVER,SYSLOG_SERVERoLOGSTASH_SERVER. - Alerta sobre
maltrail_log_dir_free_bytescon suficiente margen para la tasa de eventos esperada. - Rota, archiva o elimina los logs diarios locales usando herramientas externas.
- Mantén sin comprimir en
LOG_DIRlos archivos que necesita la interfaz de informes; archiva los archivos comprimidos en otro lugar.
Cuando el sistema de archivos de logs está lleno, el sensor no puede añadir eventos. Los registros de eventos también pueden contener direcciones IP y dominios que están regulados como datos personales en algunas jurisdicciones; la política de retención debería tener en cuenta los requisitos aplicables.
Tráfico sintético
Para comprobar que tanto la detección como el panel de control siguen funcionando, sin esperar tráfico real:```bash python3 server.py --detect-test # assert every detection fires, then exit python3 server.py --detect-test --keep DIR --serve # ...and keep the events, serving them on :8338
`--keep` también reproduce `sensor/tests/corpus/` en el mismo registro e imprime cuáles de las formas que el panel renderiza de manera diferente tienen un evento detrás, de modo que un icono, color o glifo faltante sea visible en lugar de asumido. Las marcas de tiempo se desplazan para que el día más reciente sea hoy. Se requiere un binario del sensor (`cargo build --release --manifest-path sensor/Cargo.toml`).
Los datos de la demo pública se regeneran a partir de una ejecución de este tipo:```bash
python3 sensor/tools/gen_demo_js.py --from DIR/logs # tops up html/js/demo.js
Documentación
| Documento | Contenido |
|---|---|
sensor/docs/INSTALL.md | Instalación, privilegios, configuración y solución de problemas |
sensor/docs/ARCHITECTURE.md | Funcionamiento interno del sensor y flujo de datos |
sensor/docs/COMPATIBILITY.md | Diferencias deliberadas con el sensor Python retirado |
sensor/docs/REPORT.md | Mediciones, perfiles y resultados de pruebas |
sensor/docs/ROADMAP.md | Trabajo abierto del sensor |
SekuriPy Labs | Notas de ingeniería, benchmarks y análisis |
Contribuir
Las adiciones de trails, el mantenimiento de feeds, los informes de errores, la documentación y las mejoras del sensor son bienvenidos. Los envíos de trails deben incluir una fuente fiable y deben utilizar la clasificación más específica adecuada.
Ejecute las comprobaciones pertinentes antes de enviar código. La puerta completa del sensor es:```bash bash sensor/tools/check.sh
Ejecuta el formateo, Clippy con advertencias denegadas, y las suites de pruebas de depuración y de lanzamiento. Ejecuta la suite del servidor Python con:```bash
bash tests/run.sh python3
La compilación para Windows puede probarse desde Linux, que es donde se han encontrado sus errores:```bash sh sensor/tools/check_windows.sh
Se compila de forma cruzada el sensor con mingw-w64, se extrae la biblioteca de espacio de usuario de Npcap desde su instalador
(un archivo NSIS, por lo que no se instala nada), y se ejecuta el resultado bajo Wine — toda la suite de pruebas,
`-T` contra la configuración incluida, el corpus de pcap comparado byte a byte contra el binario nativo,
y el servidor respondiendo a `/ping` bajo un Python de Windows. La captura en vivo es lo único que
no puede cubrir; eso requiere el controlador del kernel de Npcap y una máquina Windows real. Los requisitos previos son
`gcc-mingw-w64-x86-64`, `wine` y `p7zip-full`.
## Proyecto
### Licencia
**TL;DR:** Maltrail tiene licencia MIT, pero el conjunto de datos Maltrail Trails tiene términos separados. La consulta/referencia independiente de IOC está bien; el uso sistemático de Trails como fuente de inteligencia en un producto o servicio comercial requiere permiso/licencia.
Maltrail se distribuye bajo la Licencia MIT. Consulte [`LICENSE`](https://github.com/stamparm/maltrail/blob/master/LICENSE).
Ese es el motor. El conjunto de trails estático es un trabajo separado bajo términos separados: gratuito para uso
defensivo interno, investigación y enseñanza, pero un producto comercial, servicio, oferta de MSSP o MDR, o un
feed redistribuido necesita una licencia. Un motor MIT no hace que el contenido sea gratuito para vender — consulte
[`LICENSE.md`](https://github.com/stamparm/trails/blob/main/LICENSE.md) en
[stamparm/trails](https://github.com/stamparm/trails) antes de incluirlo en algo por lo que cobre.
### Mantenedores
- Miroslav Stampar ([@stamparm](https://github.com/stamparm))
- Mikhail Kasimov ([@MikhailKasimov](https://github.com/MikhailKasimov))
### Patrocinadores
- [Sansec](https://sansec.io/) (2024–2025)
- [Sansec](https://sansec.io/) (2020–2021)
### Presentaciones y publicaciones
- 47th TF-CSIRT Meeting, Praga, 2016
([diapositivas](https://web.archive.org/web/20161109135211/https://www.terena.org/activities/tf-csirt/meeting47/M.Stampar-Maltrail.pdf))
- _Detect attacks on your network with Maltrail_, Linux Magazine, 2022
([artículo](https://www.linux-magazine.com/Issues/2022/258/Maltrail))
- _Best Cyber Threat Intelligence Feeds_, Silent Push, 2022
([reseña](https://www.silentpush.com/blog/best-cyber-threat-intelligence-feeds))
- _Research on Network Malicious Traffic Detection System Based on Maltrail_, Nanotechnology
Perceptions, 2024
([artículo](https://nano-ntp.com/index.php/nano/article/view/1915/1497))
### Integraciones de terceros
- [FreeBSD Port](https://www.freshports.org/security/maltrail)
- [OPNsense Gateway Plugin](https://github.com/opnsense/plugins/pull/1257)
- [D4 Project](https://www.d4-project.org/2019/09/25/maltrail-integration.html)
- [BlackArch Linux](https://github.com/BlackArch/blackarch/blob/master/packages/maltrail/PKGBUILD)
- [Validin](https://x.com/ValidinLLC/status/1719666086390517762)
- [Maltrail Add-on for Splunk](https://splunkbase.splunk.com/app/7211)
- [Maltrail decoder and rules for Wazuh](https://github.com/MikhailKasimov/maltrail-wazuh-decoder-and-rules)
- [GScan](https://github.com/grayddq/GScan) (solo trails)
- [MalwareWorld](https://www.malwareworld.com/) (solo trails)
- [oisd domain blocklist](https://oisd.nl/?p=inc) (solo trails)
- [NextDNS](https://github.com/nextdns/metadata/blob/e0c9c7e908f5d10823b517ad230df214a7251b13/security/threat-intelligence-feeds.json) (solo trails)
- [NoTracking](https://github.com/notracking/hosts-blocklists/blob/master/SOURCES.md) (solo trails)
- [OWASP Mobile Audit](https://github.com/mpast/mobileAudit#environment-variables) (solo trails)
- [Mobile Security Framework MobSF](https://github.com/MobSF/Mobile-Security-Framework-MobSF/commit/12b07370674238fa4281fc7989b34decc2e08876) (solo trails)
- [pfBlockerNG-devel](https://github.com/pfsense/FreeBSD-ports/blob/devel/net/pfSense-pkg-pfBlockerNG-devel/files/usr/local/www/pfblockerng/pfblockerng_feeds.json) (solo trails)
- [Sansec eComscan](https://sansec.io/kb/about-ecomscan/ecomscan-license) (solo trails)
- [Palo Alto Networks Cortex XSOAR](https://xsoar.pan.dev/docs/reference/integrations/github-maltrail-feed) (conector de trails)
### Agradecimientos
- Thomas Kristner
- Eduardo Arcusa Les
- James Lay
- Ladislav Baco (@laciKE)
- John Kristoff (@jtkdpu)
- Michael Münz (@mimugmail)
- David Brush
- @Godwottery
- Chris Wild (@briskets)
- Keith Irwin (@ki9us)
- Simon Szustkowski (@simonszu)