From 686ab951d1b63ebfffa5bbe42e849ab480f45821 Mon Sep 17 00:00:00 2001 From: G Date: Sat, 25 Oct 2025 02:21:42 +0300 Subject: [PATCH] updated docs with dns-exfiltration-safe defaults and security note --- README.md | 5 ++--- docs/api/endpoints/sandboxes.mdx | 4 ++-- docs/api/security.mdx | 8 ++++++-- docs/guides/cli.mdx | 7 ++++--- docs/guides/python-sdk.mdx | 5 ++--- 5 files changed, 16 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 8affdef..5dd0194 100644 --- a/README.md +++ b/README.md @@ -185,10 +185,9 @@ name: my-sandbox-123 image: alpine:latest namespace: default -# Optional: restrict egress +# Optional: restrict egress (safe pattern: whitelist only your own egress proxy IP) egress_whitelist: - - "1.1.1.1/32" # Cloudflare DNS - - "8.8.8.8/32" # Google DNS + - "10.0.0.5/32" # Your private egress proxy/gateway # Optional: resource limits limits: diff --git a/docs/api/endpoints/sandboxes.mdx b/docs/api/endpoints/sandboxes.mdx index 89ebea5..986b7a2 100644 --- a/docs/api/endpoints/sandboxes.mdx +++ b/docs/api/endpoints/sandboxes.mdx @@ -32,14 +32,14 @@ Body example: } ``` -Body example with egress whitelist: +Body example with egress whitelist (safe pattern: proxy IP only): ```json { "name": "my-restricted-sandbox", "image": "alpine:latest", "namespace": "default", - "egress_whitelist": ["1.1.1.1/32", "8.8.8.8/32"], + "egress_whitelist": ["10.0.0.5/32"], "limits": {"cpu": "500m", "memory": "512Mi"} } ``` diff --git a/docs/api/security.mdx b/docs/api/security.mdx index ba7bc19..608a6f4 100644 --- a/docs/api/security.mdx +++ b/docs/api/security.mdx @@ -105,12 +105,12 @@ Partial isolation (no inter-VM communication, but external internet allowed): { "name": "partial-isolation", "image": "alpine:latest" } ``` -Whitelist specific external services: +Whitelist specific external services (avoid public DNS resolvers): ```json { "name": "egress-restricted", "image": "alpine:latest", - "egress_whitelist": ["1.1.1.1/32", "8.8.8.8/32"] + "egress_whitelist": ["10.0.0.5/32"] } ``` @@ -121,6 +121,10 @@ Whitelist specific external services: - **Administrative access**: `kubectl exec`, `k7 shell`, and API operations bypass network policies + +Do not whitelist public DNS resolver IPs (e.g., 1.1.1.1, 8.8.8.8). Because K7's `egress_whitelist` is CIDR-only (no L7/port rules), allowing those IPs enables outbound DNS (UDP/TCP 53) and DNS-over-HTTPS (443), which can be used for exfiltration. If you want an egress deny with whitelisting, prefer whitelisting only your own egress proxy/gateway IP and enforce DNS/DoH policy at that proxy. Later, whenever we integrate Cilium (a roadmap feature), it will be much simpler as you'll be able to whitelist domain names directly. + + ### Mitigations when DNS is blocked - Use IP/CIDR whitelisting only (no domains post-lockdown) diff --git a/docs/guides/cli.mdx b/docs/guides/cli.mdx index 6059ef2..89f10fd 100644 --- a/docs/guides/cli.mdx +++ b/docs/guides/cli.mdx @@ -32,7 +32,7 @@ k7 create -f k7.yaml # or k7 create --name my-sb --image alpine:latest \ --cpu 1 --memory 1Gi --storage 2Gi \ - --env-file .env --egress 1.1.1.1/32 --egress 8.8.8.8/32 \ + --env-file .env --egress 10.0.0.5/32 \ --before-script "apk add curl" ``` @@ -63,8 +63,7 @@ name: project-build image: alpine:latest namespace: default egress_whitelist: - - "1.1.1.1/32" # Cloudflare DNS - - "8.8.8.8/32" # Google DNS + - "10.0.0.5/32" # Private egress proxy/gateway limits: cpu: "1" memory: "1Gi" @@ -81,6 +80,8 @@ cap_add: ``` +Do not whitelist public DNS resolvers (e.g., 1.1.1.1, 8.8.8.8). Doing so re-enables DNS exfiltration (UDP/TCP 53 and DoH over 443). Prefer whitelisting only your own egress proxy IP and enforce DNS/DoH policies at the proxy. + If using package managers that require root (e.g., `apk add`, `apt-get install`) in `before_script` make sure you didn't add security policies that prevent it such as running the pod or container as non-root. Check Security & Networking section in the API reference for more. diff --git a/docs/guides/python-sdk.mdx b/docs/guides/python-sdk.mdx index 4ade913..767bb36 100644 --- a/docs/guides/python-sdk.mdx +++ b/docs/guides/python-sdk.mdx @@ -22,7 +22,7 @@ sb = k7.create({ "image": "alpine:latest", # optional: "namespace": "default", # optional: "env_file": ".env", - # optional: "egress_whitelist": ["1.1.1.1/32", "8.8.8.8/32"], + # optional: "egress_whitelist": ["10.0.0.5/32"], # private egress proxy # optional: "limits": {"cpu": "1", "memory": "1Gi", "ephemeral-storage": "2Gi"}, # optional: "before_script": "apk add curl" }) @@ -70,8 +70,7 @@ sb = k7.create({ # - [] blocks all egress (DNS blocked) # - [CIDRs] allows only those CIDRs (DNS still blocked) "egress_whitelist": [ - "1.1.1.1/32", - "8.8.8.8/32", + "10.0.0.5/32", # private egress proxy "203.0.113.0/24" ],