Access sandbox instances over a private network

Updated at:

After you create an interface endpoint in a Virtual Private Cloud (VPC), clients can call sandbox API operations, connect to sandboxes, and access services that run in sandboxes over private network addresses. Traffic never traverses the public internet.

How it works

This solution creates an interface endpoint in the VPC where your clients run, and connects it to the endpoint service com.aliyuncs.privatelink.<REGION>.sandbox that the sandbox service provides. The interface endpoint is the private network entry point for calls to the sandbox API from within the VPC, and the endpoint service forwards API requests. When an SDK connects to a sandbox or accesses a service that runs in the sandbox, it uses the private network domain name of the sandbox service.

The private network access process is as follows:

  1. Resolve the sandbox API domain name: PrivateLink resolves the sandbox API domain name to the private IP address of the interface endpoint within the VPC where the endpoint resides.

  2. Call API operations through the endpoint: The client sends an HTTPS API request. After the request passes the access check of the security group associated with the endpoint, PrivateLink forwards it to the sandbox API entry point over the endpoint connection.

    Requests that create or manage sandboxes use E2B_API_URL. When the SDK connects to a sandbox and generates the domain name used to access services in the sandbox, it uses E2B_DOMAIN. Set both variables to the private network addresses in the following table.

Parameter

Private network value

Description

E2B_API_URL

https://api.<REGION>-vpc.sandbox.aliyuncs.com

Calls sandbox API operations, for example, to create a sandbox.

E2B_DOMAIN

<REGION>-vpc.sandbox.aliyuncs.com

Connects to a sandbox and generates the domain name of a service in the sandbox by calling getHost(port) or get_host(port). This value does not include https://.

In the table, <REGION> is the destination region ID, for example cn-shanghai. Set it to the same region as the endpoint service you select. The connection domain name and the service access domain name that the SDK generates resolve to the private network address of the sandbox service. This address is not required to match the private IP address of the interface endpoint. The rest of this topic relies on this relationship when interpreting DNS resolution results.

Clients in the VPC initiate this interface endpoint connection, and responses return over the established connection. Creating the connection does not open a channel through which a sandbox can access resources such as databases in your VPC. For more information about endpoints and private network domain resolution, see How PrivateLink works.

Private and public access coexist

Enabling private network access does not disable the existing public endpoint: The interface endpoint only adds a PrivateLink path to the sandbox, and existing clients can still access the sandbox over the public network. To switch clients to the private path, configure private network addresses for clients in a VPC that has an interface endpoint, as described in this topic. Enabling PrivateLink is not the same as restricting the sandbox to private access only.

Prerequisites

The operations and verifications in this topic assume that your clients and the interface endpoint reside in the same VPC. If your clients reside in another VPC or an on-premises environment, you must configure additional network connectivity and DNS resolution, which is out of scope. Before you start, make sure that the following conditions are met:

  • You have activated the PrivateLink service.

  • You have prepared the VPC where your clients run, together with the vSwitch and the security group that are required to create an interface endpoint. The outbound rules on the client side must allow access to TCP port 443 of the endpoint. The inbound rules of the security group associated with the endpoint are configured when you create the interface endpoint.

  • You have obtained a sandbox API key and use it to set the E2B_API_KEY environment variable.

  • You have prepared an Elastic Compute Service (ECS) instance or a container in the VPC to run the examples. You have also installed Python and pip, or Node.js and npm, based on the language of the examples.

Create an interface endpoint

  1. Log on to the PrivateLink console, select Interface Endpoint, and go to the creation page.

  2. In Basic Settings, set Region to the destination region and specify Endpoint Name. Set Type to Alibaba Cloud Service, and select com.aliyuncs.privatelink.<REGION>.sandbox in Available Services.

  3. Configure VPC, Zone and vSwitch, and Security Group. The inbound rules of the security group associated with the endpoint must allow the private IP addresses or CIDR blocks of your clients to access TCP port 443. The outbound rules on the client side must also allow this access.

  4. Click OK and wait until the endpoint status changes to Available and the endpoint connection status changes to Connected.

    After the endpoint is created, clients in the VPC can access the sandbox by using the private network addresses described in the following sections.

Configure private network addresses and verify connectivity

The following examples use E2B SDK 2.50.0. Before you run the Python example, run python3 -m pip install e2b==2.50.0 to install the dependency. Before you run the TypeScript example, run npm install e2b@2.50.0 to install the dependency.

On an ECS instance or in a container in the VPC where the interface endpoint resides, set the following environment variables, using private network addresses for E2B_API_URL and E2B_DOMAIN:

export E2B_API_KEY="<YOUR-API-KEY>"
export E2B_API_URL="https://api.<REGION>-vpc.sandbox.aliyuncs.com"
export E2B_DOMAIN="<REGION>-vpc.sandbox.aliyuncs.com"

Run one of the following examples to verify private network connectivity from the VPC to the sandbox service. Each example creates a sandbox, starts a temporary HTTP server on port 8000, and reads a verification file over the private network address. The examples send at most 10 requests, each with a 3-second timeout, and retry after a 1-second interval on failure. Access succeeds only when the response is HTTP 200 and the body matches the verification file. If all retries are exhausted, the example throws an error.

The following output is expected. The examples use the cn-shanghai region. <SANDBOX-ID> is the ID of the sandbox that is created in the current run, and each run generates a different ID. For other regions, use the domain names that you configure and that the SDK generates.

Verification URL: https://8000-<SANDBOX-ID>.cn-shanghai-vpc.sandbox.aliyuncs.com/private-access-check.txt
HTTP 200
sandbox-private-access-ok

If the response returns HTTP 200 and the response body matches the content of the verification file, the service in the sandbox is accessible. To confirm that the access is over the private network, check that the private network addresses are configured as described in this topic. Then verify that the resolution results of the API domain name and the service access domain name that the SDK generates match the description in How it works.

Automatic cleanup: These examples verify connectivity only. The sandbox is destroyed automatically after the examples succeed or fail, and the verification URL becomes invalid.

If a request times out, the response does not return HTTP 200, or the response body does not match the verification file, check the VPC where the client runs, the private network domain resolution, and the security group configurations as described in Troubleshooting.

TypeScript

The following example uses the ESM import syntax and creates the sandbox with a top-level await. Your runtime must support ES modules.

import { Sandbox } from "e2b";

const sandbox = await Sandbox.create("code-interpreter-v1", {
  apiKey: process.env.E2B_API_KEY,
  apiUrl: process.env.E2B_API_URL,
  domain: process.env.E2B_DOMAIN,
});

try {
  await sandbox.files.write(
    "/tmp/private-access-check.txt", "sandbox-private-access-ok\n"
  );
  await sandbox.commands.run("python3 -m http.server 8000 --directory /tmp", {
    background: true,
  });

  const url = `https://${sandbox.getHost(8000)}/private-access-check.txt`;
  console.log(`Verification URL: ${url}`);

  // Wait until the service is ready: up to 10 requests, a 3-second timeout per request, and a 1-second retry interval.
  for (let attempt = 1; attempt <= 10; attempt++) {
    try {
      const response = await fetch(url, { signal: AbortSignal.timeout(3000) });
      if (!response.ok) throw new Error(`HTTP ${response.status}`);
      const body = await response.text();
      if (response.status !== 200 || body.trim() !== "sandbox-private-access-ok") {
        throw new Error(`Unexpected response: HTTP ${response.status}`);
      }
      console.log(`HTTP ${response.status}`);
      console.log(body.trim());
      break;
    } catch (error) {
      if (attempt === 10) throw error;
      await new Promise((resolve) => setTimeout(resolve, 1000));
    }
  }
} finally {
  // The sandbox is destroyed after the example ends, and the verification URL becomes invalid.
  await sandbox.kill();
}

Python

The following example calls the synchronous API of the SDK at the top level of the script and requires no additional module system configuration.

import os
import time
import urllib.error
import urllib.request

from e2b import Sandbox

sandbox = Sandbox.create(
    template="code-interpreter-v1",
    api_key=os.environ["E2B_API_KEY"],
    api_url=os.environ["E2B_API_URL"],
    domain=os.environ["E2B_DOMAIN"],
)

try:
    sandbox.files.write(
        "/tmp/private-access-check.txt", "sandbox-private-access-ok\n"
    )
    sandbox.commands.run(
        "python3 -m http.server 8000 --directory /tmp", background=True
    )

    url = f"https://{sandbox.get_host(8000)}/private-access-check.txt"
    print(f"Verification URL: {url}")

    # Wait until the service is ready: up to 10 requests, a 3-second timeout per request, and a 1-second retry interval.
    for attempt in range(1, 11):
        try:
            with urllib.request.urlopen(url, timeout=3) as response:
                body = response.read().decode().strip()
                if response.status != 200 or body != "sandbox-private-access-ok":
                    raise ValueError(f"Unexpected response: HTTP {response.status}")
                print(f"HTTP {response.status}")
                print(body)
            break
        except (urllib.error.URLError, OSError, ValueError):
            if attempt == 10:
                raise
            time.sleep(1)
finally:
    # The sandbox is destroyed after the example ends, and the verification URL becomes invalid.
    sandbox.kill()

Troubleshooting

If private network access fails, first identify whether the failure occurs when you create a sandbox, connect to a sandbox, or access a service in a sandbox. Then use the following table to troubleshoot the issue:

Check item

Solution

VPC of the client and destination region

Make sure that your code runs in the VPC where the interface endpoint resides. The endpoint service name is com.aliyuncs.privatelink.<REGION>.sandbox, and the region in the private network address is the same as the region of the service you select. Other VPCs or on-premises environments require additional network connectivity and DNS resolution configurations.

Endpoint and connection status

In the PrivateLink console, make sure that the endpoint status is Available and the endpoint connection status is Connected. If the connection is not established, check the connection status and the messages in the console.

Private network domain resolution and DNS

On the client that runs the code, use nslookup to check the API domain name and the service access domain name that the SDK generates. The API domain name must resolve to the private IP address of the endpoint network interface. The service access domain name that the SDK generates must resolve to the private network address of the sandbox service. For more information about the expected resolution results, see How it works. If the domain names cannot be resolved or the results are unexpected, check the DNS server that the client uses. If the API domain name is resolved abnormally, log on to the PrivateLink console and check whether the Custom Domain Name switch of the interface endpoint is manually disabled. If it is disabled, turn it on again.

Security group and access port

Make sure that the security group associated with the endpoint allows the source CIDR blocks of your clients to access TCP port 443, and that the outbound rules on the client side allow this access. Port 8000 in the examples is the listening port of the HTTP server in the sandbox. Clients access the domain name that the SDK generates over HTTPS port 443.

API key and access permissions

If HTTP 401 or 403 is returned, check the API key and access permissions together with the error message. Do not conclude that the PrivateLink connection failed based only on the status code.

Service readiness in the sandbox

Make sure that the HTTP process runs as expected, listens on port 8000, and that the verification file exists. If the sandbox is created but the service is inaccessible, check the process logs and the response content. The sandbox is destroyed after the examples end, so the verification URL becomes invalid as expected.

What to do next

After the verification is complete, the sandbox that the examples create is destroyed. The interface endpoint continues to serve as the private network entry point for clients in the VPC to access the sandbox. For more information about how to manage interface endpoints and the related mechanisms, see the following topics: