← Containers / containers / platform-details
Zpracování odchozího provozu
Odchozí handlery umožňují pomocí důvěryhodného kódu zachytávat a upravovat HTTP provoz z kontejneru.
Použijte je k:
- Povolte nebo zamítněte konkrétní cílové origin servery
- Bezpečně vkládejte autorizační hlavičky nebo tokeny
- Transparentně přesměrovat provoz
- Přidejte vlastní zásadu pro odchozí provoz (například zamítnutí konkrétních HTTP požadavků)
- Připojte se k Workers bindings jako KV, R2 a Durable Objects
Blokujte odchozí provoz
Použijte enableInternet = false pro výchozí blokování přístupu z veřejného internetu:
import { Container } from "@cloudflare/containers";
export class MyContainer extends Container {
enableInternet = false;
}Když enableInternet je false, pouze provoz, který na této stránce dále explicitně povolíte prostřednictvím allowedHosts nebo obslužné rutiny odchozího provozu mohou kontejner 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 Container.
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ů.
Ve výchozím nastavení Container povoluje přístup k internetu a můžete nastavit deniedHosts k
zakázání konkrétních hostitelů nebo IP adres:
import { Container, ContainerProxy } from "@cloudflare/containers";
export { ContainerProxy };
export class MyContainer extends Container {
// Make sure the container trusts /etc/cloudflare/certs/cloudflare-containers-ca.crt
interceptHttps = true;
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 { Container, ContainerProxy } from "@cloudflare/containers";
export { ContainerProxy };
export class MyContainer extends Container {
// Make sure the container trusts /etc/cloudflare/certs/cloudflare-containers-ca.crt
interceptHttps = true;
// 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
Odchozí handlery jsou programovatelné proxy servery pro odchozí provoz, které běží na stejném počítači jako kontejner. Mají přístup ke všem vazbám Workers.
Použijte outbound k zachycení veškerého provozu HTTP a HTTPS:
import { Container, ContainerProxy } from "@cloudflare/containers";
export { ContainerProxy };
export class MyContainer extends Container {
interceptHttps = true;
}
MyContainer.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);
};Použijte outboundByHost k namapování konkrétních názvů domén nebo IP adres na proxy funkce:
import { Container, ContainerProxy } from "@cloudflare/containers";
export { ContainerProxy };
export class MyContainer extends Container {
interceptHttps = true;
}
MyContainer.outboundByHost = {
"my.worker": async (request, env, ctx) => {
// Run arbitrary Workers logic from this hostname
return await someWorkersFunction(request.body);
},
};Volání na http://my.worker z kontejneru vyvolávají handler, který běží uvnitř Workers runtime, mimo sandbox kontejneru.
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
Protože odchozí handlery běží v runtime Workers, mimo sandbox kontejneru, mohou obsahovat tajné údaje, ke kterým se samotný kontejner nikdy nedostane. Kontejner odešle běžný HTTP požadavek a handler k němu před předáním nadřazené službě připojí přihlašovací údaje.
export class MyContainer extends Container {
// Make sure the container trusts /etc/cloudflare/certs/cloudflare-containers-ca.crt
interceptHttps = true;
}
MyContainer.outboundByHost = {
"github.com": (request, env, ctx) => {
const requestWithAuth = new Request(request);
requestWithAuth.headers.set("x-auth-token", env.SECRET);
return fetch(requestWithAuth);
},
};To je užitečné zejména pro agentní úlohy, kde nemůžete kódu spuštěnému uvnitř kontejneru plně důvěřovat. Při tomto přístupu:
- Kontejneru není zpřístupněn žádný token. Tajný klíč zůstává v prostředí Workeru a do sandboxu se nikdy nepředává.
- Uvnitř kontejneru neprobíhá rotace tokenů. Otočte tajný klíč v prostředí svého Workeru a každý požadavek ho ihned zohlední.
- Pravidla pro jednotlivé hostitele a instance. Kombinujte
outboundByHosthodnotouctx.containerIdk omezení přihlašovacích údajů nebo oprávnění na konkrétní instanci kontejneru.
Zde ctx.containerId vyhledá klíč pro danou instanci v KV:
export class MyContainer extends Container {
// Make sure the container trusts /etc/cloudflare/certs/cloudflare-containers-ca.crt
interceptHttps = true;
}
MyContainer.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);
},
};Provoz HTTPS
Ve výchozím nastavení odchozí handlery provoz HTTPS nezachytávají. Pokud to chcete povolit,
musíte nastavit interceptHttps atribut.
export class MyContainer extends Container {
// Make sure the container trusts /etc/cloudflare/certs/cloudflare-containers-ca.crt
interceptHttps = true;
}
MyContainer.outbound = (req, env, ctx) => {
// All HTTP(S) requests will trigger this hook.
return fetch(req);
};To se hodí pro služby podobné sandboxu, které přesměrovávají nedůvěryhodný provoz z instance kontejneru na Workers kvůli filtrování a úpravám.
Když je aktivní zachytávání HTTPS, vytvoří se dočasný soubor CA na /etc/cloudflare/certs/cloudflare-containers-ca.crt jakmile se váš kontejner spustí. CA se vloží pouze v případě, že současně nastavíte interceptHttps = true a definujte outbound nebo outboundByHost handler.
Důvěřovat certifikátu CA
Aby fungovalo zachytávání HTTPS, musíte důvěřovat souboru CA. CA je dočasná a existuje pouze za běhu, proto se ji nesnažte zapéct do obrazu během docker build. Místo toho jej zkopírujte do úložiště důvěryhodných certifikátů vaší distribuce a aktualizujte toto úložiště z kontejneru entrypoint před spuštěním vaší aplikace.
Pokud váš základní obraz ještě neobsahuje nástroje pro trust store, nainstalujte ca-certificates balíček do vašeho image nejdříve.
import { Container, ContainerProxy } from "@cloudflare/containers";
export { ContainerProxy };
export class MyContainer extends Container {
interceptHttps = true;
entrypoint = [
"sh",
"-lc",
[
"cp /etc/cloudflare/certs/cloudflare-containers-ca.crt /usr/local/share/ca-certificates/cloudflare-containers-ca.crt",
"update-ca-certificates",
"exec node server.js",
].join(" && "),
];
}import { Container, ContainerProxy } from "@cloudflare/containers";
export { ContainerProxy };
export class MyContainer extends Container {
interceptHttps = true;
entrypoint = [
"sh",
"-lc",
[
"cp /etc/cloudflare/certs/cloudflare-containers-ca.crt /usr/local/share/ca-certificates/cloudflare-containers-ca.crt",
"update-ca-certificates",
"exec node server.js",
].join(" && "),
];
}import { Container, ContainerProxy } from "@cloudflare/containers";
export { ContainerProxy };
export class MyContainer extends Container {
interceptHttps = true;
entrypoint = [
"sh",
"-lc",
[
"cp /etc/cloudflare/certs/cloudflare-containers-ca.crt /etc/pki/ca-trust/source/anchors/cloudflare-containers-ca.crt",
"update-ca-trust",
"exec node server.js",
].join(" && "),
];
}import { Container, ContainerProxy } from "@cloudflare/containers";
export { ContainerProxy };
export class MyContainer extends Container {
interceptHttps = true;
entrypoint = [
"sh",
"-lc",
[
"cp /etc/cloudflare/certs/cloudflare-containers-ca.crt /etc/ca-certificates/trust-source/anchors/cloudflare-containers-ca.crt",
"trust extract-compat",
"exec node server.js",
].join(" && "),
];
}Nahraďte node server.js s příkazem, který spouští vaši aplikaci.
Většina runtime prostředí pak automaticky důvěřuje CA prostřednictvím systémového úložiště kořenových certifikátů. Pokud vaše runtime prostředí používá vlastní sadu CA certifikátů, nasměrujte ji na /etc/cloudflare/certs/cloudflare-containers-ca.crt přímo, například pomocí NODE_EXTRA_CA_CERTS nebo REQUESTS_CA_BUNDLE.
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 kontejneru:
export class MyContainer extends Container {
// Make sure the container trusts /etc/cloudflare/certs/cloudflare-containers-ca.crt
interceptHttps = true;
}
MyContainer.outboundHandlers = {
authenticatedGithub: async (request, env, ctx) => {
const githubToken = env.GITHUB_TOKEN;
return authenticateGitHttpsRequest(request, githubToken, ctx.containerId);
},
};Handlery aplikujte na hosty programově přímo z Workeru:
async setUpContainer(req, env) {
const container = await env.MY_CONTAINER.getByName("my-instance");
// Give the container access to github.com on a specific host during setup
await container.setOutboundByHost("github.com", "authenticatedGithub");
// do something with github.com on your container...
}
async removeAccessToGithub(req, env) {
const container = await env.MY_CONTAINER.getByName("my-instance");
// Remove access to Github
await container.removeOutboundByHost("github.com");
}Priorita handlerů
Požadavky se vyhodnocují v tomto pořadí:
deniedHostsse kontroluje jako první. Odpovídající hosty nebo IP adresy jsou okamžitě zamítnuty.allowedHostsse 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.- Pravidla na úrovni instance nastavená pomocí
setOutboundByHost()se kontrolují před úrovní třídyoutboundByHostpravidla. - Obslužné rutiny pro jednotlivé hostitele mají vždy přednost před univerzálními obslužnými rutinami, takže
outboundByHostse spustí předoutbound. - Obslužné rutiny na úrovni instance nastavené pomocí
setOutboundHandler()se kontrolují před danou úrovní třídyoutboundhandler. - Pokud neodpovídá žádný handler, požadavek může přesto opustit síť do veřejného internetu, pokud odpovídal
allowedHostsneboenableInternet = true. V opačném případě je operace zamítnuta.
Nízkoúrovňové API
Pro konfiguraci zachytávání odchozího provozu přímo na ctx.container, použijte interceptOutboundHttp pro konkrétní glob hostname, IP nebo rozsah CIDR,
nebo interceptAllOutboundHttp pro veškerý provoz. Oba přijímají WorkerEntrypoint.
import { WorkerEntrypoint } from "cloudflare:workers";
export class MyOutboundWorker extends WorkerEntrypoint {
fetch(request) {
// Inspect, modify, or deny the request before passing it on
return fetch(request);
}
}
// Inside your Container DurableObject
this.ctx.container.start({ enableInternet: false });
const worker = this.ctx.exports.MyOutboundWorker({ props: {} });
await this.ctx.container.interceptAllOutboundHttp(worker);Tyto metody můžete volat před spuštěním kontejneru nebo po něm, a to i v době, kdy jsou spojení otevřená. Právě probíhající TCP spojení automaticky přejmou nový handler, žádná spojení se přitom nepřeruší.
// Intercept a specific CIDR range
await this.ctx.container.interceptOutboundHttp("203.0.113.0/24", worker);
// Intercept by hostname
this.ctx.container.interceptOutboundHttp("foo.com", worker);
// Update the handler while the container is running
const updated = this.ctx.exports.MyOutboundWorker({
props: { phase: "post-install" },
});
await this.ctx.container.interceptOutboundHttp("203.0.113.0/24", updated);Pro HTTPS, interceptOutboundHttps funguje stejně jako interceptOutboundHttp.
// Intercept a specific hostname
this.ctx.container.interceptOutboundHttps("foo.com", worker);
// Intercept all traffic
this.ctx.container.interceptOutboundHttps("*", worker); Container třída tyto metody volá automaticky, když použijete výše uvedené funkce. Můžete je také zavolat přímo pro případy, které tato třída nepokrývá.
Lokální vývoj
wrangler dev podporuje zachytávání odchozího provozu. Uvnitř síťového jmenného prostoru kontejneru se spustí sidecar proces, který aplikuje TPROXY pravidla pro směrování odpovídajícího provozu na lokální instanci Workerd, což odpovídá chování v produkci.
Související zdroje
- Připojte se k Workers bindings : Přístup ke KV, R2, Durable Objects a dalším vazbám z kontejneru
- Řízení odchozího provozu (Sandboxes) : Sandbox SDK API pro odchozí handlery
- Proměnné prostředí a secrets : Konfigurace secrets a proměnných prostředí
- Rozhraní Durable Object : Úplný
ctx.containerreferenční dokumentace API