Redes Superpuestas
Redes Superpuestas
Sección titulada «Redes Superpuestas»Enruta llamadas HTTP salientes y procesos generados a través de superposiciones SOCKS5, Tailscale o I2P.
Descripción General
Sección titulada «Descripción General»Wippy soporta redes superpuestas que transportan de forma transparente el tráfico originado en funciones, procesos y clientes HTTP. Cada superposición es una entrada de registro; el código la selecciona por llamada, y la selección se hereda en las llamadas internas hasta que un descendiente la sobreescribe explícitamente.
Superposiciones soportadas:
network.socks5— proxy SOCKS5 genérico (también el listener SOCKS5 de Tor)network.tailscale— nodo overlay tsnetnetwork.i2p— puente SAM v3 de I2P
Estructura del Proyecto
Sección titulada «Estructura del Proyecto»netdemo/├── wippy.lock└── src/ ├── _index.yaml └── probe.luaPaso 1: Definir una Superposición
Sección titulada «Paso 1: Definir una Superposición»Crea src/_index.yaml:
version: "1.0"namespace: app
entries: - name: processes kind: process.host lifecycle: auto_start: true
- name: terminal kind: terminal.host lifecycle: auto_start: true
# Entrada de proxy SOCKS5 (Tor lo expone en 127.0.0.1:9050 por defecto) - name: tor kind: network.socks5 host: 127.0.0.1 port: 9050 isolate_streams: true
- name: probe kind: process.lua meta: command: name: probe short: Check outbound IP through overlays source: file://probe.lua method: main modules: - io - http_client - jsonisolate_streams: true hace que el driver SOCKS5 genere credenciales aleatorias por conexión para que Tor abra un circuito nuevo en cada dial.
Paso 2: Enrutar Llamadas Salientes
Sección titulada «Paso 2: Enrutar Llamadas Salientes»Crea src/probe.lua:
local io = require("io")local http_client = require("http_client")local json = require("json")
local function fetch_ip(overlay) local options = { timeout = "15s" } if overlay then options.overlay_network = overlay end
local resp, err = http_client.get("https://api.ipify.org?format=json", options) if err then return nil, tostring(err) end if resp.status_code ~= 200 then return nil, "HTTP " .. resp.status_code end
local body = json.decode(resp.body or "") return body and body.ip, nilend
local function main() local direct, d_err = fetch_ip(nil) if d_err then io.print("direct failed: " .. d_err) else io.print("direct IP: " .. direct) end
local routed, r_err = fetch_ip("app:tor") if r_err then io.print("tor failed: " .. r_err) else io.print("tor IP: " .. routed) end
return 0end
return { main = main }La opción overlay_network en http_client selecciona la superposición solo para esa llamada. Sin ella, el dial va a través del valor predeterminado del proceso (ya sea network_service.default_network en .wippy.yaml o una conexión directa).
Paso 3: Ejecutarlo
Sección titulada «Paso 3: Ejecutarlo»wippy initwippy run probeCon Tor ejecutándose localmente:
direct IP: 203.0.113.42tor IP: 185.220.101.61Si Tor no está en ejecución, la línea tor IP reportará un error de dial — la superposición SOCKS5 no cae silenciosamente a una conexión directa.
Herencia
Sección titulada «Herencia»La selección de superposición fluye a través de llamadas anidadas. Selecciona la superposición una vez en el borde de un funcs.call o process.spawn y cada llamada HTTP interna, funcs.call anidado y process.spawn subyacente la utiliza hasta que haya una sobreescritura explícita:
local funcs = require("funcs")
local result, err = funcs.new() :with_options({ network = "app:tor" }) :call("app:scrape_site", url)local pid, err = process.with_options({ network = "app:tor" }) :spawn_monitored("app.workers:probe", "app:processes")La función anidada o el proceso generado utiliza la superposición en cada dial saliente sin necesidad de pasarla explícitamente.
Vincular un Listener
Sección titulada «Vincular un Listener»Las superposiciones que soportan tráfico entrante (Tailscale, I2P) también pueden aceptar listeners HTTP. Adjunta la superposición al http.service en lugar del cliente:
- name: tailnet kind: network.tailscale hostname: wippy-node auth_key_env: TS_AUTHKEY ephemeral: true
- name: gateway kind: http.service addr: ":8080" network: app:tailnet lifecycle: auto_start: trueEl servidor se vincula en la interfaz de tailnet; los clientes lo alcanzan a través de la dirección de Tailscale. SOCKS5 es solo para salida — asignarlo a http.service es rechazado.
Predeterminado para Toda la App
Sección titulada «Predeterminado para Toda la App»Establece una superposición predeterminada en .wippy.yaml para que cada llamada la use salvo que se sobreescriba:
network_service: state_dir: .wippy/net default_network: app:torLa selección explícita con network = nil elimina el predeterminado para esa llamada.
Permisos
Sección titulada «Permisos»La acción network.select controla la selección explícita de superposición. Deniégala en un scope para evitar que el código elija una superposición:
- name: deny_network kind: security.policy policy: actions: "network.select" resources: "*" effect: deny groups: - untrustedLas superposiciones heredadas omiten esta comprobación — fueron autorizadas en el borde del caller. Solo la re-selección explícita en un límite Lua está controlada.
Siguientes Pasos
Sección titulada «Siguientes Pasos»- Sistema de Red - Referencia de tipos de entrada
- Cliente HTTP - Opciones de superposición por llamada
- Modelo de Seguridad - Políticas y scopes
- Autenticación - Seguridad basada en tokens