- AntigravityGatewayService 嵌入心跳,构造时自动启动 - Forward() 方法中注册心跳(首次 API 调用触发,后续更新 token) - 新建 gateway_errors.go: WriteClaudeErrorResponse/WriteGoogleErrorResponse 共享实现 - antigravity writeGoogleError 去掉手写映射,统一用 googleapi.HTTPStatusToGoogleStatus() - gemini writeClaudeError/writeGoogleError 委托到共享实现 - 新增 docs/antigravity-fingerprint-diagnostic.md 诊断手册
8.9 KiB
8.9 KiB
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 侧(服务器):
# 开启 debug 日志,抓取发往 googleapis 的请求头
docker logs sub2api 2>&1 | grep -E "googleapis|antigravity" | tail -50
真实 Antigravity 侧(装有 IDE 的电脑):
# 方法 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 服务器上抓:
# 抓 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 机器上抓:
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 侧:
# 统计某账号的请求频率
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 侧:
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 更新后,执行以下检查:
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 天 |