Proxy tunneling
How to tunnel Sandbox network traffic through a proxy server
Setting up proxy tunneling
We will set up a proxy server on a GCP VM instance running Shadowsocks and use it to tunnel the Sandbox network traffic. This will allow you to use a dedicated IP address for outgoing requests.
GCP VM setup
-
Create a firewall rule to allow all tcp/udp traffic to port 8388.
Replace
your-project-idwith your actual project ID.gcloud compute firewall-rules create shadowsocks \ --project=your-project-id \ --direction=INGRESS \ --priority=1000 \ --network=default \ --action=ALLOW \ --rules=tcp:8388,udp:8388 \ --source-ranges=0.0.0.0/0 \ --target-tags=allow-shadowsocks -
Create a VM instance with the following tags:
allow-shadowsocks.Replace
your-project-idwith your actual project ID.gcloud compute instances create shadowsocks-vm \ --project=your-project-id \ --zone=us-west1-a \ --machine-type=n2-standard-2 \ --can-ip-forward \ --tags=allow-shadowsocks \ --image-project=debian-cloud \ --image-family=debian-12 \ --boot-disk-size=20GB -
After the VM is created, you can connect to it using the following command:
Replace
your-project-idwith your actual project ID.# May take a few seconds until the instance is ready to accept SSH connections gcloud compute ssh shadowsocks-vm \ --project=your-project-id \ --zone=us-west1-a
Shadowsocks server setup (VM)
SSH into the VM and follow the instructions below to install and configure Shadowsocks.
-
Install the necessary packages, if missing:
sudo apt update sudo apt install -y wget tar -
Download and install Shadowsocks (v1.24.0):
wget https://github.com/shadowsocks/shadowsocks-rust/releases/latest/download/shadowsocks-v1.24.0.x86_64-unknown-linux-gnu.tar.xz tar -xf shadowsocks-*.tar.xz sudo mv ssserver ssmanager ssurl /usr/local/bin/ -
Create a shadowsocks configuration file:
Replace
STRONG_PASSWORD_HEREwith your own password./etc/shadowsocks/server.json { "server": "0.0.0.0", "server_port": 8388, "password": "STRONG_PASSWORD_HERE", "method": "aes-256-gcm", "mode": "tcp_and_udp", "timeout": 300, "fast_open": true } -
Enable IP forwarding:
/etc/sysctl.d/99-shadowsocks.conf net.core.default_qdisc=fq net.ipv4.tcp_congestion_control=bbr net.ipv4.ip_forward=1sudo sysctl -p /etc/sysctl.d/99-shadowsocks.confOptional: Update the Ubuntu Firewall rules to allow traffic to port 8388:
sudo ufw allow 8388/tcp sudo ufw allow 8388/udp -
Start the Shadowsocks server:
sudo ssserver -c /etc/shadowsocks/server.json -vYou should see the following in the console output:
shadowsocks tcp server listening on 0.0.0.0:8388 shadowsocks udp server listening on 0.0.0.0:8388 -
Optional: Create a systemd service to start the Shadowsocks server on boot:
/etc/systemd/system/ssserver.service [Unit] Description=Shadowsocks Rust Server After=network.target [Service] ExecStart=/usr/local/bin/ssserver -c /etc/shadowsocks/server.json Restart=always LimitNOFILE=51200 User=root [Install] WantedBy=multi-user.targetReload the systemd daemon and start the service:
sudo systemctl daemon-reload sudo systemctl enable --now ssserverYou can check the status of the service with the following command:
sudo systemctl status ssserver
Shadowsocks client setup (sandbox)
Create a custom Sandbox template that uses the shadowsocks client to tunnel TCP traffic through the proxy server we set up above.
Route only designated traffic through the proxy.
-
Create a configuration file for the shadowsocks client:
Replace
SERVER_IPwith the IP address of the proxy server andSTRONG_PASSWORD_HEREwith your own password.config.json { "server": "SERVER_IP", "server_port": 8388, "password": "STRONG_PASSWORD_HERE", "method": "aes-256-gcm", "local_address": "0.0.0.0", "local_port": 1080, "mode": "tcp" } -
Create a template file (
template.ts/template.py):import { Template, waitForPort } from "e2b"; const shadowSocksVersion = "1.24.0" const downloadUrl = `https://github.com/shadowsocks/shadowsocks-rust/releases/latest/download/shadowsocks-v${shadowSocksVersion}.x86_64-unknown-linux-gnu.tar.xz` export const template = Template() .fromBaseImage() .runCmd([ `wget ${downloadUrl}`, "tar -xf shadowsocks-*.tar.xz", "sudo mv sslocal /usr/local/bin/" ]) .copy('config.json', 'config.json') .setStartCmd( "sudo sslocal -c config.json --daemonize", waitForPort(1080) ) -
Create a build script (
build.ts/build.py):import { Template, defaultBuildLogger } from "e2b"; import { template as localProxyTemplate } from "./template"; await Template.build(template, { alias: 'shadowsocks-client', memoryMB: 1024, cpuCount: 1, onBuildLogs: defaultBuildLogger() }) -
Build the template using the build script:
npx tsx build.ts
Using the proxies
Create a new Sandbox from the built template and run a curl command to verify that the traffic is routed through the proxy:
Only designated traffic should be routed through the proxy.
import { Sandbox } from "e2b";
// create a new Sandbox from the built template
const sbx = await Sandbox.create('shadowsocks-client')
// run a command to curl the IP address of the proxy server
const curl = await sbx.commands.run('curl --socks5 127.0.0.1:1080 https://ifconfig.me')
console.log(curl.stdout)
await sbx.kill()npx tsx sandbox.tsYou should see the IP address of the proxy server.