- Trading skills (OKX, dividend, lottery, quantitative) - Creative skills (ASCII art, diagrams, video) - Development skills (GitHub, debugging, TDD) - Research skills (arXiv, blog monitoring) - Productivity skills (email, documents, notes) - MCP integration skills - Custom user skills
189 lines
8.8 KiB
Markdown
189 lines
8.8 KiB
Markdown
# Proxy Diagnostics: "Is the proxy working?"
|
|
|
|
Systematic checklist when the user asks whether the proxy is healthy, or when Hermes services show connection timeouts despite the proxy running.
|
|
|
|
## Key Insight
|
|
**Proxy works ≠ Hermes is using it.** These are independent checks. A curl test passing through the proxy proves the proxy is healthy, but Hermes may not be routing through it.
|
|
|
|
## Critical: Telegram Proxy Source
|
|
|
|
The Telegram adapter reads proxy from environment variables at the network layer.
|
|
|
|
Source code path:
|
|
- `gateway/platforms/telegram_network.py` → `_resolve_proxy_url()` → `resolve_proxy_url("TELEGRAM_PROXY", ...)` from `gateway/platforms/base.py`
|
|
- `gateway/platforms/telegram.py` line 2068 → same `resolve_proxy_url()` call
|
|
|
|
`resolve_proxy_url()` checks (in order):
|
|
1. `TELEGRAM_PROXY` env var (Telegram-specific, highest priority)
|
|
2. `HTTPS_PROXY` / `HTTP_PROXY` / `ALL_PROXY` env vars (and lowercase variants)
|
|
3. macOS system proxy auto-detection
|
|
|
|
**Key: `telegram.proxy_url` in config.yaml IS bridged to `TELEGRAM_PROXY` env var** by `load_gateway_config()` at startup. So both config.yaml and direct env vars work. However, if `load_gateway_config()` fails to run (e.g. gateway started manually without the config bridge), only direct env vars work.
|
|
|
|
**Dual defense recommended**: set BOTH `telegram.proxy_url` in config.yaml AND `HTTPS_PROXY` in the systemd service file. This ensures proxy works whether the config bridge runs or not.
|
|
|
|
## Quick Diagnosis: Read Gateway Logs Directly
|
|
|
|
When `terminal()` is blocked (consent mechanism, security scanner, etc.), diagnose via log files:
|
|
|
|
```python
|
|
# 1. Find log files
|
|
search_files(pattern="*.log", path="~/.hermes/logs", target="files")
|
|
|
|
# 2. Read recent gateway log tail
|
|
read_file(path="~/.hermes/logs/gateway.log", offset=-100) # last 100 lines
|
|
|
|
# 3. Search for Telegram errors
|
|
search_files(pattern="telegram.*failed|Connect attempt|All connection",
|
|
path="~/.hermes/logs/gateway.log", target="content")
|
|
```
|
|
|
|
**Key log patterns to look for:**
|
|
|
|
| Log Pattern | Meaning |
|
|
|---|---|
|
|
| `Proxy detected; passing explicitly to HTTPXRequest: http://127.0.0.1:7890` | Proxy URL is configured in Hermes ✓ |
|
|
| `Connect attempt N/8 failed: httpx.ConnectError: All connection attempts failed` | Proxy port unreachable (proxy down or wrong port) |
|
|
| `connect timed out after 30s` | All retry attempts exhausted, will retry in N seconds |
|
|
| `Reconnect telegram error: ... next retry in 300s` | Exponential backoff — retries increase: 60→120→240→300s |
|
|
| `Primary api.telegram.org connection failed (); trying fallback IPs` | DNS resolution worked but TCP connection failed |
|
|
| `DoH discovery yielded no usable IPs` | DNS-over-HTTPS failed, using hardcoded fallback IPs |
|
|
|
|
**Common failure: proxy itself is DOWN** (simplest case):
|
|
- Log shows: `Proxy detected` + `All connection attempts failed` on every attempt
|
|
- This means Hermes knows about the proxy (config bridge works), but the proxy port is not responding
|
|
- Fix: restart mihomo (`systemctl --user restart mihomo` or `bash ~/clash/startup.sh restart mihomo`)
|
|
|
|
**This is different from**: proxy running but Hermes not routing through it (see "Common Failure Pattern" below).
|
|
|
|
## Diagnostic Steps (in order)
|
|
|
|
### 1. Proxy process alive?
|
|
```bash
|
|
ss -tlnp | grep 7890 # mihomo should be LISTEN
|
|
# Expected: users:(("mihomo",pid=NNNN,fd=3))
|
|
```
|
|
|
|
### 2. Proxy actually works? (curl test)
|
|
```bash
|
|
curl -x http://127.0.0.1:7890 -I https://www.google.com --connect-timeout 5
|
|
curl -x http://127.0.0.1:7890 -I https://api.telegram.org --connect-timeout 5
|
|
```
|
|
Both should return HTTP 200/302, not timeout.
|
|
|
|
### 3. Gateway process has proxy env vars?
|
|
```bash
|
|
PID=$(pgrep -f "hermes_cli.main gateway" | head -1)
|
|
tr '\0' '\n' < /proc/$PID/environ | grep -i proxy
|
|
```
|
|
If empty — the gateway process has NO proxy env vars and relies solely on the config bridge (`telegram.proxy_url` → `TELEGRAM_PROXY`). If the bridge fails, Telegram connects DIRECT.
|
|
|
|
### 4. Check systemd service file
|
|
```bash
|
|
grep -i proxy ~/.config/systemd/user/hermes-gateway.service
|
|
```
|
|
If no `HTTPS_PROXY` / `HTTP_PROXY` lines — the service file needs updating for dual defense.
|
|
|
|
### 5. Check config.yaml bridge
|
|
```bash
|
|
grep proxy_url ~/.hermes/config.yaml
|
|
```
|
|
Should show `proxy_url: http://127.0.0.1:7890` under `telegram:`.
|
|
|
|
### 6. Gateway status + logs
|
|
```bash
|
|
hermes gateway status
|
|
journalctl --user -u hermes-gateway -n 50 | grep -i telegram
|
|
```
|
|
Look for: "Proxy detected" (good) or "connection failed" / "Timed out" (bad).
|
|
|
|
### 7. Run hermes doctor
|
|
```bash
|
|
hermes doctor
|
|
```
|
|
Shows API connectivity, missing configs, auth issues.
|
|
|
|
## Common Failure Pattern
|
|
|
|
**Symptom**: Proxy is running, curl tests pass, but gateway shows:
|
|
```
|
|
[Telegram] Primary api.telegram.org connection failed
|
|
[Telegram] Fallback IP 149.154.167.220 failed
|
|
[Telegram] Connect attempt N/8 failed: Timed out
|
|
```
|
|
|
|
**Root cause**: Gateway systemd service file has no proxy environment variables AND the config bridge failed (or `telegram.proxy_url` not set). The Telegram adapter falls back to direct connection, which fails behind GFW.
|
|
|
|
**Fix** (dual defense — set both):
|
|
```bash
|
|
# 1. Set config bridge
|
|
hermes config set telegram.proxy_url http://127.0.0.1:7890
|
|
|
|
# 2. Add proxy env vars to systemd service
|
|
python3 -c "
|
|
import pathlib
|
|
p = pathlib.Path.home() / '.config/systemd/user/hermes-gateway.service'
|
|
lines = p.read_text().splitlines()
|
|
lines = [l for l in lines if 'HTTPS_PROXY' not in l and 'HTTP_PROXY' not in l]
|
|
out = []
|
|
for l in lines:
|
|
out.append(l)
|
|
if 'HERMES_HOME' in l and l.strip().startswith('Environment'):
|
|
out.append('Environment=\"HTTPS_PROXY=http://127.0.0.1:7890\"')
|
|
out.append('Environment=\"HTTP_PROXY=http://127.0.0.1:7890\"')
|
|
p.write_text('\n'.join(out) + '\n')
|
|
"
|
|
systemctl --user daemon-reload
|
|
hermes gateway restart
|
|
```
|
|
|
|
**Quick fix**: `bash ~/clash/fix-proxy.sh --fix`
|
|
|
|
**Verification**:
|
|
```bash
|
|
PID=$(pgrep -f "hermes_cli.main gateway" | head -1)
|
|
tr '\0' '\n' < /proc/$PID/environ | grep -i proxy
|
|
# Expected: TELEGRAM_PROXY=http://127.0.0.1:7890 (from config bridge)
|
|
# HTTPS_PROXY=http://127.0.0.1:7890 (from systemd service)
|
|
```
|
|
|
|
## Network/Proxy Audit Checklist
|
|
|
|
When the user asks "check my network/proxy config" or "any redundant configs?", cover these dimensions:
|
|
|
|
1. **代理进程**: mihomo running? Port 7890 listening?
|
|
2. **代理连通性**: curl through proxy works? (Google, Telegram)
|
|
3. **Gateway 代理模式**: Both config.yaml `proxy_url` AND systemd `HTTPS_PROXY` set? (dual defense)
|
|
4. **旧服务残留**: Any old gateway services (e.g. `openclaw-gateway.service`) still in `~/.config/systemd/user/`? Disable with `systemctl --user disable --now <name>`
|
|
5. **重复启动脚本**: Both `startup.sh` and systemd managing the same service? Pick one — systemd preferred. The other is dead code.
|
|
6. **WireGuard 残留**: Check `/etc/wireguard/` for leftover `.conf` files. WireGuard can intercept ALL traffic if misconfigured.
|
|
7. **环境变量代理**: Check `~/.bashrc` for `HTTP_PROXY`/`HTTPS_PROXY` — needed for terminal sessions but NOT sufficient for systemd services (they don't source .bashrc).
|
|
8. **channel_prompts 重复**: Same prompt in slack/discord/telegram sections of config.yaml — only needed in platforms actually used.
|
|
|
|
## Quick Status Summary Template
|
|
When reporting proxy status to the user, cover these four dimensions:
|
|
1. **代理进程**: mihomo running? Port 7890 listening?
|
|
2. **代理连通性**: curl through proxy works? (Google, Telegram)
|
|
3. **Gateway 代理模式**: systemd service has proxy env vars? Config bridge set? Gateway process has them?
|
|
4. **网关状态**: Gateway running? Telegram connected? No timeout errors in logs?
|
|
|
|
- **Gateway log path**: `~/.hermes/logs/gateway.log`, NOT `~/.hermes/gateway.log`. Also check `~/.hermes/logs/errors.log` for historical errors. Use `search_files(pattern="*.log", path="~/.hermes/logs", target="files")` to discover all logs.
|
|
- **Telegram reconnect backoff**: When Telegram fails to connect, the gateway retries with exponential backoff: 60s → 120s → 240s → 300s (cap). After fixing the proxy, you may need to `hermes gateway restart` to reset the backoff instead of waiting for the next retry window.
|
|
- **QQBot also fails when proxy is down**: The QQBot adapter routes through the same proxy. If `127.0.0.1:7890` is down, both Telegram AND QQ will show connection failures. Check QQBot logs for `Failed to get QQ Bot access token: All connection attempts failed`.
|
|
|
|
## Quick-Fix Script
|
|
|
|
`~/clash/fix-proxy.sh` — interactive menu with 8 functions:
|
|
1. 📊 查看状态 (full status overview)
|
|
2. 🔧 一键诊断修复 (auto-diagnose and fix)
|
|
3. 🔄 重启 Mihomo
|
|
4. 📡 更新/更换订阅
|
|
5. 🔀 切换代理节点 (via Mihomo API)
|
|
6. 🌐 Gateway 代理/直连切换
|
|
7. 🔁 重启 Hermes Gateway
|
|
8. 📋 查看日志
|
|
|
|
Usage:
|
|
- Interactive: `bash ~/clash/fix-proxy.sh`
|
|
- One-click fix: `bash ~/clash/fix-proxy.sh --fix`
|