- AntigravityGatewayService 嵌入心跳,构造时自动启动 - Forward() 方法中注册心跳(首次 API 调用触发,后续更新 token) - 新建 gateway_errors.go: WriteClaudeErrorResponse/WriteGoogleErrorResponse 共享实现 - antigravity writeGoogleError 去掉手写映射,统一用 googleapi.HTTPStatusToGoogleStatus() - gemini writeClaudeError/writeGoogleError 委托到共享实现 - 新增 docs/antigravity-fingerprint-diagnostic.md 诊断手册
258 lines
8.9 KiB
Markdown
258 lines
8.9 KiB
Markdown
# Antigravity 指纹诊断与封号排查手册
|
||
|
||
## 一、当前指纹基线(2026-03-27)
|
||
|
||
### 真实 Antigravity IDE
|
||
|
||
| 项目 | 值 | 来源 |
|
||
|------|-----|------|
|
||
| Extension 版本 | `0.2.0` | package.json |
|
||
| Go 版本 | `go1.27-20260305-RC01` | 二进制 strings |
|
||
| TLS 库 | BoringCrypto | 二进制编译标记 |
|
||
| gRPC | `grpc-go/1.81.0-dev` | 二进制 strings |
|
||
| gax | `gax-go/v2` | 二进制 strings |
|
||
| User-Agent | `antigravity/{ver} {os}/{arch}` | 二进制 `User-Agent: %s` |
|
||
| x-goog-api-client | `gl-go/{goVer} gax-go/v2 grpc-go/1.81.0-dev` | 二进制 strings |
|
||
| Client ID | `884354919052-...` (主) / `1071006060591-...` (备) | 二进制 strings |
|
||
| API 端点 | `daily-cloudcode-pa.googleapis.com` | Antigravity 运行日志 |
|
||
| 心跳间隔 | 每 5 分钟 | cloudcode.log |
|
||
| 心跳内容 | loadCodeAssist + fetchAvailableModels | cloudcode.log |
|
||
| Token 刷新 | 约每 1 小时 | auth.log |
|
||
| Redirect URI | `http://localhost:{port}/oauth-callback` | extension.js |
|
||
| ideType | `ANTIGRAVITY` | 二进制 strings |
|
||
|
||
### sub2api 模拟值
|
||
|
||
| 项目 | 值 | 匹配度 |
|
||
|------|-----|--------|
|
||
| Extension 版本 | `0.2.0` | ✅ |
|
||
| Go 版本 | `go1.26.1` | ⚠️ 小版本差异 |
|
||
| TLS 库 | BoringCrypto (`GOEXPERIMENT=boringcrypto`) | ✅ |
|
||
| gRPC | `grpc-go/1.81.0-dev` | ✅ |
|
||
| User-Agent | `antigravity/0.2.0 {runtime.GOOS}/{runtime.GOARCH}` | ✅ |
|
||
| x-goog-api-client | `gl-go/{runtime.Version()} gax-go/v2 grpc-go/1.81.0-dev` | ✅ |
|
||
| Client ID | `1071006060591-...` | ✅ 真实二进制中也有 |
|
||
| API 端点 | `daily-cloudcode-pa.googleapis.com` | ✅ |
|
||
| 心跳 | Go 后端 5 分钟定时 | ✅ |
|
||
| TLS 路径 | Go BoringCrypto → GOST proxy → googleapis | ✅ |
|
||
|
||
---
|
||
|
||
## 二、封号排查决策树
|
||
|
||
```
|
||
账号被封
|
||
│
|
||
├── 只封 1 个账号
|
||
│ └── 大概率账号本身问题(被举报/异常使用/违规内容)
|
||
│ → 换号,不需要改代码
|
||
│
|
||
├── 同一 IP 下多个账号同时封
|
||
│ └── IP 关联检测
|
||
│ → 检查该 GOST proxy IP 绑了几个账号
|
||
│ → 减少到 1 IP : 1-2 账号
|
||
│ → 换 IP
|
||
│
|
||
├── 所有账号陆续被封(不同 IP)
|
||
│ └── 指纹问题(TLS 或 HTTP headers)
|
||
│ → 执行「指纹对比流程」(见第三节)
|
||
│ → 检查 Antigravity IDE 是否有新版本
|
||
│
|
||
└── 用了一段时间后才封
|
||
└── 行为模式问题
|
||
→ 检查请求频率(是否远超正常 IDE 使用)
|
||
→ 检查心跳是否正常(有没有漏发)
|
||
→ 检查是否有异常的模型调用模式
|
||
```
|
||
|
||
---
|
||
|
||
## 三、指纹对比流程
|
||
|
||
### 3.1 HTTP Headers 对比
|
||
|
||
**sub2api 侧(服务器):**
|
||
|
||
```bash
|
||
# 开启 debug 日志,抓取发往 googleapis 的请求头
|
||
docker logs sub2api 2>&1 | grep -E "googleapis|antigravity" | tail -50
|
||
```
|
||
|
||
**真实 Antigravity 侧(装有 IDE 的电脑):**
|
||
|
||
```bash
|
||
# 方法 1:读 IDE 日志
|
||
LATEST=$(ls -t ~/Library/Application\ Support/Antigravity/logs/ | head -1)
|
||
cat ~/Library/Application\ Support/Antigravity/logs/$LATEST/cloudcode.log | tail -30
|
||
cat ~/Library/Application\ Support/Antigravity/logs/$LATEST/auth.log | tail -10
|
||
|
||
# 方法 2:mitmproxy 抓包(需信任证书)
|
||
mitmproxy --mode regular --listen-port 8888
|
||
# 设置 Antigravity 的 HTTP 代理为 127.0.0.1:8888
|
||
# 观察 daily-cloudcode-pa.googleapis.com 的请求头
|
||
```
|
||
|
||
**对比项:**
|
||
|
||
```
|
||
□ User-Agent 格式和值是否一致
|
||
□ x-goog-api-client 是否一致
|
||
□ Authorization 格式是否一致
|
||
□ Content-Type 是否一致
|
||
□ 有没有多余的 header(sub2api 多发了)
|
||
□ 有没有缺少的 header(sub2api 少发了)
|
||
```
|
||
|
||
### 3.2 TLS 指纹对比
|
||
|
||
**sub2api 服务器上抓:**
|
||
|
||
```bash
|
||
# 抓 TLS ClientHello 包
|
||
sudo tcpdump -i eth0 -w /tmp/sub2api_tls.pcap \
|
||
'dst port 443 and (dst host cloudcode-pa.googleapis.com or dst host daily-cloudcode-pa.googleapis.com)' \
|
||
-c 10
|
||
|
||
# 提取 JA3
|
||
python3 antigravity/capture/ja3_extract.py /tmp/sub2api_tls.pcap
|
||
```
|
||
|
||
**真实 Antigravity 机器上抓:**
|
||
|
||
```bash
|
||
sudo tcpdump -i en0 -w /tmp/real_tls.pcap \
|
||
'dst port 443 and (dst host cloudcode-pa.googleapis.com or dst host daily-cloudcode-pa.googleapis.com)' \
|
||
-c 10
|
||
|
||
python3 antigravity/capture/ja3_extract.py /tmp/real_tls.pcap
|
||
```
|
||
|
||
**对比项:**
|
||
|
||
```
|
||
□ JA3 hash 是否一致
|
||
□ TLS 版本是否一致(应该都是 TLS 1.3)
|
||
□ Cipher suite 列表和顺序是否一致
|
||
□ TLS extensions 是否一致
|
||
□ ALPN 协议列表是否一致(应该是 h2, http/1.1)
|
||
```
|
||
|
||
### 3.3 行为模式对比
|
||
|
||
**sub2api 侧:**
|
||
|
||
```bash
|
||
# 统计某账号的请求频率
|
||
docker logs sub2api 2>&1 | grep "account_id=73" | \
|
||
awk '{print $1}' | cut -d: -f1-2 | uniq -c | tail -20
|
||
|
||
# 检查心跳
|
||
docker logs sub2api 2>&1 | grep "heartbeat" | tail -20
|
||
```
|
||
|
||
**真实 Antigravity 侧:**
|
||
|
||
```bash
|
||
LATEST=$(ls -t ~/Library/Application\ Support/Antigravity/logs/ | head -1)
|
||
|
||
# 心跳间隔(应该 ~5 分钟)
|
||
grep "loadCodeAssist" ~/Library/Application\ Support/Antigravity/logs/$LATEST/cloudcode.log | \
|
||
awk '{print $1, $2}' | head -20
|
||
|
||
# Token 刷新间隔(应该 ~1 小时)
|
||
grep "handleAuthRefresh" ~/Library/Application\ Support/Antigravity/logs/$LATEST/auth.log | \
|
||
awk '{print $1, $2}'
|
||
```
|
||
|
||
**对比项:**
|
||
|
||
```
|
||
□ 心跳间隔是否 ~5 分钟
|
||
□ 每次心跳是否发 loadCodeAssist + fetchAvailableModels 两个请求
|
||
□ 两个请求间隔是否 ~500ms
|
||
□ Token 刷新间隔是否 ~1 小时
|
||
□ 请求频率是否在正常 IDE 使用范围内
|
||
```
|
||
|
||
---
|
||
|
||
## 四、Antigravity IDE 版本更新检查
|
||
|
||
当 Antigravity IDE 更新后,执行以下检查:
|
||
|
||
```bash
|
||
BINARY="/Applications/Antigravity.app/Contents/Resources/app/extensions/antigravity/bin/language_server_macos_arm"
|
||
PKG="/Applications/Antigravity.app/Contents/Resources/app/extensions/antigravity/package.json"
|
||
|
||
echo "=== 1. Extension 版本 ==="
|
||
python3 -c "import json; d=json.load(open('$PKG')); print(d['version'])"
|
||
|
||
echo "=== 2. Go 版本 ==="
|
||
strings "$BINARY" | grep "^go1\." | head -1
|
||
|
||
echo "=== 3. gRPC 版本 ==="
|
||
strings "$BINARY" | grep -oE "grpc-go/[^ ]+" | head -1
|
||
|
||
echo "=== 4. Client ID ==="
|
||
strings "$BINARY" | grep -oE "[0-9]+-[a-z0-9]+\.apps\.googleusercontent\.com" | sort -u
|
||
|
||
echo "=== 5. OAuth Scopes ==="
|
||
strings "$BINARY" | grep -oE "googleapis.com/auth/[a-z._-]+" | sort -u
|
||
|
||
echo "=== 6. API 端点确认 ==="
|
||
LATEST=$(ls -t ~/Library/Application\ Support/Antigravity/logs/ | head -1)
|
||
grep "URL:" ~/Library/Application\ Support/Antigravity/logs/$LATEST/window*/exthost/google.antigravity/Antigravity.log | head -5
|
||
```
|
||
|
||
**如果有变更,需要更新的文件:**
|
||
|
||
| 变更项 | 更新文件 |
|
||
|--------|----------|
|
||
| Extension 版本 | `backend/internal/pkg/antigravity/oauth.go` → `defaultUserAgentVersion` |
|
||
| gRPC 版本 | `backend/internal/pkg/antigravity/client.go` → `GetGoogAPIClient()` |
|
||
| Client ID | `backend/internal/pkg/antigravity/oauth.go` → `ClientID` |
|
||
| Scopes | `backend/internal/pkg/antigravity/oauth.go` → `Scopes` |
|
||
| API 端点 | `backend/internal/pkg/antigravity/oauth.go` → `antigravityDailyBaseURL` |
|
||
|
||
---
|
||
|
||
## 五、关键文件定位
|
||
|
||
```
|
||
指纹配置
|
||
├── backend/internal/pkg/antigravity/oauth.go # Client ID, URL, UA 版本, Scopes, Redirect URI
|
||
├── backend/internal/pkg/antigravity/client.go # x-goog-api-client, 请求头组装, DoRaw
|
||
├── backend/internal/pkg/geminicli/constants.go # GeminiCLI UA
|
||
└── backend/internal/service/gemini_messages_compat_service.go # AI Studio / Code Assist 请求头
|
||
|
||
行为模拟
|
||
├── backend/internal/service/antigravity_heartbeat.go # 5 分钟心跳
|
||
└── antigravity/node-tls-proxy/proxy.js # Claude 遥测模拟(非 Antigravity)
|
||
|
||
网络路由
|
||
├── backend/internal/repository/http_upstream.go # googleapis → Go 原生, anthropic → Node.js proxy
|
||
└── Dockerfile / backend/Makefile # BoringCrypto 编译
|
||
|
||
真实 IDE 日志(对比用)
|
||
├── ~/Library/Application Support/Antigravity/logs/{timestamp}/cloudcode.log # API 调用记录
|
||
├── ~/Library/Application Support/Antigravity/logs/{timestamp}/auth.log # Token 刷新
|
||
└── ~/Library/Application Support/Antigravity/logs/{timestamp}/window*/exthost/google.antigravity/Antigravity.log # 语言服务器日志
|
||
|
||
抓包工具
|
||
├── antigravity/capture/ja3_extract.py # JA3 指纹提取
|
||
├── antigravity/capture/capture_traffic.py # mitmproxy HTTP 抓包
|
||
└── antigravity/capture/capture_tls.sh # TLS 抓包脚本
|
||
```
|
||
|
||
---
|
||
|
||
## 六、预防措施
|
||
|
||
| # | 措施 | 说明 |
|
||
|---|------|------|
|
||
| 1 | 1 IP : 1-2 账号 | 同一 GOST proxy 最多绑 2 个 Antigravity 账号 |
|
||
| 2 | 监控 403 | 连续 403 立刻暂停账号,不继续请求 |
|
||
| 3 | 心跳随机化 | 5 分钟 ±30 秒随机偏移,避免精确整数间隔 |
|
||
| 4 | 定期对比 | 每次 IDE 更新后执行第四节检查 |
|
||
| 5 | 保留旧日志 | 封号前后的 docker logs 保存至少 7 天 |
|