feat(cybersecurity): auto-commit con 10 cambios

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-02 21:50:23 +02:00
parent 4bbfc127ad
commit f74d0d8e32
10 changed files with 825 additions and 0 deletions
@@ -0,0 +1,74 @@
---
name: launch_chromium_proxy
kind: function
lang: bash
domain: browser
version: "1.0.0"
purity: impure
signature: "launch_chromium_proxy [--proxy URL] [--profile DIR] [--url URL] [--ca-cert PATH] [--extra \"ARGS\"]"
description: "Lanza Chromium (o Chrome) apuntando a un proxy HTTP/HTTPS local con un perfil completamente aislado del perfil real del usuario. Pensado para capturar trafico con un proxy de interceptacion (mitmproxy, Burp Suite) sin contaminar la sesion normal de navegacion. Emite un JSON con el PID del proceso lanzado."
tags: [chromium, chrome, proxy, mitmproxy, burp, browser, web-proxy, intercept, tls]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: []
params:
- name: "--proxy URL"
desc: "URL del proxy HTTP/HTTPS local, ej. http://127.0.0.1:8080. Se pasa a Chromium como --proxy-server=URL. Default: http://127.0.0.1:8080."
- name: "--profile DIR"
desc: "Directorio de perfil aislado para Chromium (--user-data-dir). Se crea automaticamente si no existe. Default: /tmp/chromium-proxy. Usar un path distinto por sesion si se quiere aislamiento total entre corridas."
- name: "--url URL"
desc: "URL inicial a abrir al arrancar el navegador. Opcional. Si se omite, Chromium abre su pagina de nueva pestana."
- name: "--ca-cert PATH"
desc: "Ruta a un CA cert PEM del proxy (ej. ~/.mitmproxy/mitmproxy-ca-cert.pem). Si se pasa, la funcion NO agrega --ignore-certificate-errors y asume que el usuario ya importo el CA en el perfil o en el sistema. Si se omite, se agrega --ignore-certificate-errors automaticamente para que el proxy MITM no rompa HTTPS (menos seguro)."
- name: "--extra \"ARGS\""
desc: "Flags extra que se pasan directamente a chromium, ej. --extra \"--disable-gpu --window-size=1280,800\". El valor completo debe ir entre comillas."
output: "JSON en stdout: {\"pid\": <pid>, \"browser\": \"<binario>\", \"proxy\": \"<url>\", \"profile\": \"<dir>\", \"log\": \"<ruta_log>\"}. Mensajes de estado e informacion de CA en stderr. El navegador corre en background desacoplado de la sesion. Exit codes: 0=lanzado correctamente, 1=binario no encontrado o argumento invalido o error al crear el directorio de perfil."
tested: false
tests: []
test_file_path: ""
file_path: "bash/functions/browser/launch_chromium_proxy.sh"
---
## Ejemplo
```bash
source bash/functions/browser/launch_chromium_proxy.sh
# Caso mas comun: interceptar trafico con mitmproxy corriendo en 8080
# (sin CA instalado: --ignore-certificate-errors se aplica automaticamente)
result=$(launch_chromium_proxy --proxy http://127.0.0.1:8080 --url https://httpbin.org/get)
echo "$result"
# {"pid":12345,"browser":"chromium","proxy":"http://127.0.0.1:8080","profile":"/tmp/chromium-proxy","log":"/tmp/chromium-proxy-12345.log"}
# Con CA cert instalado (mitmproxy): sin --ignore-certificate-errors
launch_chromium_proxy \
--proxy http://127.0.0.1:8080 \
--ca-cert ~/.mitmproxy/mitmproxy-ca-cert.pem \
--profile /tmp/mitm-session \
--url https://api.ejemplo.com/v1/test
# Con Burp Suite en puerto 8081, perfil aislado y ventana de tamano fijo
launch_chromium_proxy \
--proxy http://127.0.0.1:8081 \
--profile /tmp/burp-session \
--extra "--window-size=1440,900" \
--url https://app.objetivo.com
```
## Cuando usarla
Cuando necesitas capturar y analizar trafico HTTPS de un navegador con mitmproxy, Burp Suite u otro proxy de interceptacion, sin tocar el perfil real del usuario ni sus cookies/credenciales guardadas. Ideal antes de hacer analisis de trafico de una app web o API, o al reproducir un flujo autenticado desde una sesion limpia.
## Gotchas
- **Deteccion de binario en orden**: la funcion prueba `chromium`, `chromium-browser`, `google-chrome-stable`, `google-chrome`. En sistemas donde solo existe `google-chrome`, ese sera el binario usado. Si ninguno esta en el PATH, retorna exit 1. Instalar con `sudo apt install chromium` o `chromium-browser`.
- **`--ignore-certificate-errors` sin `--ca-cert`**: este flag desactiva toda la validacion TLS del navegador. Es conveniente para empezar rapido, pero reduce la seguridad de la sesion. Para produccion o analisis de seguridad serio, instalar el CA del proxy en el sistema (`sudo cp mitmproxy-ca-cert.pem /usr/local/share/ca-certificates/mitmproxy.crt && sudo update-ca-certificates`) o en el perfil de Chromium (chrome://settings/certificates), y pasar `--ca-cert` para que la funcion omita el flag inseguro.
- **`--proxy-bypass-list="<-loopback>"`**: fuerza que el trafico loopback (127.0.0.1, localhost) TAMBIEN pase por el proxy. Sin esto, Chromium excluye loopback del proxy por defecto y no veras esas peticiones en mitmproxy. Si quieres el comportamiento estandar (excluir loopback), elimina este flag via `--extra`.
- **Perfil persistente entre sesiones**: el perfil en `/tmp/chromium-proxy` (o el directorio que elijas) persiste entre ejecuciones. Si quieres una sesion 100% limpia cada vez, pasa `--profile /tmp/chromium-proxy-$$` (usa el PID del shell como sufijo) o borra el directorio antes de llamar a la funcion.
- **`setsid` + `disown`**: el navegador se lanza desacoplado de la sesion del agente. Si la shell/sesion que llamo a la funcion termina, el proceso Chromium sigue vivo. Para matarlo, usar `kill <pid>` con el PID del JSON de salida.
- **Log del navegador**: stdout y stderr de Chromium se redirigen a `/tmp/chromium-proxy-<pid>.log`. Si el navegador no arranca, revisar ese archivo para ver el error.
- **Chrome STABLE 138+**: al igual que `chrome_load_extensions`, algunos flags de automatizacion estan bloqueados en Chrome STABLE. Para interceptacion de trafico `--proxy-server` y `--user-data-dir` siguen funcionando en todas las versiones. Esta funcion es compatible con Chrome/Chromium en cualquier canal.
- **Multiples instancias**: si ya hay una instancia de Chromium corriendo con el mismo `--user-data-dir`, Chromium puede reusar esa instancia en lugar de abrir una nueva. Usar un directorio de perfil distinto por sesion concurrente.
@@ -0,0 +1,104 @@
#!/usr/bin/env bash
# launch_chromium_proxy — Lanza Chromium apuntando a un proxy HTTP/HTTPS local con perfil aislado.
launch_chromium_proxy() {
local proxy_url="http://127.0.0.1:8080"
local profile_dir="/tmp/chromium-proxy"
local start_url=""
local ca_cert=""
local extra_args=""
# Parsear argumentos
while [[ $# -gt 0 ]]; do
case "$1" in
--proxy)
proxy_url="$2"; shift 2 ;;
--profile)
profile_dir="$2"; shift 2 ;;
--url)
start_url="$2"; shift 2 ;;
--ca-cert)
ca_cert="$2"; shift 2 ;;
--extra)
extra_args="$2"; shift 2 ;;
*)
echo "ERROR: argumento desconocido: $1" >&2
return 1 ;;
esac
done
# Detectar binario del navegador
local browser_bin=""
for candidate in chromium chromium-browser google-chrome-stable google-chrome; do
if command -v "$candidate" &>/dev/null; then
browser_bin="$candidate"
break
fi
done
if [[ -z "$browser_bin" ]]; then
echo "ERROR: no se encontro ningun binario Chromium/Chrome en el PATH." >&2
echo " Probados: chromium, chromium-browser, google-chrome-stable, google-chrome." >&2
return 1
fi
# Crear directorio de perfil si no existe
if [[ ! -d "$profile_dir" ]]; then
mkdir -p "$profile_dir" || {
echo "ERROR: no se pudo crear el directorio de perfil: $profile_dir" >&2
return 1
}
fi
# Construir argumentos del navegador
local args=(
"--proxy-server=${proxy_url}"
"--user-data-dir=${profile_dir}"
"--proxy-bypass-list=<-loopback>"
"--no-first-run"
"--no-default-browser-check"
)
# Manejo de certificados TLS
if [[ -n "$ca_cert" ]]; then
# El usuario instalo el CA en el perfil; no ignorar errores de certificado.
# (El CA se instala en el sistema o en el perfil antes de lanzar.)
echo "INFO: CA cert declarado: $ca_cert" >&2
echo "INFO: Asegurate de haber importado el CA en el perfil o en el sistema antes de navegar HTTPS." >&2
else
# Sin CA cert: ignorar errores de certificado para que mitmproxy/Burp funcionen sin configuracion extra.
# ADVERTENCIA: esto desactiva la validacion TLS completa del navegador.
args+=("--ignore-certificate-errors")
echo "WARN: --ignore-certificate-errors activo. Usa --ca-cert si instalaste el CA del proxy." >&2
fi
# URL inicial opcional
if [[ -n "$start_url" ]]; then
args+=("$start_url")
fi
# Argumentos extra pasados por el usuario
# shellcheck disable=SC2206
local extra_arr=()
if [[ -n "$extra_args" ]]; then
read -r -a extra_arr <<< "$extra_args"
args+=("${extra_arr[@]}")
fi
# Log temporal para stderr/stdout del navegador
local log_file="/tmp/chromium-proxy-$$.log"
# Lanzar en background desacoplado de la sesion del agente
setsid "$browser_bin" "${args[@]}" </dev/null >"$log_file" 2>&1 &
local browser_pid=$!
disown "$browser_pid"
# Emitir JSON con informacion del proceso lanzado
printf '{"pid":%d,"browser":"%s","proxy":"%s","profile":"%s","log":"%s"}\n' \
"$browser_pid" "$browser_bin" "$proxy_url" "$profile_dir" "$log_file"
}
# Ejecutar si se llama directamente (fn run / bash <file>)
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
launch_chromium_proxy "$@"
fi
@@ -0,0 +1,88 @@
---
name: query_mitm_flows
kind: function
lang: bash
domain: cybersecurity
version: "1.0.0"
purity: impure
signature: "query_mitm_flows(file_or_glob: string, filter?: string, har?: string, mitmdump?: string) -> void"
description: "Consulta capturas .mitm guardadas con mitmproxy: vuelca los flujos que coinciden con un filtro de mitmproxy a stdout, o exporta la captura a HAR. Acepta uno o varios archivos .mitm (incluyendo globs expandidos por el shell). Autodetecta mitmdump en PATH y $HOME/.local/bin."
tags: [bash, cybersecurity, mitmproxy, web-proxy, query, har, capture, traffic, proxy, network]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: []
params:
- name: file_or_glob
desc: "Ruta a un archivo .mitm o glob expandido por el shell (ej. ~/captures/traffic-*.mitm). Acepta múltiples archivos como argumentos posicionales."
- name: filter
desc: "Expresión de filtro mitmproxy (ej. '~m POST & ~u /api', '~c 500', '~d example.com'). Si se omite, vuelca todos los flujos."
- name: har
desc: "Ruta de salida para exportar en formato HAR (--set hardump=OUT). Si se omite, el volcado va a stdout."
- name: mitmdump
desc: "Ruta al binario mitmdump. Si se omite, autodetecta en PATH y luego en $HOME/.local/bin/mitmdump."
output: "Vuelca los flujos capturados a stdout (modo default) o exporta a un archivo HAR (con --har); informa la ruta de exportación en stderr al terminar. Exit code de mitmdump propagado."
tested: false
tests: []
test_file_path: ""
file_path: "bash/functions/cybersecurity/query_mitm_flows.sh"
---
## Ejemplo
```bash
source bash/functions/cybersecurity/query_mitm_flows.sh
# Volcar todos los flujos de una captura
query_mitm_flows ~/captures/traffic-20260602.mitm
# Filtrar solo peticiones POST a /api (glob expandido por el shell)
query_mitm_flows ~/captures/traffic-20260602-*.mitm --filter "~m POST & ~u /api"
# Ver solo respuestas con código 500
query_mitm_flows session.mitm --filter "~c 500"
# Exportar a HAR para abrir en el Network tab del browser DevTools
query_mitm_flows ~/captures/traffic-20260602.mitm --har salida.har
# Exportar a HAR con filtro aplicado
query_mitm_flows session.mitm --filter "~d example.com" --har example_flows.har
# Especificar mitmdump manualmente (ej. en un venv de Python)
query_mitm_flows session.mitm --mitmdump ~/.venv/bin/mitmdump --filter "~m POST"
```
## Cuando usarla
Cuando hayas capturado tráfico HTTP/HTTPS con mitmproxy y necesites consultarlo después sin abrir una interfaz interactiva: filtrar flujos específicos por método, dominio, URL o código de respuesta, o exportar la captura a HAR para análisis posterior en herramientas externas (browser DevTools, Insomnia, Postman). Úsala desde scripts de análisis automatizados o pipelines de revisión de seguridad.
## Gotchas
**Sintaxis de filtros mitmproxy** — los filtros se pasan como expresión entre comillas:
| Operador | Significado | Ejemplo |
|---|---|---|
| `~u <regex>` | URL (path + query) | `~u /api/login` |
| `~d <regex>` | Dominio del host | `~d example.com` |
| `~m <método>` | Método HTTP | `~m POST` |
| `~c <código>` | Código de respuesta | `~c 500` |
| `~bq <regex>` | Body del request | `~bq password` |
| `~bs <regex>` | Body del response | `~bs token` |
| `~t <regex>` | Content-Type | `~t application/json` |
| `~s` | Solo respuestas | `~s` |
| `~q` | Solo requests | `~q` |
Combinar con `&` (AND), `|` (OR), `!` (NOT). Ejemplos:
- `"~m POST & ~u /api"` — POST a rutas /api
- `"~c 500 | ~c 503"` — errores de servidor
- `"~d example.com & !~u /static"` — todo de example.com excepto estáticos
**Globs:** el shell expande el glob *antes* de pasar los argumentos a la función. Pasar `~/captures/traffic-*.mitm` sin comillas para que el shell expanda; con comillas el glob llega literalmente y fallará si el archivo no existe.
**Inspección interactiva:** para navegar los flujos con UI, usar `mitmweb -r <file>` (web) o `mitmproxy -r <file>` (TUI), no esta función. Esta función es para consulta programática y scripting.
**Múltiples archivos con `-r`:** mitmdump acepta varios flags `-r` y concatena los flujos en orden. El filtro se aplica sobre el conjunto completo.
**HAR y filtros juntos:** al usar `--har` con `--filter`, solo los flujos que pasen el filtro se exportan al HAR.
@@ -0,0 +1,101 @@
#!/usr/bin/env bash
# query_mitm_flows — Consulta capturas .mitm con mitmdump: vuelca flujos a stdout
# o exporta a HAR. Acepta uno o varios archivos (también globs expandidos por el shell).
query_mitm_flows() {
local -a files=()
local filter=""
local har_out=""
local mitmdump_bin=""
# ── Parseo de argumentos ────────────────────────────────────────────────────
while [[ $# -gt 0 ]]; do
case "$1" in
--filter)
[[ -z "${2:-}" ]] && { echo "ERROR: --filter requiere un valor" >&2; return 1; }
filter="$2"; shift 2 ;;
--har)
[[ -z "${2:-}" ]] && { echo "ERROR: --har requiere una ruta de salida" >&2; return 1; }
har_out="$2"; shift 2 ;;
--mitmdump)
[[ -z "${2:-}" ]] && { echo "ERROR: --mitmdump requiere la ruta al binario" >&2; return 1; }
mitmdump_bin="$2"; shift 2 ;;
--*)
echo "ERROR: opcion desconocida: $1" >&2; return 1 ;;
*)
files+=("$1"); shift ;;
esac
done
# ── Validar que se paso al menos un archivo ─────────────────────────────────
if [[ ${#files[@]} -eq 0 ]]; then
echo "ERROR: se requiere al menos un archivo .mitm como argumento" >&2
echo "Uso: query_mitm_flows <file_or_glob> [--filter EXPR] [--har OUT] [--mitmdump BIN]" >&2
return 1
fi
# ── Verificar que cada archivo existe ──────────────────────────────────────
local -a valid_files=()
for f in "${files[@]}"; do
if [[ -f "$f" ]]; then
valid_files+=("$f")
else
echo "ERROR: archivo no encontrado: $f" >&2
fi
done
if [[ ${#valid_files[@]} -eq 0 ]]; then
echo "ERROR: ningun archivo valido encontrado (el patron no matcheo nada)" >&2
return 1
fi
# ── Autodetectar mitmdump ───────────────────────────────────────────────────
if [[ -z "$mitmdump_bin" ]]; then
if command -v mitmdump &>/dev/null; then
mitmdump_bin="mitmdump"
elif [[ -x "$HOME/.local/bin/mitmdump" ]]; then
mitmdump_bin="$HOME/.local/bin/mitmdump"
else
echo "ERROR: mitmdump no encontrado. Instala mitmproxy:" >&2
echo " pip install mitmproxy o pip install --user mitmproxy" >&2
return 1
fi
fi
if [[ ! -x "$(command -v "$mitmdump_bin" 2>/dev/null || echo "$mitmdump_bin")" ]]; then
echo "ERROR: binario mitmdump no ejecutable: $mitmdump_bin" >&2
return 1
fi
# ── Construir y ejecutar el comando ────────────────────────────────────────
local -a cmd=("$mitmdump_bin" -n)
# Añadir todos los archivos de entrada con -r
for f in "${valid_files[@]}"; do
cmd+=(-r "$f")
done
# Modo HAR
if [[ -n "$har_out" ]]; then
cmd+=(--set "hardump=${har_out}")
fi
# Filtro de flujos (argumento posicional al final)
if [[ -n "$filter" ]]; then
cmd+=("$filter")
fi
"${cmd[@]}"
local exit_code=$?
if [[ -n "$har_out" && $exit_code -eq 0 ]]; then
echo "HAR exportado a ${har_out}" >&2
fi
return $exit_code
}
# Ejecutar si se llama directamente
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
query_mitm_flows "$@"
fi
@@ -0,0 +1,80 @@
---
name: start_mitm_capture
kind: function
lang: bash
domain: cybersecurity
version: "1.0.0"
purity: impure
signature: "start_mitm_capture([--port N] [--out DIR] [--rotate-min N] [--addon PATH] [--mitmdump BIN] [--log PATH]) -> string"
description: "Arranca mitmdump en modo headless en segundo plano como proxy de interceptación liviano, con rotación de capturas cada N minutos vía el addon rotate_capture_flows.py del registry. El proceso sobrevive al cierre de la shell (setsid). Emite JSON con PID, puerto, directorio de salida y ruta del log."
tags: [bash, cybersecurity, mitmproxy, proxy, capture, web-proxy, network, interception, mitmdump]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: []
params:
- name: "--port N"
desc: "Puerto TCP donde mitmdump escucha conexiones del cliente proxy. Default: 8080."
- name: "--out DIR"
desc: "Directorio donde se guardan los archivos .mitm rotados. Se crea automáticamente si no existe. Default: $HOME/captures."
- name: "--rotate-min N"
desc: "Minutos de duración de cada archivo de captura antes de rotar. Default: 20."
- name: "--addon PATH"
desc: "Ruta al addon Python de rotación (rotate_capture_flows.py). Default: derivado desde FN_REGISTRY_ROOT o desde la ubicación del propio script (3 niveles arriba)."
- name: "--mitmdump BIN"
desc: "Ruta al binario mitmdump. Default: autodetectado con command -v mitmdump, luego $HOME/.local/bin/mitmdump. Si no se encuentra, falla con instrucción de instalación."
- name: "--log PATH"
desc: "Archivo de log del proceso mitmdump. Default: <out>/mitmdump.log."
output: "JSON en stdout: {\"pid\": <pid>, \"port\": <port>, \"out_dir\": \"<dir>\", \"rotate_min\": <n>, \"log\": \"<log>\"}. Exit 1 en error (binario no encontrado, addon ausente, proceso muerto al arrancar)."
tested: false
tests: []
test_file_path: ""
file_path: "bash/functions/cybersecurity/start_mitm_capture.sh"
---
## Ejemplo
```bash
source bash/functions/cybersecurity/start_mitm_capture.sh
# Arranque con defaults (puerto 8080, capturas en ~/captures, rotación cada 20 min)
start_mitm_capture --port 8080 --out /home/enmanuel/captures --rotate-min 20
# Salida esperada:
# {"pid": 123456, "port": 8080, "out_dir": "/home/enmanuel/captures", "rotate_min": 20, "log": "/home/enmanuel/captures/mitmdump.log"}
# Puerto alternativo y rotación más frecuente
start_mitm_capture --port 9090 --out /tmp/mitm_session --rotate-min 5
# Pasando addon y binario explícitos
start_mitm_capture \
--port 8080 \
--out /home/enmanuel/captures \
--addon /home/enmanuel/fn_registry/python/functions/cybersecurity/rotate_capture_flows.py \
--mitmdump /home/enmanuel/.local/bin/mitmdump
# Leer el PID para poder parar el proceso más adelante
info=$(start_mitm_capture --port 8080 --out /home/enmanuel/captures)
pid=$(echo "$info" | python3 -c "import sys,json; print(json.load(sys.stdin)['pid'])")
echo "Proxy corriendo con PID $pid"
# Para parar: kill "$pid"
```
## Cuando usarla
Cuando necesites un proxy de interceptación pasivo siempre activo en segundo plano que capture y rote el tráfico HTTP/HTTPS de forma continua sin supervisión manual. Úsala antes de lanzar pruebas de integración, sesiones de auditoría web o scraping supervisado donde quieras replay o análisis posterior de las capturas `.mitm`.
## Gotchas
- **HTTPS requiere instalar el CA de mitmproxy en el cliente.** El certificado raíz está en `~/.mitmproxy/mitmproxy-ca-cert.pem` tras el primer arranque. En navegadores: importar como CA de confianza. En curl/httpx: `--cacert ~/.mitmproxy/mitmproxy-ca-cert.pem`. En Chrome/Chromium headless: `--ignore-certificate-errors` (solo para pruebas).
- **El proceso queda en background.** Para pararlo: `kill <pid>` (el PID se devuelve en el JSON) o `port_kill 8080` si tienes la función del registry disponible.
- **El addon rotate_capture_flows.py debe existir.** La función lo busca en la raíz del registry derivada automáticamente; si el registry está en una ubicación no estándar, pasa `--addon` explícitamente o setea `FN_REGISTRY_ROOT`.
- **setsid desacopla el proceso de la shell.** Si cierras la terminal, mitmdump sigue corriendo. Necesitas matar el PID manualmente o via systemd/supervisor si quieres ciclo de vida gestionado.
- **El log crece sin límite.** El log de mitmdump no rota; solo rotan los archivos `.mitm` de capturas. Monitoriza el tamaño de `<out>/mitmdump.log` en sesiones largas.
- **Solo funciona con mitmdump >= 9.x** (API de addons `--set` con parámetros por nombre). Versiones anteriores usan sintaxis distinta.
## Notas
La derivación de la raíz del registry cuando `FN_REGISTRY_ROOT` no está seteado asciende 3 niveles desde `bash/functions/cybersecurity/` hasta la raíz usando `dirname "${BASH_SOURCE[0]}"`. Esto funciona siempre que el script se sourcee desde su ubicación original en el registry.
@@ -0,0 +1,114 @@
#!/usr/bin/env bash
# start_mitm_capture — Arranca mitmdump en segundo plano como proxy de interceptación
# con rotación de capturas cada N minutos vía addon Python del registry.
start_mitm_capture() {
local port=8080
local out_dir="$HOME/captures"
local rotate_min=20
local addon_path=""
local mitmdump_bin=""
local log_path=""
# Parseo de argumentos
while [[ $# -gt 0 ]]; do
case "$1" in
--port) port="$2"; shift 2 ;;
--out) out_dir="$2"; shift 2 ;;
--rotate-min) rotate_min="$2"; shift 2 ;;
--addon) addon_path="$2"; shift 2 ;;
--mitmdump) mitmdump_bin="$2"; shift 2 ;;
--log) log_path="$2"; shift 2 ;;
*)
echo "ERROR: argumento desconocido: $1" >&2
echo "Uso: start_mitm_capture [--port N] [--out DIR] [--rotate-min N] [--addon PATH] [--mitmdump BIN] [--log PATH]" >&2
return 1
;;
esac
done
# Derivar raíz del registry cuando FN_REGISTRY_ROOT no está seteado
local registry_root
if [[ -n "${FN_REGISTRY_ROOT:-}" ]]; then
registry_root="$FN_REGISTRY_ROOT"
else
# bash/functions/cybersecurity/ -> 3 niveles arriba = raíz del registry
registry_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
fi
# Default addon usando la raíz derivada
if [[ -z "$addon_path" ]]; then
addon_path="${registry_root}/python/functions/cybersecurity/rotate_capture_flows.py"
fi
# Default log path (depende de out_dir, se resuelve después de crear el dir)
# Se asigna más abajo si sigue vacío
# Crear directorio de capturas si no existe
if [[ ! -d "$out_dir" ]]; then
mkdir -p "$out_dir" || {
echo "ERROR: no se pudo crear el directorio de capturas: $out_dir" >&2
return 1
}
fi
# Asignar log por defecto ahora que out_dir existe
if [[ -z "$log_path" ]]; then
log_path="${out_dir}/mitmdump.log"
fi
# Resolver binario mitmdump
if [[ -z "$mitmdump_bin" ]]; then
if command -v mitmdump &>/dev/null; then
mitmdump_bin="$(command -v mitmdump)"
elif [[ -x "$HOME/.local/bin/mitmdump" ]]; then
mitmdump_bin="$HOME/.local/bin/mitmdump"
else
echo "ERROR: mitmdump no encontrado; instala con: uv tool install mitmproxy" >&2
return 1
fi
else
if [[ ! -x "$mitmdump_bin" ]]; then
echo "ERROR: el binario indicado no existe o no es ejecutable: $mitmdump_bin" >&2
return 1
fi
fi
# Verificar que el addon existe
if [[ ! -f "$addon_path" ]]; then
echo "ERROR: addon no encontrado: $addon_path" >&2
echo " Asegúrate de que FN_REGISTRY_ROOT apunta a la raíz del registry" >&2
echo " o pasa --addon con la ruta correcta a rotate_capture_flows.py" >&2
return 1
fi
# Arrancar mitmdump en background con setsid (sobrevive al cierre de la shell).
# El redirect </dev/null desacopla stdin: sin él, el proceso retiene el pipe
# heredado y la shell sale con exit 144 (SIGTERM) al cerrarse. disown lo saca
# de la tabla de jobs para que la shell no le envíe señales al terminar.
setsid "$mitmdump_bin" \
-s "$addon_path" \
--set "rotate_min=${rotate_min}" \
--set "capture_dir=${out_dir}" \
--listen-port "$port" \
</dev/null >> "$log_path" 2>&1 &
local pid=$!
disown "$pid" 2>/dev/null || true
# Esperar ~1s y verificar que el proceso sigue vivo
sleep 1
if ! kill -0 "$pid" 2>/dev/null; then
echo "ERROR: mitmdump murió al arrancar. Últimas líneas del log:" >&2
tail -20 "$log_path" >&2
return 1
fi
# Emitir JSON con información del proceso arrancado
printf '{"pid": %d, "port": %d, "out_dir": "%s", "rotate_min": %d, "log": "%s"}\n' \
"$pid" "$port" "$out_dir" "$rotate_min" "$log_path"
}
# Ejecutar si se llama directamente (fn run / bash <file>)
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
start_mitm_capture "$@"
fi