🚀 Two-minute setup: One-click deploy Gost + Clash subscription (SOCKS5)
2025/09/30

🚀 Two-minute setup: One-click deploy Gost + Clash subscription (SOCKS5)

Set up a Gost SOCKS5 proxy with Docker in minutes and publish a Clash subscription via Nginx.

If you just want a quick SOCKS5 proxy and a ready-to-use Clash subscription, it's dead simple. Follow along: run Gost with Docker as the proxy core, then serve the subscription via Nginx. Works for beginners too.


1. Install Docker (if you don't have it)

sudo apt update
sudo apt install -y ca-certificates curl gnupg lsb-release
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \
  | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io

# add to docker group to avoid sudo
sudo usermod -aG docker $USER
exit   # re-login via SSH to take effect

2. Spin up a Gost container (SOCKS5)

Listen on port 1080 with account myuser and password mypass — one command and you're done:

docker run -d --name gost --restart unless-stopped \
  -p 1080:1080 \
  gogost/gost:latest \
  -L=socks5://myuser:mypass@:1080

Notes:

  • -d: runs in background
  • --restart unless-stopped: auto-restarts on reboot
  • -p 1080:1080: exposes port 1080
  • -L: tells Gost to use a SOCKS5 listener

3. Firewall / security group

Allow these ports and you're good:

  • 22/tcp: only your public IP (SSH login)
  • 1080/tcp: your relay server or trusted client IPs

Example (AWS security group → inbound rules):

  • Type: SSH / Port: 22 / Source: your public IP
  • Type: Custom TCP / Port: 1080 / Source: relay server IP

4. Smoke test the proxy

On the server itself, test:

curl -x socks5h://myuser:[email protected]:1080 https://api.ipify.org

From another machine (e.g., a relay server):

curl -x socks5h://myuser:mypass@<YOUR_SERVER_PUBLIC_IP>:1080 https://api.ipify.org

👉 If you see the VPS public IP, you're good.


5. Publish a Clash subscription

5.1 Install Nginx

sudo apt install -y nginx

5.2 Drop a subscription file

sudo tee /var/www/html/clash-sub.yaml >/dev/null <<'EOF'
proxies:
  - name: "my-socks5"
    type: socks5
    server: <YOUR_SERVER_PUBLIC_IP>
    port: 1080
    username: "myuser"
    password: "mypass"

proxy-groups:
  - name: "Proxy"
    type: select
    proxies:
      - my-socks5
      - DIRECT

rules:
  - MATCH,Proxy
EOF

Proxy verification screenshot

5.3 Use the subscription in browser / Clash client

http://<YOUR_SERVER_PUBLIC_IP>/clash-sub.yaml

After refreshing, you should see the my-socks5 node.

Clash node screenshot

🔐 Recommendation: Replace the sample credentials with strong random passwords ASAP; also restrict 1080/tcp to trusted IP ranges via security group or firewall.


In the AI era, handing repetitive, standardized, and scriptable work over to AI is the most efficient and worry-free approach. Paste the prompt below verbatim into GPT/Claude and it will set up SOCKS5 and the Clash subscription end-to-end, including self-check and rollback commands.

One-click AI prompt (paste as-is into your AI)

I need to automatically deploy a SOCKS5 proxy (Gost) and publish a Clash subscription on a fresh Ubuntu (20.04/22.04/24.04) server.
Please follow the requirements below and finish in one shot:

Requirements & constraints
- SOCKS5 runs on TCP 1080
- Proxy auth enabled by default (username: myuser, password: mypass); to disable, set USE_AUTH=false
- Nginx must serve /clash-sub.yaml (URL: http://<SERVER_PUBLIC_IP>/clash-sub.yaml)
- All commands must be idempotent; exit immediately on failure
- Finally print verification commands and cleanup/rollback commands
- If UFW is enabled, allow 80/1080 (skip if not enabled)

Run the following script as root (or prefix each line with sudo):
#!/usr/bin/env bash
set -euo pipefail

############################
# Configurable parameters
############################
SOCKS_PORT=1080
USE_AUTH=true              # 需要认证:true;不要认证:false
S5_USER="myuser"
S5_PASS="mypass"

SUB_FILE="/var/www/html/clash-sub.yaml"

############################
# Preparation & common
############################
export DEBIAN_FRONTEND=noninteractive

echo "[1/7] Update package index (no dist-upgrade)"
apt-get update -y

############################
# Install Docker (official repo)
############################
echo "[2/7] Install Docker deps and repository"
apt-get install -y ca-certificates curl gnupg lsb-release
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg

UBU_CODENAME="$(. /etc/os-release && echo "${VERSION_CODENAME}")"
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu ${UBU_CODENAME} stable" \
  > /etc/apt/sources.list.d/docker.list

apt-get update -y
apt-get install -y docker-ce docker-ce-cli containerd.io

systemctl enable --now docker

############################
# Start/Update Gost (Docker)
############################
echo "[3/7] Deploy/Update Gost container (SOCKS5 port: ${SOCKS_PORT})"
docker rm -f gost 2>/dev/null || true

if [ "${USE_AUTH}" = "true" ]; then
  GOST_CMD="-L=socks5://${S5_USER}:${S5_PASS}@:$(printf '%d' "${SOCKS_PORT}")"
else
  GOST_CMD="-L=socks5://:$(printf '%d' "${SOCKS_PORT}")"
fi

docker run -d --name gost --restart unless-stopped \
  --pull=always \
  -p "${SOCKS_PORT}:${SOCKS_PORT}" \
  gogost/gost:latest ${GOST_CMD}

echo "Gost started:"
docker ps --filter name=gost --format "table {{.Names}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}"

############################
# Install Nginx and publish Clash subscription
############################
echo "[4/7] Install Nginx and publish Clash subscription"
apt-get install -y nginx
systemctl enable --now nginx

# Detect public IP (for subscription)
PUB_IP="$(curl -fsS https://api.ipify.org || true)"
if [[ -z "${PUB_IP}" ]]; then
  echo "Failed to get public IP, will write 127.0.0.1 temporarily; you can replace it later."
  PUB_IP="127.0.0.1"
fi

install -d -m 0755 /var/www/html

cat > "${SUB_FILE}" <<'YAML'
# Minimal Clash config (auto-generated; extend as needed)
mixed-port: 7890
allow-lan: true
mode: Rule
log-level: info

proxies:
  - name: "aws-socks5"
    type: socks5
    server: __PUB_IP__
    port: __SOCKS_PORT__
__AUTH_BLOCK__

proxy-groups:
  - name: "Select"
    type: select
    proxies:
      - aws-socks5
      - DIRECT

rules:
  - GEOIP,CN,DIRECT
  - MATCH,Select
YAML

# Build auth block according to switch
if [ "${USE_AUTH}" = "true" ]; then
  AUTH_BLOCK="    username: ${S5_USER}\n    password: ${S5_PASS}"
else
  AUTH_BLOCK=""
fi

# Replace variables
sed -i \
  -e "s/__PUB_IP__/${PUB_IP}/g" \
  -e "s/__SOCKS_PORT__/${SOCKS_PORT}/g" \
  -e "s|__AUTH_BLOCK__|${AUTH_BLOCK}|g" \
  "${SUB_FILE}"

# Permissions
chown www-data:www-data "${SUB_FILE}"
chmod 0644 "${SUB_FILE}"

# Local check
curl -fsSI "http://127.0.0.1/$(basename "${SUB_FILE}")" >/dev/null \
  && echo "Nginx can serve the subscription file locally." \
  || (echo "Nginx failed to serve the subscription file. Please check."; exit 1)

############################
# UFW (if enabled, allow 80/1080)
############################
echo "[5/7] If UFW is enabled, allow 80 and ${SOCKS_PORT}"
if ufw status 2>/dev/null | grep -q "Status: active"; then
  ufw allow 80/tcp || true
  ufw allow "${SOCKS_PORT}"/tcp || true
fi

############################
# Optional: enable BBR for better long-distance throughput
############################
echo "[6/7] (Optional) enable BBR congestion control"
if ! sysctl net.ipv4.tcp_congestion_control | grep -q bbr; then
  {
    echo "net.core.default_qdisc=fq"
    echo "net.ipv4.tcp_congestion_control=bbr"
  } >> /etc/sysctl.conf
  sysctl -p >/dev/null || true
fi

echo "Current congestion control: $(sysctl -n net.ipv4.tcp_congestion_control)"

############################
# Final info & verification
############################
echo "[7/7] Self-check and usage"

echo
echo "=== Self-check (SOCKS5 -> public IP) ==="
if [ "${USE_AUTH}" = "true" ]; then
  echo "curl -x 'socks5h://${S5_USER}:${S5_PASS}@${PUB_IP}:${SOCKS_PORT}' -sS https://api.ipify.org && echo"
else
  echo "curl -x 'socks5h://${PUB_IP}:${SOCKS_PORT}' -sS https://api.ipify.org && echo"
fi

echo
echo "=== Self-check (Clash subscription URL) ==="
echo "curl -I http://${PUB_IP}/$(basename "${SUB_FILE}")"

echo
echo "=== Cleanup/Rollback (if needed) ==="
cat <<'CLEAN'
# Stop and remove Gost container and images
docker rm -f gost 2>/dev/null || true
docker image prune -f 2>/dev/null || true

# Remove subscription file (optional)
rm -f /var/www/html/clash-sub.yaml

# (Optional) revert congestion control to cubic
sed -i '/^net.core.default_qdisc=fq$/d' /etc/sysctl.conf
sed -i '/^net.ipv4.tcp_congestion_control=bbr$/d' /etc/sysctl.conf
sysctl -p || true
CLEAN

echo
echo "=== Done! In your cloud security group, allow: 22/tcp, 80/tcp, ${SOCKS_PORT}/tcp (restrict 1080 to trusted sources only). ==="

What I expect to see
- Docker and Gost container status printed
- Nginx ready and the subscription file accessible
- Self-check commands provided (SOCKS5 curl returns public IP; subscription URL returns 200)
- If something goes wrong, print the reason and suggested fix