Spaces:
Paused
Paused
Upload 4 files
Browse files
Dockerfile
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 使用轻量级的 Alpine Linux 作为基础镜像
|
| 2 |
+
FROM alpine:latest
|
| 3 |
+
|
| 4 |
+
# 设置环境变量,用于指定目标 WebSocket 代理 URL
|
| 5 |
+
# 这将被 Hugging Face Secret 覆盖 (在构建时)
|
| 6 |
+
ARG TARGET_WSPROXY_URL="wss://your-first-space.hf.space/wsproxy"
|
| 7 |
+
ENV TARGET_WSPROXY_URL=${TARGET_WSPROXY_URL}
|
| 8 |
+
|
| 9 |
+
# 工作目录
|
| 10 |
+
WORKDIR /app
|
| 11 |
+
|
| 12 |
+
# 安装必要的软件
|
| 13 |
+
RUN apk --no-cache add curl bash python3 netcat-openbsd
|
| 14 |
+
|
| 15 |
+
# 下载并安装 gost
|
| 16 |
+
ARG GOST_VERSION="2.11.5"
|
| 17 |
+
RUN curl -L "https://github.com/ginuerzh/gost/releases/download/v${GOST_VERSION}/gost-linux-amd64-${GOST_VERSION}.gz" | gzip -d > /usr/local/bin/gost && \
|
| 18 |
+
chmod +x /usr/local/bin/gost
|
| 19 |
+
|
| 20 |
+
# 复制启动脚本
|
| 21 |
+
COPY start.sh /app/
|
| 22 |
+
RUN chmod +x /app/start.sh
|
| 23 |
+
|
| 24 |
+
# 暴露 7860 端口 (Hugging Face 默认端口)
|
| 25 |
+
EXPOSE 7860
|
| 26 |
+
|
| 27 |
+
# 设置健康检查
|
| 28 |
+
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
| 29 |
+
CMD nc -z localhost 7860 || exit 1
|
| 30 |
+
|
| 31 |
+
# 运行启动脚本
|
| 32 |
+
ENTRYPOINT ["/app/start.sh"]
|
| 33 |
+
|
| 34 |
+
# 默认参数 (可被 CMD 覆盖)
|
| 35 |
+
CMD []
|
README.md
CHANGED
|
@@ -1,11 +1,67 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# WebSocket 代理转换器
|
| 2 |
+
|
| 3 |
+
这个项目提供了一个简单的代理中转服务,将 WebSocket 代理转换为标准的 SOCKS5/HTTP 代理,使其更容易被普通应用程序使用。
|
| 4 |
+
|
| 5 |
+
## 背景
|
| 6 |
+
|
| 7 |
+
许多云平台(如 Hugging Face Spaces)不允许直接暴露代理端口,但允许通过 WebSocket 提供服务。这种情况下,直接使用标准的代理配置可能会遇到困难。这个项目解决了这个问题:
|
| 8 |
+
|
| 9 |
+
1. **第一个 Space**(Clash WebSocket 代理): 通过 WebSocket 隧道(`/wsproxy`)提供代理服务
|
| 10 |
+
2. **这个 Space**(代理转换器): 将 WebSocket 代理转换为标准 SOCKS5 或 HTTP 代理
|
| 11 |
+
|
| 12 |
+
## 特点
|
| 13 |
+
|
| 14 |
+
- 自动将 WebSocket 代理转换为标准 SOCKS5/HTTP 代理
|
| 15 |
+
- 支持在 Hugging Face Spaces 等平台上部署
|
| 16 |
+
- 轻量级、安全和高性能
|
| 17 |
+
- 基于 [gost](https://github.com/ginuerzh/gost) 实现,成熟稳定
|
| 18 |
+
|
| 19 |
+
## 部署指南
|
| 20 |
+
|
| 21 |
+
### 在 Hugging Face Space 上部署
|
| 22 |
+
|
| 23 |
+
1. 创建一个新的 Space(使用 Docker 运行时)
|
| 24 |
+
2. 上传这个目录中的所有文件
|
| 25 |
+
3. 在 Space 的设置中添加一个密钥(Secret):
|
| 26 |
+
- 名称: `TARGET_WSPROXY_URL`
|
| 27 |
+
- 值: 第一个 Space 的 WebSocket 代理地址,例如 `wss://your-first-space.hf.space/wsproxy`
|
| 28 |
+
4. 部署并等待构建完成
|
| 29 |
+
|
| 30 |
+
### 本地部署(测试用途)
|
| 31 |
+
|
| 32 |
+
```bash
|
| 33 |
+
# 设置目标 WebSocket 代理 URL
|
| 34 |
+
export TARGET_WSPROXY_URL="wss://your-first-space.hf.space/wsproxy"
|
| 35 |
+
|
| 36 |
+
# 运行 Docker 容器
|
| 37 |
+
docker build -t proxy-converter .
|
| 38 |
+
docker run -p 1080:7860 -e TARGET_WSPROXY_URL=$TARGET_WSPROXY_URL proxy-converter
|
| 39 |
+
```
|
| 40 |
+
|
| 41 |
+
## 使用方法
|
| 42 |
+
|
| 43 |
+
部署完成后,你可以使用以下代理设置:
|
| 44 |
+
|
| 45 |
+
- **SOCKS5 代理**:
|
| 46 |
+
- 主机: `your-space-name.hf.space`
|
| 47 |
+
- 端口: 443(或 Hugging Face 分配的端口)
|
| 48 |
+
- 类型: SOCKS5
|
| 49 |
+
- (注:可能需要使用 HTTP CONNECT 隧道连接)
|
| 50 |
+
|
| 51 |
+
- **HTTP 代理**(如果在 Dockerfile 中启用):
|
| 52 |
+
- URL: `http://your-space-name.hf.space`
|
| 53 |
+
- 端口: 443(或 Hugging Face 分配的端口)
|
| 54 |
+
|
| 55 |
+
## 故障排除
|
| 56 |
+
|
| 57 |
+
- **无法连接**:确保 `TARGET_WSPROXY_URL` 指向正确的第一个 Space 的 WebSocket 地址
|
| 58 |
+
- **连接失败**:尝试在 Dockerfile 中切换协议类型(SOCKS5 / HTTP)
|
| 59 |
+
- **性能问题**:Hugging Face 对免费 Spaces 有带宽和计算限制,请考虑升级或使用其他平台
|
| 60 |
+
|
| 61 |
+
## 自定义
|
| 62 |
+
|
| 63 |
+
修改 `Dockerfile` 中的配置可以自定义代理类型、添加认证等。详细请参考 [gost 文档](https://github.com/ginuerzh/gost/blob/master/README_en.md)。
|
| 64 |
+
|
| 65 |
+
## 安全注意事项
|
| 66 |
+
|
| 67 |
+
这种代理转换不提供加密,所以不要用于传输敏感数据,除非你信任 Hugging Face 的网络环境。如需加密传输,请考虑在此基础上配置 TLS。
|
app.py
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
这个文件是为了 Hugging Face Spaces 而创建的。
|
| 3 |
+
当使用 Dockerfile 部署时,Hugging Face 仍然期望存在一个 app.py 文件,
|
| 4 |
+
但实际上服务是由 Dockerfile 中的命令启动的,这个文件不会被执行。
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
print("这个文件不会被 Hugging Face Spaces 执行。")
|
| 8 |
+
print("实际服务由 Dockerfile 和 start.sh 启动。")
|
start.sh
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
|
| 3 |
+
# 显示欢迎信息
|
| 4 |
+
echo "======================================"
|
| 5 |
+
echo " WebSocket Proxy Converter (by gost)"
|
| 6 |
+
echo "======================================"
|
| 7 |
+
echo "Starting service at port 7860..."
|
| 8 |
+
|
| 9 |
+
# 检查目标 WebSocket 代理 URL 是否已设置
|
| 10 |
+
if [ -z "$TARGET_WSPROXY_URL" ]; then
|
| 11 |
+
echo "Error: TARGET_WSPROXY_URL environment variable is not set."
|
| 12 |
+
echo "Please set it to your WebSocket proxy URL, like: wss://your-first-space.hf.space/wsproxy"
|
| 13 |
+
exit 1
|
| 14 |
+
fi
|
| 15 |
+
|
| 16 |
+
echo "Target WebSocket proxy: $TARGET_WSPROXY_URL"
|
| 17 |
+
|
| 18 |
+
# 创建状态页面
|
| 19 |
+
mkdir -p /app/html
|
| 20 |
+
cat > /app/html/index.html << EOF
|
| 21 |
+
<!DOCTYPE html>
|
| 22 |
+
<html>
|
| 23 |
+
<head>
|
| 24 |
+
<title>Proxy Converter Status</title>
|
| 25 |
+
<style>
|
| 26 |
+
body {
|
| 27 |
+
font-family: Arial, sans-serif;
|
| 28 |
+
max-width: 800px;
|
| 29 |
+
margin: 0 auto;
|
| 30 |
+
padding: 20px;
|
| 31 |
+
line-height: 1.6;
|
| 32 |
+
}
|
| 33 |
+
.status {
|
| 34 |
+
padding: 15px;
|
| 35 |
+
background-color: #d4edda;
|
| 36 |
+
border-radius: 5px;
|
| 37 |
+
color: #155724;
|
| 38 |
+
margin: 20px 0;
|
| 39 |
+
border-left: 4px solid #28a745;
|
| 40 |
+
}
|
| 41 |
+
h1 {
|
| 42 |
+
color: #333;
|
| 43 |
+
border-bottom: 1px solid #eee;
|
| 44 |
+
padding-bottom: 10px;
|
| 45 |
+
}
|
| 46 |
+
code {
|
| 47 |
+
background: #f4f4f4;
|
| 48 |
+
padding: 2px 5px;
|
| 49 |
+
border-radius: 3px;
|
| 50 |
+
}
|
| 51 |
+
.info {
|
| 52 |
+
background-color: #e9f5ff;
|
| 53 |
+
border-left: 4px solid #0088ff;
|
| 54 |
+
padding: 15px;
|
| 55 |
+
margin: 20px 0;
|
| 56 |
+
border-radius: 5px;
|
| 57 |
+
}
|
| 58 |
+
</style>
|
| 59 |
+
</head>
|
| 60 |
+
<body>
|
| 61 |
+
<h1>WebSocket 代理转换器状态</h1>
|
| 62 |
+
|
| 63 |
+
<div class="status">
|
| 64 |
+
<strong>状态:</strong> 代理转换器正在运行
|
| 65 |
+
</div>
|
| 66 |
+
|
| 67 |
+
<div class="info">
|
| 68 |
+
<h3>代理信息:</h3>
|
| 69 |
+
<ul>
|
| 70 |
+
<li><strong>SOCKS5 代理地址:</strong> <code>$(hostname):7860</code></li>
|
| 71 |
+
<li><strong>目标 WebSocket 代理:</strong> <code>${TARGET_WSPROXY_URL}</code></li>
|
| 72 |
+
</ul>
|
| 73 |
+
</div>
|
| 74 |
+
|
| 75 |
+
<h3>使用说明</h3>
|
| 76 |
+
<p>将您的应用配置为使用此 Space 的地址作为 SOCKS5 代理:</p>
|
| 77 |
+
<ul>
|
| 78 |
+
<li><strong>主机:</strong> <code>$(hostname)</code> 或 <code>您的Space地址.hf.space</code></li>
|
| 79 |
+
<li><strong>端口:</strong> <code>443</code> (或 Hugging Face 分配的端口)</li>
|
| 80 |
+
<li><strong>类型:</strong> <code>SOCKS5</code></li>
|
| 81 |
+
</ul>
|
| 82 |
+
|
| 83 |
+
<p><em>注意: 此页面每30秒自动刷新以显示最新状态</em></p>
|
| 84 |
+
<script>
|
| 85 |
+
setTimeout(function() {
|
| 86 |
+
location.reload();
|
| 87 |
+
}, 30000);
|
| 88 |
+
</script>
|
| 89 |
+
</body>
|
| 90 |
+
</html>
|
| 91 |
+
EOF
|
| 92 |
+
|
| 93 |
+
# 同时启动 HTTP 服务和 gost
|
| 94 |
+
# 在后台启动 gost SOCKS5 服务
|
| 95 |
+
echo "Starting gost SOCKS5 proxy..."
|
| 96 |
+
gost -L "socks5://:7860" -F "$TARGET_WSPROXY_URL" &
|
| 97 |
+
GOST_PID=$!
|
| 98 |
+
|
| 99 |
+
# 可选:启用 HTTP 代理转发
|
| 100 |
+
# 如果要使用 HTTP 代理而不是 SOCKS5,取消下面两行的注释,并注释掉上面的 gost 命令
|
| 101 |
+
# echo "Starting gost HTTP proxy..."
|
| 102 |
+
# gost -L "http://:7860" -F "$TARGET_WSPROXY_URL" &
|
| 103 |
+
|
| 104 |
+
# 启动一个简单的 HTTP 服务器提供状态页面,如果请求不是代理请求
|
| 105 |
+
cd /app/html
|
| 106 |
+
python3 -m http.server 7861 &
|
| 107 |
+
HTTP_PID=$!
|
| 108 |
+
|
| 109 |
+
# 检查 gost 是否已经启动
|
| 110 |
+
if ! ps -p $GOST_PID > /dev/null; then
|
| 111 |
+
echo "Failed to start gost. Exiting..."
|
| 112 |
+
exit 1
|
| 113 |
+
fi
|
| 114 |
+
|
| 115 |
+
echo "Proxy converter is running..."
|
| 116 |
+
echo "- SOCKS5 proxy at port 7860"
|
| 117 |
+
echo "- Status page at port 7861"
|
| 118 |
+
|
| 119 |
+
# 设置捕获信号
|
| 120 |
+
trap "kill $GOST_PID $HTTP_PID; exit" SIGINT SIGTERM
|
| 121 |
+
|
| 122 |
+
# 等待 gost 进程结束
|
| 123 |
+
wait $GOST_PID
|