sub2api/docs/antigravity-fingerprint-diagnostic.md
win 2279bde564
Some checks failed
CI / test (push) Failing after 1m32s
CI / golangci-lint (push) Failing after 32s
Security Scan / backend-security (push) Failing after 32s
Security Scan / frontend-security (push) Failing after 1m32s
fix: 心跳接入启动 + 网关错误去重
- AntigravityGatewayService 嵌入心跳,构造时自动启动
- Forward() 方法中注册心跳(首次 API 调用触发,后续更新 token)
- 新建 gateway_errors.go: WriteClaudeErrorResponse/WriteGoogleErrorResponse 共享实现
- antigravity writeGoogleError 去掉手写映射,统一用 googleapi.HTTPStatusToGoogleStatus()
- gemini writeClaudeError/writeGoogleError 委托到共享实现
- 新增 docs/antigravity-fingerprint-diagnostic.md 诊断手册
2026-03-27 12:11:22 +08:00

258 lines
8.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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
# 方法 2mitmproxy 抓包(需信任证书)
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 是否一致
□ 有没有多余的 headersub2api 多发了)
□ 有没有缺少的 headersub2api 少发了)
```
### 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 天 |