sync: upstream + our customizations (dashboard, healthcheck, docs)
Synced from github/main: aebcfa2d copybot: live paper feed [skip ci]
Our additions: serve_dashboard.py, bot_dashboard.html, mihomo-healthcheck.sh,
中文文档, 我们的钱包配置
This commit is contained in:
+919
@@ -0,0 +1,919 @@
|
||||
# 云端 mihomo 代理部署教程
|
||||
|
||||
> 本文档教你在一台 Linux 云服务器上部署 mihomo(Clash Meta 内核)代理,用于绕过 Polymarket 的 geo-block(地理封锁),让 live trading bot 能在禁单地区(美国/英国/法国等)的服务器上下单。
|
||||
>
|
||||
> **适用场景**:paper bot 不需要代理(只读 API 全球开放),live bot 必须走代理(下单 API 有 geo-block)。
|
||||
|
||||
---
|
||||
|
||||
## 快速复用(代理已部署完成)
|
||||
|
||||
> 如果你所在的服务器**已经部署过 mihomo 代理**(按本文档下方教程完成),直接看这一节就能让新应用走代理。不用重新装。
|
||||
|
||||
### 代理位置
|
||||
|
||||
| 文件/服务 | 位置 | 说明 |
|
||||
|-----------|------|------|
|
||||
| mihomo 程序 | `/usr/local/bin/mihomo` | 二进制本体 |
|
||||
| 配置文件 | `/etc/mihomo/config.yaml` | 订阅配置 |
|
||||
| 节点记忆 | `/etc/mihomo/cache.db` | 重启后自动恢复上次选的节点 |
|
||||
| systemd 服务 | `/etc/systemd/system/mihomo.service` | 24/7 后台运行 |
|
||||
| 健康检查脚本 | `/opt/mihomo-healthcheck.sh` | 每 5 分钟自动检测 + 轮换 |
|
||||
| 监听地址 | `127.0.0.1:7890` | HTTP + SOCKS5 混合代理 |
|
||||
| 管理 API | `127.0.0.1:9090` | 切换节点 / 查状态 |
|
||||
|
||||
### 让你的应用走代理
|
||||
|
||||
**方法 A:环境变量(最常用)**
|
||||
|
||||
在应用的 systemd unit 里加 `EnvironmentFile`,或在启动命令前设环境变量:
|
||||
|
||||
```bash
|
||||
# 临时测试
|
||||
HTTPS_PROXY=http://127.0.0.1:7890 curl -s https://ipinfo.io/json
|
||||
|
||||
# 或写入 env 文件让 systemd 服务用
|
||||
echo "HTTPS_PROXY=http://127.0.0.1:7890" >> /etc/copybot/你的应用.env
|
||||
```
|
||||
|
||||
Python 的 `requests` / `urllib` / `httpx` 都会自动读 `HTTPS_PROXY` 环境变量,**不需要改代码**。
|
||||
|
||||
**方法 B:代码里显式指定(需要改代码)**
|
||||
|
||||
```python
|
||||
import requests
|
||||
proxies = {"https": "http://127.0.0.1:7890", "http": "http://127.0.0.1:7890"}
|
||||
r = requests.get("https://clob.polymarket.com/order", proxies=proxies)
|
||||
```
|
||||
|
||||
**方法 C:curl 命令行**
|
||||
|
||||
```bash
|
||||
curl -x http://127.0.0.1:7890 https://目标网址
|
||||
# 或
|
||||
HTTPS_PROXY=http://127.0.0.1:7890 curl https://目标网址
|
||||
```
|
||||
|
||||
### 验证代理在工作
|
||||
|
||||
```bash
|
||||
# 1. 代理服务活着?
|
||||
systemctl is-active mihomo
|
||||
# 预期: active
|
||||
|
||||
# 2. 端口在监听?
|
||||
ss -tlnp | grep 7890
|
||||
# 预期: LISTEN ... 127.0.0.1:7890 ...
|
||||
|
||||
# 3. 出口 IP 对不对?
|
||||
HTTPS_PROXY=http://127.0.0.1:7890 curl -s https://ipinfo.io/json
|
||||
# 预期: country 不是 US/GB/FR 等禁单地区
|
||||
|
||||
# 4. Polymarket 能下单?
|
||||
HTTPS_PROXY=http://127.0.0.1:7890 python3 /opt/winning-wallet-finder/host/geocheck.py | tail -1
|
||||
# 预期: VERDICT: TRADABLE
|
||||
```
|
||||
|
||||
### 只让特定应用走代理(不影响其他服务)
|
||||
|
||||
mihomo **不是系统级透明代理**(没开 TUN 模式),只有设了 `HTTPS_PROXY` 的程序才走代理。
|
||||
|
||||
**正确做法**:只在需要的应用的 env 文件里设 `HTTPS_PROXY`:
|
||||
```
|
||||
# /etc/copybot/live.env
|
||||
HTTPS_PROXY=http://127.0.0.1:7890
|
||||
```
|
||||
|
||||
**错误做法**:全局设(会让所有程序走代理):
|
||||
```bash
|
||||
# ❌ 不要这样做
|
||||
echo "HTTPS_PROXY=http://127.0.0.1:7890" >> /etc/environment
|
||||
echo "export HTTPS_PROXY=http://127.0.0.1:7890" >> ~/.bashrc
|
||||
```
|
||||
|
||||
### 让 systemd 服务依赖代理
|
||||
|
||||
如果你的应用**必须**走代理才能工作(如 live bot),在 systemd unit 里加依赖:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
After=network-online.target mihomo.service
|
||||
Requires=mihomo.service
|
||||
```
|
||||
|
||||
这样 mihomo 挂了你的应用也会停(不会在没代理的情况下裸奔),mihomo 恢复后自动重启。
|
||||
|
||||
### 当前节点状态 + 手动切换
|
||||
|
||||
```bash
|
||||
# 看当前用的哪个节点
|
||||
curl -s http://127.0.0.1:9090/proxies/GLOBAL | python3 -c "import sys,json; print('当前:', json.load(sys.stdin).get('now'))"
|
||||
|
||||
# 手动换节点(节点名从 config.yaml 里找)
|
||||
curl -s -X PUT http://127.0.0.1:9090/proxies/GLOBAL \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"🇯🇵日本高速06|BGP|CTCU"}'
|
||||
|
||||
# 手动跑健康检查(测当前节点通不通,不通自动换)
|
||||
/opt/mihomo-healthcheck.sh && echo "正常" || echo "异常"
|
||||
```
|
||||
|
||||
### 健康检查自动轮换
|
||||
|
||||
已配置 cron 每 5 分钟自动检查:
|
||||
- 当前节点通 -> 什么都不做
|
||||
- 当前节点挂 -> 自动遍历所有非美国节点,找到能用的就切换
|
||||
- 全部挂 -> 写 syslog 告警
|
||||
|
||||
```bash
|
||||
# 查看自动切换记录
|
||||
journalctl -t mihomo-healthcheck
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 新服务器部署教程
|
||||
|
||||
> 以下是从零开始在新服务器上部署 mihomo 代理的完整步骤。如果你的服务器已经部署过,跳过这一部分,直接看上面的[快速复用](#快速复用代理已部署完成)。
|
||||
|
||||
---
|
||||
|
||||
## 目录(完整部署)
|
||||
|
||||
1. [为什么需要代理](#1-为什么需要代理)
|
||||
2. [前置条件](#2-前置条件)
|
||||
3. [安装 mihomo](#3-安装-mihomo)
|
||||
4. [获取代理订阅配置](#4-获取代理订阅配置)
|
||||
5. [启动与节点选择](#5-启动与节点选择)
|
||||
6. [做成 systemd 服务](#6-做成-systemd-服务)
|
||||
7. [自动健康检查 + IP 轮换](#7-自动健康检查--ip-轮换)
|
||||
8. [让 live bot 走代理](#8-让-live-bot-走代理)
|
||||
9. [验证全链路](#9-验证全链路)
|
||||
10. [日常运维命令](#10-日常运维命令)
|
||||
11. [常见坑](#11-常见坑)
|
||||
|
||||
---
|
||||
|
||||
## 1. 为什么需要代理
|
||||
|
||||
### Polymarket 的 geo-block
|
||||
|
||||
Polymarket 禁止以下地区的 IP 下单(CLOB order API 返回 403):
|
||||
|
||||
```
|
||||
美国 · 英国 · 法国 · 德国 · 意大利 · 荷兰 · 波兰 · 新加坡 · 澳大利亚 · 加拿大安大略 · 巴西
|
||||
```
|
||||
|
||||
**允许的常见地区**:日本、香港、瑞典、南非、印度、韩国、台湾等。
|
||||
|
||||
### 两种 API 的区别
|
||||
|
||||
| API | 用途 | 有 geo-block? | 需要代理? |
|
||||
|-----|------|---------------|-----------|
|
||||
| data-api / gamma-api | 读取市场/钱包数据 | ❌ 全球开放 | paper bot 不需要 |
|
||||
| clob.polymarket.com/order | **下单** | ✅ 禁单地区 403 | **live bot 必须** |
|
||||
|
||||
### geo-gate 检测
|
||||
|
||||
项目自带 `host/geocheck.py` 脚本检测服务器能否下单:
|
||||
|
||||
```bash
|
||||
cd /opt/winning-wallet-finder
|
||||
python3 host/geocheck.py
|
||||
```
|
||||
|
||||
结果判读:
|
||||
- `VERDICT: TRADABLE` → 不需要代理,跳过本教程
|
||||
- `VERDICT: BLOCKED` → 需要代理,继续往下看
|
||||
- `VERDICT: UNKNOWN` → 网络问题,检查服务器能不能连 Polymarket
|
||||
|
||||
### 代理的工作原理
|
||||
|
||||
```
|
||||
你的服务器(美国/英国等禁单地区)
|
||||
│
|
||||
│ HTTPS_PROXY=http://127.0.0.1:7890
|
||||
▼
|
||||
mihomo 代理(监听 127.0.0.1:7890)
|
||||
│
|
||||
│ 通过日本/香港等节点中转
|
||||
▼
|
||||
Polymarket CLOB API ← 看到的是节点的 IP(日本),不是你服务器的 IP(美国)
|
||||
```
|
||||
|
||||
**关键**:mihomo 不是系统级透明代理(不开 TUN 模式),只有**显式设置了 `HTTPS_PROXY` 环境变量的程序**才走代理。其他程序(paper bot、dashboard、Gitea、SSH 等)全部直连,不受影响。
|
||||
|
||||
---
|
||||
|
||||
## 2. 前置条件
|
||||
|
||||
- [ ] 一台 Linux 服务器(Ubuntu 20.04+ / Debian 11+),root 权限
|
||||
- [ ] 服务器在 Polymarket 禁单地区(`geocheck.py` 返回 `BLOCKED`)
|
||||
- [ ] 一个 Clash 订阅链接(机场提供),且订阅里有**非禁单地区**的节点(日本/香港/新加坡/韩国等)
|
||||
- [ ] 你知道订阅里哪些节点是美国的(要避开)
|
||||
|
||||
### 确认禁单地区
|
||||
|
||||
```bash
|
||||
python3 /opt/winning-wallet-finder/host/geocheck.py
|
||||
```
|
||||
|
||||
如果输出 `VERDICT: BLOCKED`,说明你的服务器在禁单地区,需要配代理。
|
||||
|
||||
---
|
||||
|
||||
## 3. 安装 mihomo
|
||||
|
||||
mihomo(原名 Clash Meta)是 Clash 的开源内核,纯命令行,无 GUI,适合服务器。
|
||||
|
||||
```bash
|
||||
# 下载
|
||||
cd /tmp
|
||||
wget -q https://github.com/MetaCubeX/mihomo/releases/download/v1.19.0/mihomo-linux-amd64-v1.19.0.gz
|
||||
gzip -d mihomo-linux-amd64-v1.19.0.gz
|
||||
mv mihomo-linux-amd64-v1.19.0 /usr/local/bin/mihomo
|
||||
chmod +x /usr/local/bin/mihomo
|
||||
|
||||
# 验证
|
||||
mihomo -v
|
||||
```
|
||||
|
||||
预期输出类似 `Mihomo Meta v1.19.0 ...`。
|
||||
|
||||
> 如果 GitHub 下载慢,可以用代理或镜像站下载后 `scp` 到服务器。
|
||||
|
||||
---
|
||||
|
||||
## 4. 获取代理订阅配置
|
||||
|
||||
### 4.1 找到你的订阅链接
|
||||
|
||||
你的代理机场(如 Clash Verge 订阅)会提供一个订阅 URL,通常长这样:
|
||||
|
||||
```
|
||||
https://xxx.com/api/v1/client/subscribe?token=abcdef123456...
|
||||
```
|
||||
|
||||
**如何找到**:
|
||||
- Clash Verge 客户端 → 订阅页面 → 右键订阅卡片 → 复制订阅链接
|
||||
- 或机场官网 → 用户中心 → 复制订阅链接
|
||||
|
||||
### 4.2 下载订阅配置
|
||||
|
||||
⚠️ **大坑**:机场会检测 User-Agent,`wget` 默认 UA 会被识别为非 Clash 客户端,返回**假节点**(名字是"当前Clash客户端不支持本机场协议"之类的提示,实际连接 127.0.0.1:65535)。
|
||||
|
||||
**必须伪装 User-Agent + 指定 flag=meta**:
|
||||
|
||||
```bash
|
||||
mkdir -p /etc/mihomo
|
||||
|
||||
wget -O /etc/mihomo/config.yaml \
|
||||
--user-agent="clash-verge/v1.7.7" \
|
||||
"你的订阅链接&flag=meta"
|
||||
```
|
||||
|
||||
### 4.3 验证拿到的是真实节点
|
||||
|
||||
```bash
|
||||
# 查看节点列表
|
||||
grep "name:" /etc/mihomo/config.yaml | head -30
|
||||
```
|
||||
|
||||
**正确**:看到真实节点名,如 `🇯🇵日本高速01|BGP|CTCU`、`🇭🇰香港高速02|BGP|CMCU` 等。
|
||||
|
||||
**错误**(假节点):
|
||||
```
|
||||
name: 当前Clash客户端不支持本机场协议
|
||||
name: 请更换以下支持协议的代理软件
|
||||
```
|
||||
|
||||
如果拿到假节点,尝试以下方法:
|
||||
1. 换 User-Agent:`--user-agent="clash.meta"` 或 `--user-agent="ClashforWindows/0.20.39"`
|
||||
2. 换 flag 参数:`&flag=clash` 或 `&flag=meta`
|
||||
3. 直接在本地 Clash 客户端导出配置文件,`scp` 到服务器
|
||||
|
||||
### 4.4 筛选非美国节点
|
||||
|
||||
Polymarket 禁单地区包括美国,必须选**非美国**节点。
|
||||
|
||||
```bash
|
||||
# 列出所有节点名
|
||||
grep "name:" /etc/mihomo/config.yaml | grep -oP "name: [^,}]+" | sed 's/name: //'
|
||||
```
|
||||
|
||||
**可用节点**(不在禁单列表):
|
||||
- 🇯🇵 日本(JP)
|
||||
- 🇭🇰 香港(HK)
|
||||
- 🇸🇬 新加坡(SG)⚠️ 新加坡在禁单列表!不能用
|
||||
- 🇰🇷 韩国(KR)
|
||||
- 🇨🇳 台湾(TW)
|
||||
- 🇸🇪 瑞典(SE)
|
||||
|
||||
**不可用节点**(在禁单列表):
|
||||
- 🇺🇸 美国(US)
|
||||
- 🇬🇧 英国(GB)
|
||||
- 🇫🇷 法国(FR)
|
||||
- 🇩🇪 德国(DE)
|
||||
- 🇮🇹 意大利(IT)
|
||||
- 🇳🇱 荷兰(NL)
|
||||
- 🇵🇱 波兰(PL)
|
||||
- 🇸🇬 新加坡(SG)
|
||||
- 🇦🇺 澳大利亚(AU)
|
||||
|
||||
> **注意**:新加坡虽然在很多机场里速度快,但 Polymarket 禁单!必须避开。
|
||||
|
||||
### 4.5 改全局模式
|
||||
|
||||
mihomo 默认是 `rule` 模式(按规则分流),我们需要 `global` 模式(所有流量走指定节点):
|
||||
|
||||
```bash
|
||||
sed -i 's/^mode: rule/mode: global/' /etc/mihomo/config.yaml
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 启动与节点选择
|
||||
|
||||
### 5.1 前台启动(测试用)
|
||||
|
||||
```bash
|
||||
mihomo -d /etc/mihomo
|
||||
```
|
||||
|
||||
等待几秒(首次启动会下载 GeoSite 数据库),看到 `Mixed(http+socks) proxy listening at: 127.0.0.1:7890` 表示成功。
|
||||
|
||||
`Ctrl+C` 退出(后面会做成 systemd 服务)。
|
||||
|
||||
### 5.2 选择非美国节点
|
||||
|
||||
mihomo 启动后默认 GLOBAL 组走 DIRECT(直连),需要通过 API 手动选节点。
|
||||
|
||||
```bash
|
||||
# 查看当前 GLOBAL 选的什么
|
||||
curl -s http://127.0.0.1:9090/proxies/GLOBAL | python3 -c "import sys,json; print('当前:', json.load(sys.stdin).get('now'))"
|
||||
|
||||
# 切换到日本节点(替换成你订阅里的真实节点名)
|
||||
curl -s -X PUT http://127.0.0.1:9090/proxies/GLOBAL \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"🇯🇵日本高速06|BGP|CTCU"}'
|
||||
```
|
||||
|
||||
> **节点名必须跟 config.yaml 里的 `name:` 字段完全一致**(包括 emoji 和特殊字符)。
|
||||
|
||||
### 5.3 验证代理 + geo-gate
|
||||
|
||||
```bash
|
||||
# 测出口 IP(应该不是美国)
|
||||
HTTPS_PROXY=http://127.0.0.1:7890 curl -s https://ipinfo.io/json
|
||||
|
||||
# 测 Polymarket geo-gate(关键!)
|
||||
HTTPS_PROXY=http://127.0.0.1:7890 python3 /opt/winning-wallet-finder/host/geocheck.py
|
||||
```
|
||||
|
||||
预期最后一行:`VERDICT: TRADABLE - order endpoint reachable past the geo-gate`
|
||||
|
||||
如果还是 `BLOCKED`,说明选的节点也在禁单地区,换一个节点再试。
|
||||
|
||||
### 5.4 mihomo 自动记住节点选择
|
||||
|
||||
mihomo 会把节点选择保存在 `/etc/mihomo/cache.db`,重启后自动恢复。**第一次手动选完,以后重启不用再选**。
|
||||
|
||||
验证:
|
||||
```bash
|
||||
# 选好节点后重启 mihomo
|
||||
systemctl restart mihomo # 或 kill 后重启
|
||||
sleep 5
|
||||
|
||||
# 看它记不记得
|
||||
curl -s http://127.0.0.1:9090/proxies/GLOBAL | python3 -c "import sys,json; print('当前:', json.load(sys.stdin).get('now'))"
|
||||
```
|
||||
|
||||
如果输出你之前选的节点名,说明记住了。
|
||||
|
||||
---
|
||||
|
||||
## 6. 做成 systemd 服务
|
||||
|
||||
### 6.1 杀掉前台进程
|
||||
|
||||
```bash
|
||||
kill $(pgrep mihomo)
|
||||
```
|
||||
|
||||
### 6.2 写 systemd unit
|
||||
|
||||
```bash
|
||||
cat > /etc/systemd/system/mihomo.service <<'EOF'
|
||||
[Unit]
|
||||
Description=Mihomo (Clash Meta) Proxy
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/local/bin/mihomo -d /etc/mihomo
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=mihomo
|
||||
|
||||
NoNewPrivileges=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
```
|
||||
|
||||
### 6.3 启动 + 验证
|
||||
|
||||
```bash
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now mihomo
|
||||
sleep 5
|
||||
|
||||
# 确认服务活着
|
||||
systemctl status mihomo --no-pager | head -5
|
||||
|
||||
# 确认端口在监听
|
||||
ss -tlnp | grep 7890
|
||||
|
||||
# 确认节点选择还在(mihomo 应该记住了)
|
||||
curl -s http://127.0.0.1:9090/proxies/GLOBAL | python3 -c "import sys,json; print('当前节点:', json.load(sys.stdin).get('now'))"
|
||||
|
||||
# 确认代理 + geo-gate 通过
|
||||
HTTPS_PROXY=http://127.0.0.1:7890 python3 /opt/winning-wallet-finder/host/geocheck.py | tail -1
|
||||
```
|
||||
|
||||
预期:
|
||||
- `Active: active (running)`
|
||||
- `:7890` 在监听
|
||||
- 当前节点是你选的非美国节点
|
||||
- `VERDICT: TRADABLE`
|
||||
|
||||
---
|
||||
|
||||
## 7. 自动健康检查 + IP 轮换
|
||||
|
||||
### 7.1 为什么需要
|
||||
|
||||
代理节点可能随时挂掉(服务器维护、被封 IP、网络抖动等)。如果节点挂了:
|
||||
- live bot 的所有请求超时
|
||||
- bot 无法下单
|
||||
- `CASH≠CHAIN` 警告可能出现
|
||||
|
||||
需要**自动检测 + 自动切换**到其他可用节点。
|
||||
|
||||
### 7.2 健康检查脚本
|
||||
|
||||
```bash
|
||||
cat > /opt/mihomo-healthcheck.sh <<'SCRIPT'
|
||||
#!/bin/bash
|
||||
# 检查代理是否通,不通就自动换非美国节点
|
||||
API="http://127.0.0.1:9090"
|
||||
PROXY="http://127.0.0.1:7890"
|
||||
|
||||
# 1. 测当前节点能不能连 Polymarket CLOB API
|
||||
code=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 -x $PROXY \
|
||||
"https://clob.polymarket.com/markets?next_cursor=" 2>/dev/null)
|
||||
|
||||
if [ "$code" = "200" ]; then
|
||||
exit 0 # 通的,不用换
|
||||
fi
|
||||
|
||||
# 2. 不通,拉所有节点列表,挑非美国的试
|
||||
nodes=$(curl -s "$API/proxies" | python3 -c "
|
||||
import sys, json
|
||||
d = json.load(sys.stdin)
|
||||
skip = {'DIRECT','REJECT','自动选择','故障转移','良心云','GLOBAL'}
|
||||
# Polymarket 禁单地区关键词(节点名里包含这些的不选)
|
||||
blocked = ['美国','US','United States','英国','GB','法国','FR','德国','DE',
|
||||
'意大利','IT','荷兰','NL','波兰','PL','新加坡','SG','新加坡',
|
||||
'澳大利亚','AU','澳洲','巴西','BR']
|
||||
for name, info in d.get('proxies', {}).items():
|
||||
if name in skip:
|
||||
continue
|
||||
if info.get('type') in ('Selector','URLTest','Fallback','LoadBalance'):
|
||||
continue
|
||||
if any(k in name for k in blocked):
|
||||
continue
|
||||
print(name)
|
||||
")
|
||||
|
||||
# 3. 逐个试,找到能用的就切
|
||||
for node in $nodes; do
|
||||
curl -s -X PUT "$API/proxies/GLOBAL" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"name\":\"$node}" > /dev/null
|
||||
sleep 2
|
||||
code=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 -x $PROXY \
|
||||
"https://clob.polymarket.com/markets?next_cursor=" 2>/dev/null)
|
||||
if [ "$code" = "200" ]; then
|
||||
logger "mihomo-healthcheck: switched to $node (previous was down)"
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
|
||||
logger "mihomo-healthcheck: ALL nodes failed - check mihomo or subscription"
|
||||
exit 1
|
||||
SCRIPT
|
||||
|
||||
chmod +x /opt/mihomo-healthcheck.sh
|
||||
```
|
||||
|
||||
### 7.3 加 cron 定时任务
|
||||
|
||||
```bash
|
||||
# 每 5 分钟检查一次
|
||||
(crontab -l 2>/dev/null | grep -v mihomo-healthcheck; \
|
||||
echo "*/5 * * * * /opt/mihomo-healthcheck.sh") | crontab -
|
||||
|
||||
# 验证
|
||||
crontab -l | grep mihomo
|
||||
```
|
||||
|
||||
### 7.4 手动测试健康检查
|
||||
|
||||
```bash
|
||||
/opt/mihomo-healthcheck.sh && echo "代理正常 ✓" || echo "代理异常 ✗"
|
||||
```
|
||||
|
||||
### 7.5 健康检查的工作逻辑
|
||||
|
||||
```
|
||||
每 5 分钟 cron 触发
|
||||
│
|
||||
▼
|
||||
测当前节点能否连 Polymarket CLOB API
|
||||
│
|
||||
├── 200 OK → 退出(代理正常)
|
||||
│
|
||||
└── 非 200 / 超时 → 当前节点挂了
|
||||
│
|
||||
▼
|
||||
遍历所有非美国节点
|
||||
│
|
||||
├── 找到一个能连的 → 切换 + 写 syslog
|
||||
│
|
||||
└── 全部失败 → 写 syslog 告警
|
||||
```
|
||||
|
||||
### 7.6 查看健康检查日志
|
||||
|
||||
```bash
|
||||
# 查看切换记录
|
||||
journalctl -t mihomo-healthcheck
|
||||
|
||||
# 或
|
||||
grep mihomo-healthcheck /var/log/syslog
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 让 live bot 走代理
|
||||
|
||||
### 8.1 原理
|
||||
|
||||
`py_clob_client`(Polymarket 下单 SDK)底层用 Python `requests` 库,`requests` 自动读 `HTTPS_PROXY` 环境变量。所以只要在 live bot 的环境变量里设 `HTTPS_PROXY`,所有下单请求自动走代理。
|
||||
|
||||
### 8.2 配置 live.env
|
||||
|
||||
在 `/etc/copybot/live.env` 里加一行:
|
||||
|
||||
```
|
||||
HTTPS_PROXY=http://127.0.0.1:7890
|
||||
```
|
||||
|
||||
完整 live.env 示例:
|
||||
|
||||
```
|
||||
LIVE_PRIVATE_KEY=0x你的私钥
|
||||
LIVE_FUNDER_ADDRESS=0x你的钱包地址
|
||||
LIVE_SIGNATURE_TYPE=1
|
||||
LIVE_CONFIRM=TRADE LIVE
|
||||
HTTPS_PROXY=http://127.0.0.1:7890
|
||||
```
|
||||
|
||||
### 8.3 live systemd unit 依赖 mihomo
|
||||
|
||||
确保 live bot 的 systemd unit 有 `Requires=mihomo.service` 和 `After=mihomo.service`:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Polymarket LIVE Copybot (real money)
|
||||
After=network-online.target mihomo.service
|
||||
Wants=network-online.target
|
||||
Requires=mihomo.service
|
||||
```
|
||||
|
||||
这样 mihomo 挂了 live bot 也会停(不会在没代理的情况下尝试下单),mihomo 恢复后 live bot 自动重启。
|
||||
|
||||
### 8.4 隔离原则
|
||||
|
||||
| 服务 | 走代理? | 为什么 |
|
||||
|------|---------|--------|
|
||||
| live bot | ✅ 走 | 下单需要绕 geo-block |
|
||||
| paper bot | ❌ 直连 | 只读 API 不受 geo-block,直连更快 |
|
||||
| dashboard | ❌ 直连 | 本地文件服务,不需要外网 |
|
||||
| Gitea | ❌ 直连 | 推代码不需要代理 |
|
||||
| mihomo 本身 | ❌ 直连 | 代理连节点用直连 |
|
||||
|
||||
> **不要**把 `HTTPS_PROXY` 写进 `/etc/environment` 或 `~/.bashrc`(全局生效),只放在 `/etc/copybot/live.env` 里,只有 live systemd service 读它。
|
||||
|
||||
---
|
||||
|
||||
## 9. 验证全链路
|
||||
|
||||
### 9.1 代理层
|
||||
|
||||
```bash
|
||||
# mihomo 服务状态
|
||||
systemctl status mihomo
|
||||
|
||||
# 端口监听
|
||||
ss -tlnp | grep 7890
|
||||
|
||||
# 出口 IP(应该非美国)
|
||||
HTTPS_PROXY=http://127.0.0.1:7890 curl -s https://ipinfo.io/json | python3 -m json.tool
|
||||
|
||||
# Polymarket geo-gate
|
||||
HTTPS_PROXY=http://127.0.0.1:7890 python3 /opt/winning-wallet-finder/host/geocheck.py | tail -1
|
||||
```
|
||||
|
||||
### 9.2 健康检查
|
||||
|
||||
```bash
|
||||
/opt/mihomo-healthcheck.sh && echo "代理正常" || echo "代理异常"
|
||||
```
|
||||
|
||||
### 9.3 live bot 启动验证
|
||||
|
||||
```bash
|
||||
# 重启 live bot
|
||||
systemctl restart copybot-live
|
||||
sleep 10
|
||||
|
||||
# 看日志,应该有 geo-gate: TRADABLE
|
||||
journalctl -u copybot-live --since "15 seconds ago" --no-pager | grep -E "geo-gate|armed|TRADABLE|BLOCKED"
|
||||
```
|
||||
|
||||
预期看到 `geo-gate: TRADABLE - order endpoint reachable`。
|
||||
|
||||
---
|
||||
|
||||
## 10. 日常运维命令
|
||||
|
||||
### 看日志
|
||||
|
||||
```bash
|
||||
# mihomo 日志
|
||||
journalctl -u mihomo -f
|
||||
|
||||
# 健康检查切换记录
|
||||
journalctl -t mihomo-healthcheck
|
||||
|
||||
# live bot 日志(确认代理在工作)
|
||||
journalctl -u copybot-live -f
|
||||
```
|
||||
|
||||
### 代理管理
|
||||
|
||||
```bash
|
||||
# 看当前节点
|
||||
curl -s http://127.0.0.1:9090/proxies/GLOBAL | python3 -c "import sys,json; print('当前节点:', json.load(sys.stdin).get('now'))"
|
||||
|
||||
# 手动换节点(替换节点名)
|
||||
curl -s -X PUT http://127.0.0.1:9090/proxies/GLOBAL \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"🇯🇵日本高速06|BGP|CTCU"}'
|
||||
|
||||
# 手动健康检查
|
||||
/opt/mihomo-healthcheck.sh && echo "正常" || echo "异常"
|
||||
|
||||
# 测代理 + geo-gate
|
||||
HTTPS_PROXY=http://127.0.0.1:7890 python3 /opt/winning-wallet-finder/host/geocheck.py | tail -1
|
||||
```
|
||||
|
||||
### 服务管理
|
||||
|
||||
```bash
|
||||
systemctl restart mihomo # 重启代理
|
||||
systemctl stop mihomo # 停代理(live bot 也会停)
|
||||
systemctl start mihomo # 启代理(live bot 自动重启)
|
||||
systemctl status mihomo # 看状态
|
||||
```
|
||||
|
||||
### 更新订阅
|
||||
|
||||
```bash
|
||||
# 重新拉订阅(UA 不能忘!)
|
||||
wget -O /etc/mihomo/config.yaml \
|
||||
--user-agent="clash-verge/v1.7.7" \
|
||||
"你的订阅链接&flag=meta"
|
||||
|
||||
# 重启生效
|
||||
systemctl restart mihomo
|
||||
sleep 5
|
||||
|
||||
# 重新选节点(订阅更新后节点名可能变)
|
||||
curl -s http://127.0.0.1:9090/proxies/GLOBAL | python3 -c "import sys,json; print('当前:', json.load(sys.stdin).get('now'))"
|
||||
```
|
||||
|
||||
### Cron 管理
|
||||
|
||||
```bash
|
||||
crontab -l # 看所有定时任务
|
||||
# 健康检查每 5 分钟跑一次
|
||||
# 如果想改频率,编辑 crontab:
|
||||
crontab -e
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11. 常见坑
|
||||
|
||||
### 坑 1:机场返回假节点
|
||||
|
||||
**症状**:`grep "name:" config.yaml` 看到的节点名是"当前Clash客户端不支持本机场协议"之类的提示,连接地址是 127.0.0.1:65535。
|
||||
|
||||
**原因**:机场检测到 wget 的 User-Agent 不是 Clash 客户端。
|
||||
|
||||
**解法**:加 `--user-agent="clash-verge/v1.7.7"` + `&flag=meta` 参数:
|
||||
|
||||
```bash
|
||||
wget -O /etc/mihomo/config.yaml \
|
||||
--user-agent="clash-verge/v1.7.7" \
|
||||
"订阅链接&flag=meta"
|
||||
```
|
||||
|
||||
如果还是假节点,尝试不同的 UA:`clash.meta`、`ClashforWindows/0.20.39`、`clash-verge/v1.7.7`。
|
||||
|
||||
### 坑 2:选了新加坡节点,还是 BLOCKED
|
||||
|
||||
**症状**:切到新加坡节点后 `geocheck.py` 还是 `BLOCKED`。
|
||||
|
||||
**原因**:新加坡在 Polymarket 禁单列表里(很多人不知道)。
|
||||
|
||||
**解法**:换日本/香港/韩国/台湾等不在禁单列表的节点。禁单列表见 [§1](#1-为什么需要代理)。
|
||||
|
||||
### 坑 3:mihomo 重启后节点回到 DIRECT
|
||||
|
||||
**症状**:重启 mihomo 后 `geocheck.py` 变成 `BLOCKED`,检查发现 GLOBAL 回到 DIRECT。
|
||||
|
||||
**原因**:第一次启动后没手动选过节点,cache.db 里没记录。
|
||||
|
||||
**解法**:启动后手动选一次节点,mihomo 会记住(保存到 cache.db),以后重启自动恢复。
|
||||
|
||||
### 坑 4:代理影响其他服务
|
||||
|
||||
**症状**:paper bot / dashboard / Gitea 全部变慢或连不上。
|
||||
|
||||
**原因**:`HTTPS_PROXY` 被设成了全局环境变量(写进了 `/etc/environment` 或 `~/.bashrc`)。
|
||||
|
||||
**解法**:只在 `/etc/copybot/live.env` 里设 `HTTPS_PROXY`,不要全局设。mihomo 不是透明代理,只有显式设了 `HTTPS_PROXY` 的程序才走代理。
|
||||
|
||||
### 坑 5:config.yaml 追加 proxy-groups 导致启动失败
|
||||
|
||||
**症状**:mihomo 重启后报 YAML 解析错误,端口不监听。
|
||||
|
||||
**原因**:在 config.yaml 末尾追加了重复的 `proxy-groups:` 段,YAML 不允许重复键。
|
||||
|
||||
**解法**:不要追加,用 API 切换节点即可。如果一定要改 proxy-groups,编辑原有段而不是追加。
|
||||
|
||||
### 坑 6:健康检查脚本里的节点名有特殊字符
|
||||
|
||||
**症状**:健康检查脚本切换节点失败,`curl -X PUT` 返回 400。
|
||||
|
||||
**原因**:节点名包含 emoji 或特殊字符(如 `🇯🇵日本高速06|BGP|CTCU`),JSON 转义有问题。
|
||||
|
||||
**解法**:脚本里用 `python3` 读取节点列表并输出,`curl` 用 `-d` 传 JSON 时用双引号包裹。本文的脚本已处理此问题。
|
||||
|
||||
### 坑 7:mihomo 首次启动慢
|
||||
|
||||
**症状**:启动 mihomo 后 `curl` 连不上 7890 端口。
|
||||
|
||||
**原因**:首次启动会下载 GeoSite/MMDB 数据库(几 MB),需要几秒钟。
|
||||
|
||||
**解法**:等 5-10 秒再测试。看日志确认 `Mixed(http+socks) proxy listening at: 127.0.0.1:7890` 出现后再操作。
|
||||
|
||||
### 坑 8:live bot 报 CASH≠CHAIN
|
||||
|
||||
**症状**:live bot 日志出现 `⚠ CASH≠CHAIN $+X.XX`。
|
||||
|
||||
**原因**:代理在订单提交中途断了或切换了,bot 以为订单没成交但实际成交了,账本与链上不一致。
|
||||
|
||||
**解法**:
|
||||
1. 停 bot:`systemctl stop copybot-live`
|
||||
2. 查链上实际 pUSD 余额
|
||||
3. 更新 `config.live.json` 的 `bankroll_usd` 为实际余额
|
||||
4. 清 state:`rm -f /opt/winning-wallet-finder/copybot_state.live.json /opt/winning-wallet-finder/copybot_fills.live.jsonl /opt/winning-wallet-finder/live/copybot_live_real.json`
|
||||
5. 重启:`systemctl start copybot-live`
|
||||
|
||||
---
|
||||
|
||||
## 附录:完整部署一键脚本
|
||||
|
||||
> ⚠️ 不建议直接跑,建议按上面步骤一步步来。此脚本仅供参考。
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# 1. 装 mihomo
|
||||
cd /tmp
|
||||
wget -q https://github.com/MetaCubeX/mihomo/releases/download/v1.19.0/mihomo-linux-amd64-v1.19.0.gz
|
||||
gzip -d mihomo-linux-amd64-v1.19.0.gz
|
||||
mv mihomo-linux-amd64-v1.19.0 /usr/local/bin/mihomo
|
||||
chmod +x /usr/local/bin/mihomo
|
||||
|
||||
# 2. 拉订阅(替换 SUB_URL)
|
||||
SUB_URL="你的订阅链接"
|
||||
mkdir -p /etc/mihomo
|
||||
wget -O /etc/mihomo/config.yaml --user-agent="clash-verge/v1.7.7" "${SUB_URL}&flag=meta"
|
||||
sed -i 's/^mode: rule/mode: global/' /etc/mihomo/config.yaml
|
||||
|
||||
# 3. systemd 服务
|
||||
cat > /etc/systemd/system/mihomo.service <<'EOF'
|
||||
[Unit]
|
||||
Description=Mihomo (Clash Meta) Proxy
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/local/bin/mihomo -d /etc/mihomo
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=mihomo
|
||||
NoNewPrivileges=true
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now mihomo
|
||||
sleep 8
|
||||
|
||||
# 4. 健康检查脚本
|
||||
cat > /opt/mihomo-healthcheck.sh <<'SCRIPT'
|
||||
#!/bin/bash
|
||||
API="http://127.0.0.1:9090"
|
||||
PROXY="http://127.0.0.1:7890"
|
||||
code=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 -x $PROXY "https://clob.polymarket.com/markets?next_cursor=" 2>/dev/null)
|
||||
if [ "$code" = "200" ]; then exit 0; fi
|
||||
nodes=$(curl -s "$API/proxies" | python3 -c "
|
||||
import sys, json
|
||||
d = json.load(sys.stdin)
|
||||
skip = {'DIRECT','REJECT','自动选择','故障转移','良心云','GLOBAL'}
|
||||
blocked = ['美国','US','United States','英国','GB','法国','FR','德国','DE','意大利','IT','荷兰','NL','波兰','PL','新加坡','SG','澳大利亚','AU','澳洲','巴西','BR']
|
||||
for name, info in d.get('proxies', {}).items():
|
||||
if name in skip: continue
|
||||
if info.get('type') in ('Selector','URLTest','Fallback','LoadBalance'): continue
|
||||
if any(k in name for k in blocked): continue
|
||||
print(name)
|
||||
")
|
||||
for node in $nodes; do
|
||||
curl -s -X PUT "$API/proxies/GLOBAL" -H "Content-Type: application/json" -d "{\"name\":\"$node}" > /dev/null
|
||||
sleep 2
|
||||
code=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 -x $PROXY "https://clob.polymarket.com/markets?next_cursor=" 2>/dev/null)
|
||||
if [ "$code" = "200" ]; then
|
||||
logger "mihomo-healthcheck: switched to $node"
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
logger "mihomo-healthcheck: ALL nodes failed"
|
||||
exit 1
|
||||
SCRIPT
|
||||
chmod +x /opt/mihomo-healthcheck.sh
|
||||
|
||||
# 5. cron
|
||||
(crontab -l 2>/dev/null | grep -v mihomo-healthcheck; echo "*/5 * * * * /opt/mihomo-healthcheck.sh") | crontab -
|
||||
|
||||
echo "=== 部署完成 ==="
|
||||
echo "下一步:手动选一个非美国节点"
|
||||
echo " curl -s http://127.0.0.1:9090/proxies | python3 -m json.tool | grep name"
|
||||
echo " curl -s -X PUT http://127.0.0.1:9090/proxies/GLOBAL -H 'Content-Type: application/json' -d '{\"name\":\"节点名\"}'"
|
||||
echo "然后验证:"
|
||||
echo " HTTPS_PROXY=http://127.0.0.1:7890 python3 /opt/winning-wallet-finder/host/geocheck.py | tail -1"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 文件结构速查
|
||||
|
||||
```
|
||||
服务器
|
||||
├── /usr/local/bin/mihomo 代理程序本体
|
||||
├── /etc/mihomo/
|
||||
│ ├── config.yaml 订阅配置(机场下载)
|
||||
│ └── cache.db 节点选择记忆
|
||||
├── /etc/systemd/system/
|
||||
│ └── mihomo.service systemd 服务定义
|
||||
├── /opt/mihomo-healthcheck.sh 健康检查脚本
|
||||
├── /etc/copybot/
|
||||
│ └── live.env live bot 环境变量(含 HTTPS_PROXY)
|
||||
└── crontab
|
||||
└── */5 * * * * healthcheck.sh 每 5 分钟健康检查
|
||||
```
|
||||
Reference in New Issue
Block a user