> ## Documentation Index
> Fetch the complete documentation index at: https://docs.celesto.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Network configuration

> How SmolVM networking works — TAP devices, private subnets, NAT, and outbound internet access — so sandboxes stay isolated from each other and the host.

Every SmolVM sandbox gets its own private network connection. The sandbox can reach the internet, but it cannot talk to other sandboxes or access host network interfaces directly. This page explains how the networking works and what you can configure.

## How it works

When SmolVM creates a sandbox, it sets up a dedicated virtual network interface (called a TAP device) for that sandbox. The sandbox receives a private IP address and uses NAT to reach the internet through your host's network connection.

```mermaid theme={null}
flowchart TB
  subgraph Host["Host system"]
    VM1["Sandbox 1<br/>172.16.0.2"]
    VM2["Sandbox 2<br/>172.16.0.3"]
    TAP0["tap0<br/>172.16.0.1"]
    TAP1["tap1<br/>172.16.0.1"]
    NAT["NAT<br/>(nftables)"]
    ETH0["eth0"]

    VM1 --> TAP0
    VM2 --> TAP1
    TAP0 --> NAT
    TAP1 --> NAT
    NAT --> ETH0
  end

  ETH0 --> Internet["Internet"]
```

Each sandbox receives:

* **Guest IP**: an address in the `172.16.0.2` – `172.16.0.255` range
* **Gateway**: `172.16.0.1` (the host side of the TAP device)
* **Netmask**: `255.255.255.0` (`/24`)

SmolVM assigns these automatically. You do not need to configure networking for most use cases.

## Sandbox isolation

Sandboxes are isolated from each other by default. SmolVM adds a firewall rule that drops all traffic between TAP devices, so one sandbox cannot reach another:

```bash theme={null}
# This rule is added automatically
nft add rule inet smolvm_filter forward iifname "tap*" oifname "tap*" counter drop
```

Each sandbox can:

* Access the internet via NAT
* Be reached from the host via [port forwarding](/smolvm/features/port-forwarding)
* **Not** communicate directly with other sandboxes

<Note>
  Sandboxes can access the internet by default. If you need to restrict outbound traffic, add firewall rules on your host. See [security model](/smolvm/concepts/security) for details.
</Note>

## TAP devices

A TAP device is a virtual network interface that connects a sandbox to the host networking stack. SmolVM creates one TAP device per sandbox and removes it when the sandbox is deleted.

The lifecycle of a TAP device:

1. **Create** — SmolVM runs `ip tuntap add` to create a virtual interface
2. **Configure** — assigns the host-side IP and brings the link up
3. **Route** — adds a host route so packets reach the sandbox
4. **Cleanup** — deletes the TAP device when the sandbox stops

All of this is handled automatically. You only need to interact with TAP devices if you are debugging networking issues.

## NAT and firewall rules

SmolVM uses [nftables](https://wiki.nftables.org/) to manage NAT and firewall rules. It creates two tables:

* `ip smolvm_nat` — handles NAT (masquerade for outbound traffic, DNAT for port forwarding)
* `inet smolvm_filter` — handles forwarding rules and sandbox isolation

When a sandbox starts, SmolVM:

1. Enables IP forwarding on the host (`net.ipv4.ip_forward=1`)
2. Adds a masquerade rule so outbound traffic appears to come from the host
3. Adds a forwarding rule to allow traffic from the sandbox's TAP device to the internet
4. Adds an isolation rule to block sandbox-to-sandbox traffic

You can inspect the active rules at any time:

```bash theme={null}
sudo nft list table ip smolvm_nat
sudo nft list table inet smolvm_filter
```

## Port forwarding

SmolVM supports two types of port forwarding to reach services running inside a sandbox.

### SSH port forwarding

SSH access is set up automatically when a sandbox starts. SmolVM forwards a host port to port 22 inside the guest using nftables DNAT rules. You can connect manually:

```bash theme={null}
ssh -p <host_port> root@localhost
```

Or use the SDK, which handles SSH connections for you through `vm.run()`.

### Application port forwarding

To access a web server, database, or other service running inside a sandbox, use `expose_local()`:

```python theme={null}
from smolvm import SmolVM

with SmolVM() as vm:
    vm.run("python3 -m http.server 8080 &")
    host_port = vm.expose_local(guest_port=8080, host_port=18080)
    print(f"Service available at http://localhost:{host_port}")
```

```mermaid theme={null}
flowchart TB
  subgraph Host["Host"]
    Browser["Browser<br/>http://localhost:18080"]
    DNAT["nftables DNAT<br/>127.0.0.1:18080 → 172.16.0.2:8080"]
    TAP["TAP<br/>172.16.0.1"]

    Browser --> DNAT --> TAP
  end

  TAP --> VM["Sandbox<br/>172.16.0.2:8080"]
```

<Warning>
  `expose_local()` only binds to `127.0.0.1` (localhost). Services are not exposed to your network. If you need external access, set up additional forwarding outside of SmolVM.
</Warning>

See the [port forwarding guide](/smolvm/features/port-forwarding) for more examples including automatic port allocation, multiple forwards, and troubleshooting.

## Network prerequisites

SmolVM needs the following tools installed on your host (Linux only):

* `ip` (from iproute2) — manages TAP devices and routes
* `nft` (from nftables) — manages NAT and firewall rules
* `sudo` access for networking commands

The `smolvm setup` command installs these automatically. You can verify your setup with:

```bash theme={null}
smolvm doctor
```

## Troubleshooting

<AccordionGroup>
  <Accordion title="Sandbox has no internet access">
    Check that IP forwarding is enabled and NAT rules are in place:

    ```bash theme={null}
    # Should return 1
    cat /proc/sys/net/ipv4/ip_forward

    # Enable manually if needed
    sudo sysctl -w net.ipv4.ip_forward=1

    # Check NAT rules exist
    sudo nft list table ip smolvm_nat
    ```
  </Accordion>

  <Accordion title="'ip' or 'nft' command not found">
    Install the missing package:

    ```bash theme={null}
    # Ubuntu/Debian
    sudo apt install iproute2 nftables

    # Fedora/RHEL
    sudo dnf install iproute nftables
    ```
  </Accordion>

  <Accordion title="Permission denied on TAP creation">
    Run the SmolVM system setup to configure sudo permissions:

    ```bash theme={null}
    sudo ./scripts/system-setup.sh --configure-runtime
    ```
  </Accordion>

  <Accordion title="Port forwarding not working">
    Check that `route_localnet` is enabled for the TAP device and forwarding rules exist:

    ```bash theme={null}
    # Should return 1
    cat /proc/sys/net/ipv4/conf/tap0/route_localnet

    # Check forwarding rules
    sudo nft list chain inet smolvm_filter forward
    ```

    Also verify that the service inside the sandbox is binding to `0.0.0.0`, not `127.0.0.1`.
  </Accordion>

  <Accordion title="TAP device persists after sandbox deletion">
    If cleanup failed, remove the device manually:

    ```bash theme={null}
    # List TAP devices
    ip link show | grep tap

    # Delete manually
    sudo ip link delete tap0

    # Or clean up all SmolVM resources
    smolvm sandbox delete --all --force
    ```
  </Accordion>
</AccordionGroup>

## Next steps

* Review the [security model](/smolvm/concepts/security)
* Choose your [backend](/smolvm/concepts/backends) (Firecracker vs. QEMU)
* Read the [architecture overview](/smolvm/concepts/overview)
