Redes de Sobreposição
Redes de Sobreposição
Seção intitulada “Redes de Sobreposição”Roteie chamadas HTTP de saída e processos criados através de sobreposições SOCKS5, Tailscale ou I2P.
Visão Geral
Seção intitulada “Visão Geral”O Wippy suporta redes de sobreposição que transportam de forma transparente o tráfego originado de funções, processos e clientes HTTP. Cada sobreposição é uma entrada de registro; o código opta por ela por chamada, e a seleção é herdada pelas chamadas internas até que um descendente a substitua explicitamente.
Sobreposições suportadas:
network.socks5— proxy SOCKS5 genérico (também o listener SOCKS5 do Tor)network.tailscale— nó de sobreposição tsnetnetwork.i2p— bridge SAM v3 do I2P
Estrutura do Projeto
Seção intitulada “Estrutura do Projeto”netdemo/├── wippy.lock└── src/ ├── _index.yaml └── probe.luaPasso 1: Definir uma Sobreposição
Seção intitulada “Passo 1: Definir uma Sobreposição”Crie 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 (o Tor expõe um em 127.0.0.1:9050 por padrão) - 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 faz o driver SOCKS5 gerar credenciais aleatórias por conexão, de modo que o Tor abre um circuito novo para cada dial.
Passo 2: Rotear Chamadas de Saída
Seção intitulada “Passo 2: Rotear Chamadas de Saída”Crie 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 }A opção overlay_network no http_client seleciona a sobreposição apenas para aquela chamada. Sem ela, o dial usa o padrão do processo (definido via network_service.default_network em .wippy.yaml ou direto).
Passo 3: Executar
Seção intitulada “Passo 3: Executar”wippy initwippy run probeCom o Tor rodando localmente:
direct IP: 203.0.113.42tor IP: 185.220.101.61Se o Tor não estiver em execução, a linha tor IP reportará um erro de dial — a sobreposição SOCKS5 não recorre silenciosamente a uma conexão direta.
Herança
Seção intitulada “Herança”A seleção de sobreposição flui pelas chamadas aninhadas. Escolha a sobreposição uma vez na borda de um funcs.call ou process.spawn e toda chamada HTTP interna, funcs.call aninhado e process.spawn subsequente a utilizará até uma substituição 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")A função aninhada ou processo criado verá a sobreposição em todo dial de saída sem precisar passá-la explicitamente.
Vinculando um Listener
Seção intitulada “Vinculando um Listener”Sobreposições que suportam tráfego de entrada (Tailscale, I2P) também podem aceitar listeners HTTP. Anexe a sobreposição ao http.service em vez do 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: trueO servidor vincula na interface tailnet; os clientes o acessam via endereço Tailscale. SOCKS5 é apenas de saída — atribuí-lo a um http.service é rejeitado.
Padrão para a Aplicação Inteira
Seção intitulada “Padrão para a Aplicação Inteira”Defina uma sobreposição padrão em .wippy.yaml para que todas as chamadas a utilizem, salvo substituição:
network_service: state_dir: .wippy/net default_network: app:torA seleção explícita com network = nil cancela o padrão para aquela chamada.
Permissões
Seção intitulada “Permissões”A ação network.select controla a seleção explícita de sobreposição. Negue-a em um escopo para impedir que o código escolha uma sobreposição:
- name: deny_network kind: security.policy policy: actions: "network.select" resources: "*" effect: deny groups: - untrustedSobreposições herdadas ignoram essa verificação — elas foram autorizadas na borda do chamador. Apenas a reseleção explícita em uma fronteira Lua é controlada.
Próximos Passos
Seção intitulada “Próximos Passos”- Network System - Referência de tipos de entrada
- HTTP Client - Opções de sobreposição por chamada
- Security Model - Políticas e escopos
- Authentication - Segurança baseada em token