HermesFace / scripts /start_vless_proxy.sh
abbasyk60's picture
VLESS proxy: add outbound port diagnostic + fix health check
430fc94 verified
Raw
History Blame Contribute Delete
5.76 kB
#!/bin/bash
# Start xray-core with VLESS+WS+TLS -> local SOCKS5 proxy on 127.0.0.1:1080.
# Reads config from env vars (set as HF Space Secrets):
# VLESS_UUID (required)
# VLESS_ADDRESS (default: 104.18.155.69)
# VLESS_PORT (default: 2087)
# VLESS_SNI (default: rohi.zartaj.xyz)
# VLESS_WS_HOST (default: <VLESS_SNI>)
# VLESS_WS_PATH (default: /)
#
# On success, exports:
# TELEGRAM_PROXY=socks5://127.0.0.1:1080
#
# This file is meant to be `source`d from entrypoint.sh so exports propagate.
set +e # do NOT crash the whole boot if proxy fails
# Keep xray OUT of /opt/data (which is synced to the HF dataset β€” avoids
# "Text file busy" errors and bloating the persistence dataset).
XRAY_DIR="/tmp/xray"
XRAY_BIN="$XRAY_DIR/xray"
XRAY_CONF="$XRAY_DIR/config.json"
XRAY_LOG="/tmp/xray/xray.log"
if [ -z "${VLESS_UUID:-}" ]; then
echo "[vless] VLESS_UUID not set β€” skipping proxy setup"
return 0 2>/dev/null || true
fi
mkdir -p "$XRAY_DIR" /opt/data/logs
# ── Diagnostic: can HF complete a TLS/HTTPS handshake to the VLESS host? ──
VLESS_ADDRESS_DIAG="${VLESS_ADDRESS:-104.18.155.69}"
VLESS_SNI_DIAG="${VLESS_SNI:-rohi.zartaj.xyz}"
echo "[vless][diag] Direct HTTPS handshake test to $VLESS_SNI_DIAG ($VLESS_ADDRESS_DIAG):"
for p in 443 2053 2083 2087 2096 8443; do
CODE=$(timeout 12 curl -sS -o /dev/null -w "%{http_code}" --max-time 10 \
--resolve "${VLESS_SNI_DIAG}:${p}:${VLESS_ADDRESS_DIAG}" \
"https://${VLESS_SNI_DIAG}:${p}/" 2>/dev/null || echo "FAIL")
echo "[vless][diag] port $p: TLS/HTTPS -> $CODE"
done
# ── Install xray-core (once) ──────────────────────────────────────────────
if [ ! -x "$XRAY_BIN" ]; then
echo "[vless] Downloading xray-core..."
XRAY_VERSION="${XRAY_VERSION:-v1.8.24}"
if curl -fsSL -o /tmp/xray.zip \
"https://github.com/XTLS/Xray-core/releases/download/${XRAY_VERSION}/Xray-linux-64.zip"; then
python3 -c "
import zipfile
with zipfile.ZipFile('/tmp/xray.zip') as z:
z.extractall('$XRAY_DIR')
"
chmod +x "$XRAY_BIN"
rm -f /tmp/xray.zip
echo "[vless] xray-core installed at $XRAY_BIN"
else
echo "[vless] ERROR: failed to download xray-core"
return 1 2>/dev/null || true
fi
fi
# ── Config values ─────────────────────────────────────────────────────────
VLESS_ADDRESS="${VLESS_ADDRESS:-104.18.155.69}"
VLESS_SNI="${VLESS_SNI:-rohi.zartaj.xyz}"
VLESS_WS_HOST="${VLESS_WS_HOST:-$VLESS_SNI}"
VLESS_WS_PATH="${VLESS_WS_PATH:-/}"
# Ports to try, in priority order. The user-provided port first, then the
# other standard Cloudflare TLS ports as fallbacks.
PORTS_TO_TRY="${VLESS_PORT:-2087} 443 8443 2053 2083 2096"
write_config() {
local port="$1"
cat > "$XRAY_CONF" <<EOF
{
"log": {"loglevel": "warning"},
"inbounds": [{
"listen": "127.0.0.1",
"port": 1080,
"protocol": "socks",
"settings": {"udp": true, "auth": "noauth"},
"sniffing": {"enabled": true, "destOverride": ["http","tls"]}
}],
"outbounds": [
{
"tag": "vless-out",
"protocol": "vless",
"settings": {
"vnext": [{
"address": "$VLESS_ADDRESS",
"port": $port,
"users": [{"id": "$VLESS_UUID", "encryption": "none"}]
}]
},
"streamSettings": {
"network": "ws",
"security": "tls",
"tlsSettings": {
"serverName": "$VLESS_SNI",
"allowInsecure": false,
"alpn": ["h2","http/1.1"],
"fingerprint": "chrome"
},
"wsSettings": {
"path": "$VLESS_WS_PATH",
"headers": {"Host": "$VLESS_WS_HOST"}
}
}
},
{"tag": "direct", "protocol": "freedom"},
{"tag": "block", "protocol": "blackhole"}
],
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{"type": "field", "ip": ["geoip:private"], "outboundTag": "direct"},
{"type": "field", "outboundTag": "vless-out", "network": "tcp,udp"}
]
}
}
EOF
}
# ── Try each port until the tunnel actually reaches Telegram ──────────────
WORKING_PORT=""
for PORT in $PORTS_TO_TRY; do
echo "[vless] Trying VLESS via $VLESS_ADDRESS:$PORT (SNI $VLESS_SNI)..."
write_config "$PORT"
pkill -f "$XRAY_BIN" 2>/dev/null || true
sleep 1
nohup "$XRAY_BIN" run -c "$XRAY_CONF" > "$XRAY_LOG" 2>&1 &
sleep 3
OK=0
for i in 1 2 3; do
RESP=$(curl -sS --socks5-hostname 127.0.0.1:1080 --max-time 12 \
"https://api.telegram.org/" 2>/dev/null || echo "")
if echo "$RESP" | grep -qiE '"ok"|bad request|method not found|not found'; then
OK=1; break
fi
sleep 2
done
if [ "$OK" = "1" ]; then
echo "[vless] βœ“ Port $PORT WORKS β€” tunnel to Telegram verified"
WORKING_PORT="$PORT"
break
else
echo "[vless] βœ— Port $PORT did not tunnel"
fi
done
if [ -n "$WORKING_PORT" ]; then
echo "[vless] βœ“ Active tunnel on port $WORKING_PORT β€” enabling TELEGRAM_PROXY"
export TELEGRAM_PROXY="socks5://127.0.0.1:1080"
else
echo "[vless] ⚠ NO port produced a working tunnel from this HF Space."
echo "[vless] ⚠ HF's network is dropping the TLS/WS payload to $VLESS_SNI (DPI)."
echo "[vless] ⚠ Dumping xray debug tail:"
tail -25 "$XRAY_LOG" 2>/dev/null | sed 's/^/[xray] /'
pkill -f "$XRAY_BIN" 2>/dev/null || true
# Do NOT set TELEGRAM_PROXY β€” let Hermes skip telegram cleanly rather than
# spin on a dead socks proxy.
fi