Skip to main content

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

  1. Create a firewall rule to allow all tcp/udp traffic to port 8388.
    Replace your-project-id with 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
    
  2. Create a VM instance with the following tags: allow-shadowsocks.
    Replace your-project-id with 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
    
  3. After the VM is created, you can connect to it using the following command:
    Replace your-project-id with 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.
  1. Install the necessary packages, if missing:
    sudo apt update
    sudo apt install -y wget tar
    
  2. 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/
    
  3. Create a shadowsocks configuration file:
    Replace STRONG_PASSWORD_HERE with 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
    }
    
  4. Enable IP forwarding:
    /etc/sysctl.d/99-shadowsocks.conf
    net.core.default_qdisc=fq
    net.ipv4.tcp_congestion_control=bbr
    net.ipv4.ip_forward=1
    
    sudo sysctl -p /etc/sysctl.d/99-shadowsocks.conf
    
    Optional: Update the Ubuntu Firewall rules to allow traffic to port 8388:
    sudo ufw allow 8388/tcp
    sudo ufw allow 8388/udp
    
  5. Start the Shadowsocks server:
    sudo ssserver -c /etc/shadowsocks/server.json -v
    
    You 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
    
  6. 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.target
    
    Reload the systemd daemon and start the service:
    sudo systemctl daemon-reload
    sudo systemctl enable --now ssserver
    
    You 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.
  1. Create a configuration file for the shadowsocks client:
    Replace SERVER_IP with the IP address of the proxy server and STRONG_PASSWORD_HERE with 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"
    }
    
  2. 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)
        )
    
  3. 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()
    })
    
  4. 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.ts
You should see the IP address of the proxy server.