INTEGRITY Dokumentace

Zpracování odchozího provozu

Outbound handlery vám pomocí důvěryhodného kódu umožňují zachytávat a upravovat HTTP provoz ze sandboxu.

Použijte je k:

Blokujte odchozí provoz

Použijte enableInternet = false pro výchozí blokování přístupu z veřejného internetu:

import { Sandbox } from "@cloudflare/sandbox";

export class MySandbox extends Sandbox {
	enableInternet = false;
}
import { Sandbox } from "@cloudflare/sandbox";

export class MySandbox extends Sandbox {
	enableInternet = false;
}

Když enableInternet je false, pouze provoz, který na této stránce dále explicitně povolíte prostřednictvím allowedHosts nebo výstupní (outbound) handlery mohou sandbox opustit. Pouze porty 80, 443, a DNS jsou dostupné, přičemž DNS dotazy používají DNS servery Cloudflare.

Blokujte nebo povolujte provoz podle hostitele

Odchozí provoz můžete filtrovat pomocí allowedHosts a deniedHosts vlastnosti třídy Sandbox.

Když allowedHosts je nastaven, stane se allowlistem s výchozím zamítnutím. Každý host nebo IP adresa mimo seznam je zamítnuta a spojit se lze jen s outbound nebo outboundByHost handlery.

allowedHosts a deniedHosts podporují také jednoduché glob vzory, kde * odpovídá libovolné posloupnosti znaků.

Sandbox ve výchozím nastavení povoluje přístup k internetu a můžete nastavit deniedHosts pro zakázání konkrétních hostitelů nebo IP adres:

import { Sandbox, ContainerProxy } from "@cloudflare/sandbox";
export { ContainerProxy };

export class MySandbox extends Sandbox {
	deniedHosts = ["some-nefarious-website.com", "141.101.64.0/18"];
}
import { Sandbox, ContainerProxy } from "@cloudflare/sandbox";
export { ContainerProxy };

export class MySandbox extends Sandbox {
	deniedHosts = ["some-nefarious-website.com", "141.101.64.0/18"];
}

Přístup k internetu můžete také ve výchozím nastavení zakázat a povolit jen konkrétní hostitele a IP adresy:

import { Sandbox, ContainerProxy } from "@cloudflare/sandbox";
export { ContainerProxy };

export class MySandbox extends Sandbox {
	// default internet access to off unless overridden by 'allowedHosts' or outbound proxy
	enableInternet = false;

	// overrides enableInternet = false
	allowedHosts = ["allowed.com"];
}
import { Sandbox, ContainerProxy } from "@cloudflare/sandbox";
export { ContainerProxy };

export class MySandbox extends Sandbox {
	// default internet access to off unless overridden by 'allowedHosts' or outbound proxy
	enableInternet = false;

	// overrides enableInternet = false
	allowedHosts = ["allowed.com"];
}

Definujte obslužné rutiny pro odchozí provoz

Outbound handlery jsou programovatelné proxy pro odchozí provoz, které běží na stejném počítači jako sandbox. Mají přístup ke všem Workers bindings.

Použijte outbound k zachycení veškerého odchozího provozu HTTP a HTTPS:

import { Sandbox, ContainerProxy } from "@cloudflare/sandbox";
export { ContainerProxy };

export class MySandbox extends Sandbox {}

MySandbox.outbound = async (request, env, ctx) => {
	if (request.method !== "GET") {
		console.log(`Blocked ${request.method} to ${request.url}`);
		return new Response("Method Not Allowed", { status: 405 });
	}
	return fetch(request);
};
import { Sandbox, ContainerProxy } from "@cloudflare/sandbox";
export { ContainerProxy };

export class MySandbox extends Sandbox {}

MySandbox.outbound = async (
	request: Request,
	env: Env,
	ctx: OutboundHandlerContext,
) => {
	if (request.method !== "GET") {
		console.log(`Blocked ${request.method} to ${request.url}`);
		return new Response("Method Not Allowed", { status: 405 });
	}
	return fetch(request);
};

Použijte outboundByHost k namapování konkrétních doménových jmen nebo IP adres na obslužné funkce:

import { Sandbox, ContainerProxy } from "@cloudflare/sandbox";
export { ContainerProxy };

export class MySandbox extends Sandbox {}

MySandbox.outboundByHost = {
	"my.worker": async (request, env, ctx) => {
		// Run arbitrary Workers logic from this hostname
		return await someWorkersFunction(request.body);
	},
};
import { Sandbox, ContainerProxy } from "@cloudflare/sandbox";
export { ContainerProxy };

export class MySandbox extends Sandbox {}

MySandbox.outboundByHost = {
	"my.worker": async (
		request: Request,
		env: Env,
		ctx: OutboundHandlerContext,
	) => {
		// Run arbitrary Workers logic from this hostname
		return await someWorkersFunction(request.body);
	},
};

Volání na http://my.worker ze sandboxu volají handler, který běží uvnitř Workers runtime, mimo sandbox.

deniedHosts a allowedHosts se vyhodnocují před jakýmkoli outbound handlerem. Pokud používáte allowedHosts, uveďte tam hostname buď pro outbound nebo outboundByHost ke spuštění. outboundByHost handlery mají přednost před catch-all outbound handlery.

Bezpečně vkládejte přihlašovací údaje

Obslužné rutiny pro odchozí provoz běží v runtime Workers, tedy mimo sandbox, a proto mohou pracovat s tajnými údaji, ke kterým samotný sandbox nemá přístup. Sandbox odešle obyčejný HTTP požadavek a obslužná rutina k němu před předáním navazující službě připojí přihlašovací údaj.

export class MySandbox extends Sandbox {}

MySandbox.outboundByHost = {
	"github.com": (request, env, ctx) => {
		const requestWithAuth = new Request(request);
		requestWithAuth.headers.set("x-auth-token", env.SECRET);
		return fetch(requestWithAuth);
	},
};
export class MySandbox extends Sandbox {}

MySandbox.outboundByHost = {
	"github.com": (request: Request, env: Env, ctx: OutboundHandlerContext) => {
		const requestWithAuth = new Request(request);
		requestWithAuth.headers.set("x-auth-token", env.SECRET);
		return fetch(requestWithAuth);
	},
};

Je to užitečné zejména pro agentní úlohy, kde nelze kódu běžícímu uvnitř sandboxu plně důvěřovat. Při tomto vzoru:

Zde ctx.containerId vyhledá klíč pro danou instanci v KV:

export class MySandbox extends Sandbox {}

MySandbox.outboundByHost = {
	"my-internal-vcs.dev": async (request, env, ctx) => {
		const authKey = await env.KEYS.get(ctx.containerId);

		const requestWithAuth = new Request(request);
		requestWithAuth.headers.set("x-auth-token", authKey);
		return fetch(requestWithAuth);
	},
};
export class MySandbox extends Sandbox {}

MySandbox.outboundByHost = {
	"my-internal-vcs.dev": async (
		request: Request,
		env: Env,
		ctx: OutboundHandlerContext,
	) => {
		const authKey = await env.KEYS.get(ctx.containerId);

		const requestWithAuth = new Request(request);
		requestWithAuth.headers.set("x-auth-token", authKey);
		return fetch(requestWithAuth);
	},
};

Provoz HTTPS

Sandboxy standardně zachytávají HTTPS provoz: interceptHttps je nastaveno na true ve třídě Sandbox.

Pokud je aktivní zachytávání HTTPS, vytvoří se dočasný soubor CA na adrese /etc/cloudflare/certs/cloudflare-containers-ca.crt jakmile se sandbox spustí.

Sandbox runtime se snaží této CA důvěřovat automaticky bez ohledu na distribuci. Při spuštění zkontroluje obvyklá umístění systémových CA bundlů napříč hlavními rodinami Linuxu a nastaví běžné proměnné prostředí pro CA, aby ji runtime prostředí jako Node.js, curl, Python requests, a Git certifikátu důvěřují automaticky.

Provoz jiný než HTTP

Outbound handlery zachytávají pouze provoz HTTP a HTTPS. Provoz na portech jiných než 80 a 443 se nikdy nesměruje přes outbound nebo outboundByHost.

Pokud nastavíte enableInternet = false, takový provoz je zamítnut. Jedinou výjimkou jsou dotazy DNS, které však směřují pouze na servery DNS Cloudflare. Tím se zabraňuje zneužití libovolných cílů DNS k exfiltraci dat.

Měňte zásady za běhu

Použijte outboundHandlers pro definování pojmenovaných handlerů a jejich následné přiřazení konkrétním hostitelům za běhu pomocí setOutboundByHost(). Handler můžete také použít globálně pomocí setOutboundHandler().

Zásady runtime můžete také spravovat pomocí setOutboundByHosts(), setAllowedHosts(), setDeniedHosts(), allowHost(), denyHost(), removeAllowedHost(), a removeDeniedHost().

Díky tomu může důvěryhodný Worker držet přihlašovací údaje, aniž by je vystavoval nedůvěryhodnému sandboxu:

import { Sandbox, ContainerProxy } from "@cloudflare/sandbox";
export { ContainerProxy };

export class MySandbox extends Sandbox {}

MySandbox.outboundHandlers = {
	authenticatedGithub: async (request, env, ctx) => {
		const githubToken = env.GITHUB_TOKEN;
		return authenticateGitHttpsRequest(request, githubToken, ctx.containerId);
	},
};
import { Sandbox, ContainerProxy } from "@cloudflare/sandbox";
export { ContainerProxy };

export class MySandbox extends Sandbox {}

MySandbox.outboundHandlers = {
	authenticatedGithub: async (
		request: Request,
		env: Env,
		ctx: OutboundHandlerContext,
	) => {
		const githubToken = env.GITHUB_TOKEN;
		return authenticateGitHttpsRequest(request, githubToken, ctx.containerId);
	},
};

Handlery aplikujte na hosty programově přímo z Workeru:

import { Sandbox, ContainerProxy, getSandbox } from "@cloudflare/sandbox";
export { ContainerProxy };

export default {
	async fetch(request, env) {
		const sandbox = getSandbox(env.Sandbox, "agent-session");

		// Give the sandbox access to github.com during setup
		await sandbox.setOutboundByHost("github.com", "authenticatedGithub");
		await sandbox.exec("node setup.js");

		// Remove access once setup is complete
		await sandbox.removeOutboundByHost("github.com");
	},
};
import { Sandbox, ContainerProxy, getSandbox } from "@cloudflare/sandbox";
export { ContainerProxy };

export default {
	async fetch(request: Request, env: Env) {
		const sandbox = getSandbox(env.Sandbox, "agent-session");

		// Give the sandbox access to github.com during setup
		await sandbox.setOutboundByHost("github.com", "authenticatedGithub");
		await sandbox.exec("node setup.js");

		// Remove access once setup is complete
		await sandbox.removeOutboundByHost("github.com");
	},
};

Priorita handlerů

Požadavky se vyhodnocují v tomto pořadí:

  1. deniedHosts se kontroluje jako první. Odpovídající hosty nebo IP adresy jsou okamžitě zamítnuty.
  2. allowedHosts se kontroluje jako další. Pokud je nastaven, každý host nebo IP adresa, které nejsou na seznamu, jsou zamítnuty. Odpovídající hosty pokračují k outbound handlerům, nebo pokud žádný handler není nastaven, do veřejného internetu.
  3. Pravidla na úrovni instance nastavená pomocí setOutboundByHost() se kontrolují před úrovní třídy outboundByHost pravidla.
  4. Obslužné rutiny pro jednotlivé hostitele mají vždy přednost před univerzálními obslužnými rutinami, takže outboundByHost se spustí před outbound.
  5. Obslužné rutiny na úrovni instance nastavené pomocí setOutboundHandler() se kontrolují před danou úrovní třídy outbound handler.
  6. Pokud neodpovídá žádný handler, požadavek může přesto opustit síť do veřejného internetu, pokud odpovídal allowedHosts nebo enableInternet = true. V opačném případě je operace zamítnuta.

Lokální vývoj

wrangler dev podporuje zachytávání odchozích požadavků. Uvnitř síťového jmenného prostoru sandboxu se spustí sidecar proces. Ten aplikuje TPROXY pravidla pro směrování odpovídajícího provozu na lokální instanci Workerd, což odpovídá chování v produkci.