chore: auto-commit (2 archivos)
- CONVENTIONS.md - tools/gen_osint_tools.py Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+110
@@ -167,3 +167,113 @@ usa `tipo: organizacion` / `tipo: lugar` en vez de `tipo: persona`.
|
||||
|
||||
El migrador debe ser re-ejecutable: si una persona ya existe en osint con su slug, se
|
||||
actualiza (no se duplica). Los attachments ya movidos no se vuelven a mover.
|
||||
|
||||
## 9. Scans de red (recon)
|
||||
|
||||
Todo escaneo de red de una investigación —WHOIS, RDAP, DNS, nmap, traceroute, ping— se
|
||||
**archiva SIEMPRE en OSINT**. No existen scans sueltos: el resultado queda como nota navegable
|
||||
en el vault y como fila consultable en la base de datos. Lo gestionan las funciones del grupo
|
||||
de capacidad `recon` del registry (dominio `cybersecurity`); ver `docs/capabilities/recon.md`.
|
||||
|
||||
### 9.1 Nota del scan en el vault
|
||||
|
||||
Cada scan produce una nota Markdown bajo la carpeta del dominio escaneado:
|
||||
|
||||
```
|
||||
dominios/<slug>/recon/<scan_type>-<YYYYMMDD-HHMM>.md
|
||||
```
|
||||
|
||||
donde `<scan_type>` es uno de `whois | rdap | dns | nmap | traceroute | ping` y el timestamp
|
||||
tiene granularidad de minuto. Frontmatter de la nota:
|
||||
|
||||
```yaml
|
||||
tipo: scan-red
|
||||
scan_tipo: whois # whois|rdap|dns|nmap|traceroute|ping
|
||||
target: "ejemplo.com" # objetivo original (dominio, host o IP)
|
||||
slug: ejemplo.com # slug del target (clave de la carpeta)
|
||||
fecha: 2026-06-14T13:18:00 # ISO, momento del scan
|
||||
herramienta: whois # CLI usada (whois, dig, nmap, ...)
|
||||
tags: [scan-red, whois, recon]
|
||||
```
|
||||
|
||||
Body: cabecera con target/tipo/herramienta/fecha, un `## Resumen` opcional con los campos
|
||||
destacados del scan, y la salida cruda completa (`raw`) dentro de un bloque de código. La nota
|
||||
es la **capa crítica**: si no se puede escribir, el guardado falla.
|
||||
|
||||
### 9.2 Tabla `network_scans` (DuckDB, service osint_db)
|
||||
|
||||
Además de la nota, cada scan se registra en la tabla `network_scans` (schema `main`) de la
|
||||
base DuckDB que posee el service `osint_db` (single-writer), vía
|
||||
`POST http://127.0.0.1:8771/api/scan`. Columnas:
|
||||
|
||||
| Columna | Qué |
|
||||
|---|---|
|
||||
| `id` | Identificador del scan |
|
||||
| `target` | Objetivo original (dominio/host/IP) |
|
||||
| `target_slug` | Slug del target (clave de agrupación) |
|
||||
| `scan_type` | `whois \| rdap \| dns \| nmap \| traceroute \| ping` |
|
||||
| `tool` | CLI usada (whois, dig, nmap, ...) |
|
||||
| `scan_ts` | Timestamp ISO del scan |
|
||||
| `note_path` | Ruta relativa de la nota en el vault |
|
||||
| `summary` | JSON con los campos resumidos del scan |
|
||||
| `created_at` | Timestamp de inserción |
|
||||
|
||||
Es la **capa best-effort**: si `osint_db` está caído o no expone el endpoint, el guardado
|
||||
degrada a solo-nota (`registered=False` + aviso) sin fallar. El re-ingest del vault NO borra
|
||||
`network_scans` —es una tabla de datos vivos, no derivada de las notas.
|
||||
|
||||
### 9.3 Cómo lanzar y guardar
|
||||
|
||||
El camino canónico es el pipeline one-shot del registry, que escanea y archiva en una sola
|
||||
llamada:
|
||||
|
||||
```bash
|
||||
cd /home/enmanuel/fn_registry
|
||||
./fn run recon_osint <target> <scan_type> # p.ej. ./fn run recon_osint ejemplo.com whois
|
||||
```
|
||||
|
||||
Para un nmap pesado (full-tcp, vuln, udp-top) lanzar en segundo plano por la duración:
|
||||
|
||||
```bash
|
||||
nohup ./fn run recon_osint scanme.nmap.org nmap --profile full-tcp --timeout-s 7200 \
|
||||
> /tmp/recon-fulltcp.log 2>&1 &
|
||||
```
|
||||
|
||||
Alternativa atómica (controlas el scan y lo guardas aparte) desde Python, importando las
|
||||
funciones del registry —no se reescriben:
|
||||
|
||||
```python
|
||||
import sys; sys.path.insert(0, "python/functions")
|
||||
from cybersecurity import dns_records
|
||||
from cybersecurity.save_scan_to_osint import save_scan_to_osint
|
||||
|
||||
scan = dns_records("ejemplo.com")
|
||||
if scan["status"] == "ok":
|
||||
save_scan_to_osint("ejemplo.com", "dns", scan["raw"],
|
||||
summary={"A": scan["records"].get("A")}, tool="dig")
|
||||
```
|
||||
|
||||
### 9.4 Cómo consultar scans guardados
|
||||
|
||||
Desde una nota del vault, con un bloque `osintdb` (plugin osint-db) que consulta la tabla:
|
||||
|
||||
````markdown
|
||||
```osintdb
|
||||
SELECT scan_type, tool, scan_ts, note_path
|
||||
FROM network_scans
|
||||
WHERE target_slug = 'ejemplo.com'
|
||||
ORDER BY scan_ts DESC
|
||||
```
|
||||
````
|
||||
|
||||
O contra el service directamente vía `/api/query` (mismo SQL). El slug del target se deriva
|
||||
igual que en todo el vault:
|
||||
|
||||
```python
|
||||
import re
|
||||
slug = re.sub(r"[^a-z0-9._-]+", "-", target.lower())
|
||||
```
|
||||
|
||||
> Nota: el `slug` de un dominio/host (p.ej. `ejemplo.com`, `192.168.1.10`) conserva puntos y
|
||||
> guiones porque el set permitido es `[a-z0-9._-]`; difiere del slug de persona de la sección 2,
|
||||
> que solo admite `[a-z0-9-]`.
|
||||
|
||||
Reference in New Issue
Block a user