From 60aac8f9ddf54f910cd90b2e968eab68c46132fa Mon Sep 17 00:00:00 2001 From: Manuel de Brito Fontes Date: Wed, 4 Nov 2026 10:01:45 -0300 Subject: [PATCH] network: DNS follows the policy, and offline asks nothing Co-Authored-By: Claude Opus 5.5 --- src/content/docs/concepts/network.mdx | 21 +++++++++++++++++---- src/content/docs/security/index.md | 5 +++-- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/content/docs/concepts/network.mdx b/src/content/docs/concepts/network.mdx index b07abef..f5650f8 100644 --- a/src/content/docs/concepts/network.mdx +++ b/src/content/docs/concepts/network.mdx @@ -14,7 +14,7 @@ inside the workspace — even as root — can change them. [Egress is closed by default](). A workspace created without `--network-tag` runs under the installation's `default_network_tags`. If the installation has not set any, it runs under **`offline`**, which -every runner has and which allows nothing. +every runner has and which allows nothing, a DNS question included. No setting means "open". An installation that wants workspaces to reach the internet by default declares a policy that says so, for example `allow: ["0.0.0.0/0"]`, and names it in @@ -58,9 +58,22 @@ allows them all. **Tags add up.** A workspace with two tags reaches everything either one allows. -**DNS always works.** A workspace's resolver is the runner's, which answers under every policy, -so no policy needs to open port 53. It removes from its answers any address of the runner's own -networks, and every IPv6 answer. +**DNS follows the policy.** A workspace's resolver is the runner's, so no policy needs to open +port 53. A DNS question leaves from the runner, where no firewall rule sees it, and reaches whoever +answers that name, so the resolver only takes up the ones a workspace's policy names: + +- A workspace with no tag, or with a rule that reaches every address (ports with no destination, + or `0.0.0.0/0`), resolves anything. DNS gives it nothing it could not already do. +- Under any other policy, a name one of its rules names resolves, wildcards included, in any + record type. Any other question is answered `REFUSED` and goes no further, and + `spin workspace egress` lists it. +- Under `offline`, nothing goes up. A rule of narrow `allow` prefixes names nothing either, so a + workspace under one alone reaches those addresses and resolves no name: add the names to the rule. + +Allowing a name trusts whoever answers it, as much for what it asks them as for the address they +send a connection to, so a wildcard over a domain anyone can publish under is a way out. The +resolver also removes from its answers any address of the runner's own networks, and every IPv6 +answer.
diff --git a/src/content/docs/security/index.md b/src/content/docs/security/index.md index 2025dcd..95a65fb 100644 --- a/src/content/docs/security/index.md +++ b/src/content/docs/security/index.md @@ -23,8 +23,9 @@ else is built so that being root in a workspace gives nothing outside it. - **[Isolation](/security/isolation/).** Every workspace is a virtual machine with its own kernel. Its QEMU runs as its own user, in an empty network namespace and a bounded cgroup, and reaches nothing on the host but what it is handed. -- **Network.** A workspace reaches nothing until a policy allows it, never reaches the runner's - own networks or the cloud's metadata service, and cannot be reached from the network at all. +- **Network.** A workspace reaches nothing until a policy allows it, a DNS question for a name the + policy does not name included, never reaches the runner's own networks or the cloud's metadata + service, and cannot be reached from the network at all. See [Network and egress](/concepts/network/) and [Network on AWS](/aws/network/). - **[Data and encryption](/security/data/).** Every layer of every disk is encrypted with its volume's key before it leaves the runner. Keys are wrapped under a key the database does not