# How CubeSandbox Implements Per-Instance DNS Configuration and Network Isolation

> CubeSandbox uses TAP network namespaces, eBPF, and CoreDNS sidecars to implement per-instance DNS configuration and network isolation. Learn how it works.

- Repository: [Tencent Cloud/CubeSandbox](https://github.com/TencentCloud/CubeSandbox)
- Tags: internals
- Published: 2026-07-11

---

**CubeSandbox achieves per-instance DNS configuration and network isolation by combining TAP-based network namespaces, eBPF policy maps, and CoreDNS sidecars that consume the DNSConfig protobuf definitions from the Cubebox API.**

CubeSandbox, TencentCloud's container sandbox runtime, provides granular control over DNS resolution and network boundaries for each sandbox instance. Understanding how the platform configures **DNS configuration and network isolation per instance** requires examining the interplay between the Cubelet API definitions, the network-agent's TAP device management, and the eBPF-based policy enforcement in CubeVS.

## Per-Sandbox DNS Configuration via DNSConfig

### API Schema and Protobuf Definitions

The foundation of per-instance DNS control lies in the `DNSConfig` message defined in `Cubelet/api/services/cubebox/v1/cubebox.proto` and mirrored in `CubeMaster/api/services/cubebox/v1/cubebox.proto`. This schema includes the `dns_config` field (containing a list of nameserver IPs) that is copied into the sandbox's network-namespace configuration during creation.

### Default Nameservers and Fallback Behavior

When custom DNS servers are not specified, CubeSandbox falls back to the values defined in [`Cubelet/dynamicconf/conf.yaml`](https://github.com/TencentCloud/CubeSandbox/blob/main/Cubelet/dynamicconf/conf.yaml). This configuration file provides the guest container default DNS settings, which are overridden when a template specifies `dns_config.servers`.

### SDK and Web Interface Exposures

Both the Python and Go SDKs surface this capability to developers. In the Python SDK ([`sdk/python/cubesandbox/_template.py`](https://github.com/TencentCloud/CubeSandbox/blob/main/sdk/python/cubesandbox/_template.py)), the `dns` parameter accepts a list of server addresses. The Go SDK ([`sdk/go/template.go`](https://github.com/TencentCloud/CubeSandbox/blob/main/sdk/go/template.go)) similarly exposes a `DNS` field in `TemplateOptions`. The web interface also exposes these fields in [`web/src/pages/Templates.tsx`](https://github.com/TencentCloud/CubeSandbox/blob/main/web/src/pages/Templates.tsx) and [`web/src/lib/templateConfig.ts`](https://github.com/TencentCloud/CubeSandbox/blob/main/web/src/lib/templateConfig.ts), mapping UI inputs to the same `dns_config` payload structure.

## Network Isolation Architecture

### TAP Device Lifecycle and Namespace Isolation

Each sandbox receives a dedicated **TAP interface** created by the network-agent. The [`network-agent/internal/service/tap_lifecycle.go`](https://github.com/TencentCloud/CubeSandbox/blob/main/network-agent/internal/service/tap_lifecycle.go) file handles the creation, preparation, and pooling of these devices. The TAP is placed inside the sandbox's network namespace, isolating traffic at the interface level. The `buildRecoveredState` function manages the IP, MAC, and MTU assignment for each TAP device.

### eBPF Policy Enforcement for DNS Traffic

CubeVS enforces network policies through eBPF maps that include DNS-specific controls. The `dns_allow` map stores learned domain names in an inner-trie structure, populated from `allow_out` rules or L7 host/SNI matches. Per-sandbox policy flags stored in `ifindex_to_mvmmeta[].dns_policy_flags` and the `dns_learning_enabled` flag govern DNS behavior for each instance. Additional maps including `allow_out_v2` and `deny_out` hold IP/CIDR allow-lists for broader network policy enforcement. Documentation in [`docs/zh/guide/network-policy.md`](https://github.com/TencentCloud/CubeSandbox/blob/main/docs/zh/guide/network-policy.md) details these map structures.

### CoreDNS Sidecar Integration

DNS queries from within the sandbox namespace are routed to a host-side **CoreDNS** instance via the `cube-sandbox-dns.service`. The network-agent injects the per-instance DNS configuration into the CoreDNS Corefile, ensuring that UDP/TCP port 53 traffic is resolved according to the sandbox-specific upstream servers rather than the host's resolver.

## Implementing Custom DNS and Network Policies

The following examples demonstrate how to configure per-instance DNS using the CubeSandbox SDKs.

**Python SDK – Creating a sandbox with custom DNS:**

```python
from cubesandbox import Template

tpl = Template(
    name="my-app",
    image="registry.cn-beijing.aliyuncs.com/cube/example:latest",
    dns=["8.8.8.8", "1.1.1.1"],          # Per-sandbox DNS

    allow_out=["0.0.0.0/0"],            # Optional network policy

)

sandbox_id = tpl.create()
print(f"Sandbox {sandbox_id} running with DNS {tpl.dns}")

```

**Go SDK – Setting DNS in the low-level request:**

```go
opts := cubesandbox.TemplateOptions{
    Image: "docker.io/library/nginx:latest",
    DNS:   []string{"8.8.8.8", "1.1.1.1"},
}
payload := map[string]any{}
payload["dns"] = opts.DNS

```

**Inspecting the generated network state:**

```go
state := buildRecoveredState(tap, dev, mappings, cfg)
fmt.Printf("Sandbox %s IP %s DNS %v\n",
    state.persistedState.SandboxID,
    state.persistedState.SandboxIP,
    cfg.DNSConfig.Servers)   // Drawn from the DNSConfig field

```

## Summary

- CubeSandbox defines per-instance DNS through the `DNSConfig` protobuf field in `cubebox.proto`, exposed via REST and SDKs.
- Network isolation relies on dedicated TAP devices created in [`tap_lifecycle.go`](https://github.com/TencentCloud/CubeSandbox/blob/main/tap_lifecycle.go), placed in isolated network namespaces.
- eBPF maps (`dns_allow`, `ifindex_to_mvmmeta`) enforce DNS policies and prevent cross-sandbox leakage.
- CoreDNS sidecars on the host handle resolution using the instance-specific upstream configuration.

## Frequently Asked Questions

### Where is the DNS configuration defined in CubeSandbox's API?

The DNS configuration is defined in the `DNSConfig` message within `Cubelet/api/services/cubebox/v1/cubebox.proto` and `CubeMaster/api/services/cubebox/v1/cubebox.proto`. This protobuf definition includes a `servers` field that accepts a list of IP addresses for upstream DNS resolution.

### How does CubeSandbox prevent DNS leakage between sandbox instances?

CubeSandbox isolates DNS traffic through a combination of network namespaces and eBPF policy enforcement. Each sandbox runs in its own network namespace with a dedicated TAP device, while eBPF maps (`dns_allow`, `dns_policy_flags`) enforce per-instance domain allow-lists and learning policies that prevent unauthorized DNS resolution across instance boundaries.

### What happens if I don't specify custom DNS servers when creating a sandbox?

If no custom DNS servers are provided, CubeSandbox falls back to the default nameservers defined in [`Cubelet/dynamicconf/conf.yaml`](https://github.com/TencentCloud/CubeSandbox/blob/main/Cubelet/dynamicconf/conf.yaml). These defaults can be overridden at the template level, but if left unspecified, the system uses the host-configured guest container DNS settings.

### Which component is responsible for creating the network interfaces for each sandbox?

The **network-agent** component, specifically the code in [`network-agent/internal/service/tap_lifecycle.go`](https://github.com/TencentCloud/CubeSandbox/blob/main/network-agent/internal/service/tap_lifecycle.go), manages the lifecycle of TAP devices. It creates, prepares, and assigns these interfaces to individual sandbox network namespaces, handling IP address allocation and MAC address generation through the `buildRecoveredState` function.