#!/usr/bin/env node /** * Offline regression check for the server egress boundary artifacts. * * This check never applies host firewall/systemd policy and never contacts the * public network. It validates the shipped templates, exercises an in-process * exact-host+port proxy policy, and demonstrates the transports that still * require the OS boundary because HTTP proxy environment variables do not * contain them. */ import assert from 'node:assert/strict'; import { readFile } from 'node:fs/promises'; import { fileURLToPath } from 'node:url'; import http from 'node:http'; import net from 'node:net'; import dgram from 'node:dgram'; import { Resolver } from 'node:dns/promises'; import { execFile } from 'node:child_process'; const SYSTEMD_FILE = new URL('../../deploy/egress/systemd/maestro-egress.service.example', import.meta.url); const SQUID_FILE = new URL('../../deploy/egress/squid.conf', import.meta.url); const ALLOWED_HOST = 'allowed.egress.invalid'; const DENIED_HOST = 'denied.egress.invalid'; const ALLOWED_PORT = 443; const SECRET = 'EGRESS_SECRET_CANARY_7d7fc02c'; function listen(server, host) { return new Promise((resolve, reject) => { server.once('error', reject); const onReady = () => { server.off('error', reject); resolve(server.address()); }; if (typeof server.listen === 'function') server.listen(0, host, onReady); else server.bind(0, host, onReady); }); } function close(server) { server.closeAllConnections?.(); server.close(); } function runNode(code, env = {}) { return new Promise((resolve, reject) => { execFile( process.execPath, ['--use-env-proxy', '-e', code], { env: { PATH: process.env.PATH || '/usr/bin:/bin', HOME: '/tmp', LANG: 'C.UTF-8', ...env }, encoding: 'utf8', timeout: 8_000, maxBuffer: 64 * 1024, }, (error, stdout, stderr) => { if (error) { reject(new Error(`local child probe failed: ${stderr.trim() || error.message}`)); return; } resolve(stdout.trim()); }, ); }); } function rawExchange(host, port, request) { return new Promise((resolve, reject) => { const socket = net.createConnection({ host, port }); let response = ''; const timer = setTimeout(() => socket.destroy(new Error('raw probe timed out')), 3_000); socket.setEncoding('utf8'); socket.on('connect', () => socket.end(request)); socket.on('data', (chunk) => { response += chunk; }); socket.on('error', reject); socket.on('close', () => { clearTimeout(timer); resolve(response); }); }); } function parseTarget(value, fallbackScheme = 'http:') { try { const url = value.includes('://') ? new URL(value) : new URL(`${fallbackScheme}//${value}`); return { hostname: url.hostname, port: Number(url.port || (url.protocol === 'https:' ? 443 : 80)), }; } catch { return { hostname: '', port: 0 }; } } function allowedTarget(target) { return target.hostname === ALLOWED_HOST && target.port === ALLOWED_PORT; } async function validateTemplates() { const [unit, squid] = await Promise.all([ readFile(SYSTEMD_FILE, 'utf8'), readFile(SQUID_FILE, 'utf8'), ]); assert.match(unit, /^IPAddressDeny=any$/m); assert.match(unit, /^IPAddressAllow=127\.0\.0\.2\/32$/m); assert.match(unit, /^IPAddressAllow=127\.0\.0\.3\/32$/m); assert.doesNotMatch(unit, /^IPAddressAllow=(?:localhost|127\.0\.0\.0\/8|::1(?:\/128)?)$/m); assert.match(unit, /ExecStart=\/usr\/bin\/env .*HTTP_PROXY=http:\/\/127\.0\.0\.2:3128 .*HTTPS_PROXY=http:\/\/127\.0\.0\.2:3128 .*NO_PROXY= .*\/usr\/bin\/node --use-env-proxy/m); assert.doesNotMatch(unit, /NODE_OPTIONS=/); assert.match(squid, /^http_port 127\.0\.0\.2:3128$/m); assert.match(squid, /^acl maestro_llm_host dstdomain -n allowed\.egress\.invalid$/m); assert.match(squid, /^acl maestro_llm_port port 443$/m); assert.match(squid, /^http_access allow maestro_llm_host maestro_llm_port$/m); assert.match(squid, /^access_log none$/m); assert.match(squid, /^cache_store_log none$/m); const accessRules = squid.split(/\r?\n/).filter((line) => /^http_access\s+/.test(line.trim())); assert.equal(accessRules.at(-1)?.trim(), 'http_access deny all'); return { systemd: true, squid: true }; } async function runProxyChecks() { const events = []; const proxy = http.createServer((req, res) => { const selectedTarget = Array.isArray(req.headers['x-egress-target']) ? req.headers['x-egress-target'][0] : req.headers['x-egress-target']; const target = parseTarget(selectedTarget || req.url || ''); const allowed = allowedTarget(target); events.push({ protocol: 'http', decision: allowed ? 'allow' : 'deny', port: target.port }); res.writeHead(allowed ? 200 : 403, { 'content-type': 'text/plain' }); res.end(allowed ? 'allowed' : 'denied'); }); proxy.on('connect', (req, socket) => { const target = parseTarget(req.url || '', 'http:'); const allowed = allowedTarget(target); events.push({ protocol: 'connect', decision: allowed ? 'allow' : 'deny', port: target.port }); socket.end(`HTTP/1.1 ${allowed ? '200 Connection Established' : '403 Forbidden'}\r\nConnection: close\r\n\r\n`); }); proxy.on('upgrade', (req, socket) => { const target = parseTarget(req.url || ''); const allowed = allowedTarget(target); events.push({ protocol: 'websocket', decision: allowed ? 'allow' : 'deny', port: target.port }); socket.end(`HTTP/1.1 ${allowed ? '101 Switching Protocols' : '403 Forbidden'}\r\nConnection: close\r\n\r\n`); }); const address = await listen(proxy, '127.0.0.1'); const proxyUrl = `http://127.0.0.1:${address.port}`; try { const fetchAllowed = await fetch(`${proxyUrl}/private?token=${SECRET}`, { headers: { Authorization: `Bearer ${SECRET}`, 'x-egress-target': `${ALLOWED_HOST}:${ALLOWED_PORT}` }, signal: AbortSignal.timeout(3_000), }); const fetchDenied = await fetch(`${proxyUrl}/private?token=${SECRET}`, { headers: { Authorization: `Bearer ${SECRET}`, 'x-egress-target': `${DENIED_HOST}:${ALLOWED_PORT}` }, signal: AbortSignal.timeout(3_000), }); assert.equal(fetchAllowed.status, 200); assert.equal(fetchDenied.status, 403); await Promise.all([fetchAllowed.text(), fetchDenied.text()]); const connectAllowed = await rawExchange('127.0.0.1', address.port, `CONNECT ${ALLOWED_HOST}:${ALLOWED_PORT} HTTP/1.1\r\nHost: ${ALLOWED_HOST}:${ALLOWED_PORT}\r\nAuthorization: Bearer ${SECRET}\r\n\r\n`); const connectDenied = await rawExchange('127.0.0.1', address.port, `CONNECT ${DENIED_HOST}:${ALLOWED_PORT} HTTP/1.1\r\nHost: ${DENIED_HOST}:${ALLOWED_PORT}\r\n\r\n`); assert.match(connectAllowed, /^HTTP\/1\.1 200/); assert.match(connectDenied, /^HTTP\/1\.1 403/); const wsAllowed = await rawExchange('127.0.0.1', address.port, `GET ws://${ALLOWED_HOST}:${ALLOWED_PORT}/socket?token=${SECRET} HTTP/1.1\r\nHost: ${ALLOWED_HOST}:${ALLOWED_PORT}\r\nConnection: Upgrade\r\nUpgrade: websocket\r\n\r\n`); const wsDenied = await rawExchange('127.0.0.1', address.port, `GET ws://${DENIED_HOST}:${ALLOWED_PORT}/socket HTTP/1.1\r\nHost: ${DENIED_HOST}:${ALLOWED_PORT}\r\nConnection: Upgrade\r\nUpgrade: websocket\r\n\r\n`); assert.match(wsAllowed, /^HTTP\/1\.1 101/); assert.match(wsDenied, /^HTTP\/1\.1 403/); const serializedEvents = JSON.stringify(events); assert.ok(!serializedEvents.includes(SECRET), 'metadata events must not retain request secrets'); assert.equal(events.filter((event) => event.decision === 'allow').length, 3); assert.equal(events.filter((event) => event.decision === 'deny').length, 3); return { allowed: 3, denied: 3, secretRetained: false }; } finally { close(proxy); } } async function reserveTcpPort() { const server = net.createServer(); const address = await listen(server, '127.0.0.1'); await new Promise((resolve, reject) => server.close((error) => error ? reject(error) : resolve())); return address.port; } async function runActualEnvProxyChild(port) { const events = []; const proxy = http.createServer((req, res) => { const target = parseTarget(req.url || ''); const allowed = allowedTarget(target); events.push({ transport: 'absolute-form', decision: allowed ? 'allow' : 'deny', target: `${target.hostname}:${target.port}`, absoluteUrl: /^http:\/\//.test(req.url || ''), }); res.writeHead(allowed ? 200 : 403, { 'content-type': 'text/plain', connection: 'close' }); res.end(allowed ? 'allowed' : 'denied'); }); proxy.on('connect', (req, socket) => { const target = parseTarget(req.url || '', 'http:'); const allowed = allowedTarget(target); events.push({ transport: 'connect', decision: allowed ? 'allow' : 'deny', target: `${target.hostname}:${target.port}`, absoluteUrl: false, }); if (!allowed) { socket.end('HTTP/1.1 403 Forbidden\r\nConnection: close\r\n\r\n'); return; } socket.write('HTTP/1.1 200 Connection Established\r\n\r\n'); socket.once('data', () => { socket.end('HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 7\r\nConnection: close\r\n\r\nallowed'); }); }); await new Promise((resolve, reject) => { proxy.once('error', reject); proxy.listen(port, '127.0.0.1', () => { proxy.off('error', reject); resolve(); }); }); try { const init = { headers: { Authorization: `Bearer ${SECRET}` }, signal: AbortSignal.timeout(3_000), }; const allowedResponse = await fetch(`http://${ALLOWED_HOST}:${ALLOWED_PORT}/private?token=${SECRET}`, init); const allowedStatus = allowedResponse.status; await allowedResponse.text(); let deniedStatus = 'error'; try { const deniedResponse = await fetch(`http://${DENIED_HOST}:${ALLOWED_PORT}/private?token=${SECRET}`, init); deniedStatus = deniedResponse.status; await deniedResponse.text(); } catch {} return { allowedStatus, deniedStatus, events }; } finally { close(proxy); } } async function runActualEnvProxyCheck() { const port = await reserveTcpPort(); const proxyUrl = `http://127.0.0.1:${port}`; const childEnv = { PATH: process.env.PATH || '/usr/bin:/bin', HOME: '/tmp', LANG: 'C.UTF-8', MAESTRO_EGRESS_PROXY_CHILD: '1', MAESTRO_EGRESS_PROXY_PORT: String(port), HTTP_PROXY: proxyUrl, HTTPS_PROXY: proxyUrl, NO_PROXY: '', }; const output = await new Promise((resolve, reject) => { execFile( process.execPath, ['--use-env-proxy', fileURLToPath(import.meta.url)], { env: childEnv, encoding: 'utf8', timeout: 8_000, maxBuffer: 64 * 1024 }, (error, stdout, stderr) => { if (error) { reject(new Error(`env proxy child failed: ${stderr.trim() || error.message}`)); return; } resolve(stdout.trim()); }, ); }); assert.ok(!output.includes(SECRET)); const result = JSON.parse(output); assert.equal(result.allowedStatus, 200); assert.ok(result.deniedStatus === 403 || result.deniedStatus === 'error'); const allowed = result.events.find((event) => event.decision === 'allow'); const denied = result.events.find((event) => event.decision === 'deny'); assert.equal(allowed?.target, `${ALLOWED_HOST}:${ALLOWED_PORT}`); assert.equal(denied?.target, `${DENIED_HOST}:${ALLOWED_PORT}`); if (allowed.transport === 'absolute-form') assert.equal(allowed.absoluteUrl, true); return { nodeFlag: '--use-env-proxy', allowedTransport: allowed.transport, allowedTarget: allowed.target, deniedTarget: denied.target, cleanChildEnvironment: true, secretRetained: false, }; } async function runDirectBypassChecks() { const hits = { http: 0, raw: 0, childRaw: 0, ipv6: 0, dns: 0 }; const httpServer = http.createServer((req, res) => { hits.http += 1; res.end('direct-http'); }); const rawServer = net.createServer((socket) => { socket.once('data', (data) => { const kind = data.toString() === 'child' ? 'childRaw' : 'raw'; hits[kind] += 1; socket.end('ok'); }); }); const ipv6Server = net.createServer((socket) => { hits.ipv6 += 1; socket.end('ok'); }); const dnsServer = dgram.createSocket('udp4'); dnsServer.on('message', (message, remote) => { hits.dns += 1; const response = Buffer.from(message); response[2] = 0x81; response[3] = 0x83; response.writeUInt16BE(0, 6); response.writeUInt16BE(0, 8); response.writeUInt16BE(0, 10); dnsServer.send(response, remote.port, remote.address); }); const servers = [httpServer, rawServer, ipv6Server, dnsServer]; try { const httpAddress = await listen(httpServer, '127.0.0.1'); const rawAddress = await listen(rawServer, '127.0.0.1'); const ipv6Address = await listen(ipv6Server, '::1'); const dnsAddress = await listen(dnsServer, '127.0.0.1'); const directHttp = await new Promise((resolve, reject) => { const request = http.get(`http://127.0.0.1:${httpAddress.port}/direct`, (response) => { response.resume(); response.on('end', () => resolve(response.statusCode)); }); request.on('error', reject); }); assert.equal(directHttp, 200); assert.equal(await rawExchange('127.0.0.1', rawAddress.port, 'parent'), 'ok'); assert.equal(await rawExchange('::1', ipv6Address.port, 'ipv6'), 'ok'); const childResult = await runNode(` const net = require('node:net'); const socket = net.createConnection({ host: '127.0.0.1', port: ${rawAddress.port} }); socket.on('connect', () => socket.end('child')); socket.on('close', () => process.exit(0)); socket.on('error', (error) => { console.error(error); process.exit(1); }); `, { HTTP_PROXY: 'http://127.0.0.1:9', HTTPS_PROXY: 'http://127.0.0.1:9', NO_PROXY: '', }); assert.equal(childResult, ''); const resolver = new Resolver(); resolver.setServers([`127.0.0.1:${dnsAddress.port}`]); await resolver.resolve4(`dns-${SECRET.toLowerCase()}.invalid`).catch(() => {}); assert.deepEqual(hits, { http: 1, raw: 1, childRaw: 1, ipv6: 1, dns: 1 }); return { demonstrated: ['node:http', 'raw-tcp-ipv4', 'spawned-child-raw-tcp', 'raw-tcp-ipv6', 'direct-dns'], meaning: 'these transports bypass HTTP_PROXY and must be stopped by the OS boundary', }; } finally { for (const server of servers) { try { close(server); } catch {} } } } if (process.env.MAESTRO_EGRESS_PROXY_CHILD === '1') { const port = Number(process.env.MAESTRO_EGRESS_PROXY_PORT); assert.ok(Number.isInteger(port) && port > 0); const childResult = await runActualEnvProxyChild(port); const childOutput = JSON.stringify(childResult); assert.ok(!childOutput.includes(SECRET)); console.log(childOutput); process.exit(0); } const templates = await validateTemplates(); const envProxyRuntime = await runActualEnvProxyCheck(); const proxyPolicy = await runProxyChecks(); const proxyScope = await runDirectBypassChecks(); const result = { ok: true, externalNetworkUsed: false, hostIsolationApplied: false, templates, envProxyRuntime, proxyPolicy, proxyScope, }; const output = JSON.stringify(result, null, 2); assert.ok(!output.includes(SECRET)); console.log(output);