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.
 [](#license) [](sensor/) [](server.py) [](#trails) [](https://x.com/maltrail) # 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`](https://github.com/stamparm/maltrail/blob/master/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](https://github.com/stamparm/trails), obtenido desde `STATIC_TRAILS_URL`; [con licencia separada](https://github.com/stamparm/trails/blob/main/LICENSE.md) | | 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: ```yaml 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:** ```json { "status": "healthy", "version": "1.0.0", "uptime": 3600 } ``` #### `POST /api/v1/scan` Initiates a new scan. **Request Body:** ```json { "target": "example.com", "options": { "threads": 10, "timeout": 60 } } ``` **Response:** ```json { "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:** ```json { "scan_id": "abc123", "status": "completed", "results": { "vulnerabilities": [], "findings": [] } } ``` #### `DELETE /api/v1/scan/{scan_id}` Cancels or deletes a scan. **Response:** ```json { "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: ```bash 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](https://github.com/stamparm/maltrail/blob/master/CONTRIBUTING.md) for guidelines. ### Development Setup ```bash # 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](https://github.com/stamparm/maltrail/blob/master/LICENSE) file for details. ## Acknowledgments - Thanks to all contributors - Inspired by similar security tools - Built with [Go](https://golang.org/) ## Support - [Documentation](https://docs.example.com) - [Issue Tracker](https://github.com/example/scanner/issues) - [Discussions](https://github.com/example/scanner/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`](https://github.com/stamparm/maltrail/blob/master/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_SERVER` o `LOGSTASH_SERVER`. - Alerta sobre `maltrail_log_dir_free_bytes` con 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_DIR` los 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`](https://github.com/stamparm/maltrail/blob/master/sensor/docs/INSTALL.md) | Instalación, privilegios, configuración y solución de problemas | | [`sensor/docs/ARCHITECTURE.md`](https://github.com/stamparm/maltrail/blob/master/sensor/docs/ARCHITECTURE.md) | Funcionamiento interno del sensor y flujo de datos | | [`sensor/docs/COMPATIBILITY.md`](https://github.com/stamparm/maltrail/blob/master/sensor/docs/COMPATIBILITY.md) | Diferencias deliberadas con el sensor Python retirado | | [`sensor/docs/REPORT.md`](https://github.com/stamparm/maltrail/blob/master/sensor/docs/REPORT.md) | Mediciones, perfiles y resultados de pruebas | | [`sensor/docs/ROADMAP.md`](https://github.com/stamparm/maltrail/blob/master/sensor/docs/ROADMAP.md) | Trabajo abierto del sensor | | [`SekuriPy Labs`](https://www.sekuripy.hr/labs/maltrail/) | 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)