118 lines
4.9 KiB
Bash
Executable File
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.

#!/bin/bash
# test-mac.sh — 本机Mac指纹验证脚本
# 用途:验证 Node.js TLS 指纹、H2 连通性
# 运行方式bash test-mac.sh
set -euo pipefail
GREEN='\033[0;32m' RED='\033[0;31m' YELLOW='\033[1;33m' NC='\033[0m'
ok() { echo -e "${GREEN}$*${NC}"; }
fail() { echo -e "${RED}$*${NC}"; }
info() { echo -e "${YELLOW} $*${NC}"; }
echo "══════════════════════════════════════"
echo " MAC 本地指纹验证"
echo "══════════════════════════════════════"
# ── 1. Node.js 版本 ────────────────────────────────────────
echo ""
echo "【1】Node.js 版本"
NODE_VER=$(node --version 2>/dev/null || echo "未安装")
echo " 本机 Node: $NODE_VER"
if [[ "$NODE_VER" == v22* ]]; then
ok "Node.js v22.x — 与 Claude CLI 内置版本匹配"
else
fail "Node.js 版本不是 v22.x当前: $NODE_VERJA4 指纹可能不一致"
info "安装 v22: nvm install 22 && nvm use 22"
fi
# ── 2. Node.js JA4 TLS 指纹 ────────────────────────────────
echo ""
echo "【2】Node.js TLS JA4 指纹(服务器实际产生的指纹)"
JA4=$(node -e "
const https = require('https');
https.get('https://tls.peet.ws/api/all', res => {
let d=''; res.on('data',c=>d+=c);
res.on('end',()=>{
try { console.log(JSON.parse(d).tls.ja4); } catch(e){ console.log('parse_error'); }
});
}).on('error', e => console.log('error:'+e.message));
" 2>/dev/null)
echo " JA4: $JA4"
if [[ "$JA4" == t13* ]]; then
ok "TLS 1.3,看起来是合法的 Node.js 指纹"
else
fail "JA4 获取失败或格式异常: $JA4"
fi
# ── 3. H2 连接 api.anthropic.com ───────────────────────────
echo ""
echo "【3】HTTP/2 连通性Anthropic"
H2_RESULT=$(node -e "
const http2 = require('http2');
const s = http2.connect('https://api.anthropic.com', {}, () => {
console.log('ok:' + s.socket.alpnProtocol);
s.close();
});
s.on('error', e => { console.log('err:'+e.message); process.exit(0); });
setTimeout(()=>{ console.log('timeout'); process.exit(0); }, 5000);
" 2>/dev/null)
if [[ "$H2_RESULT" == ok:h2 ]]; then
ok "Anthropic H2 连接成功alpnProtocol: h2"
else
fail "H2 连接失败: $H2_RESULT"
fi
# ── 4. H2 连接 googleapis.com ──────────────────────────────
echo ""
echo "【4】HTTP/2 连通性Google / Gemini"
H2G=$(node -e "
const http2 = require('http2');
const s = http2.connect('https://generativelanguage.googleapis.com', {}, () => {
console.log('ok:' + s.socket.alpnProtocol);
s.close();
});
s.on('error', e => { console.log('err:'+e.message); process.exit(0); });
setTimeout(()=>{ console.log('timeout'); process.exit(0); }, 5000);
" 2>/dev/null)
if [[ "$H2G" == ok:h2 ]]; then
ok "Google API H2 连接成功"
else
fail "Google API H2 连接失败: $H2G"
fi
# ── 5. 本地 proxy 健康检查(如果本地起了) ─────────────────
echo ""
echo "【5】本地 node-tls-proxy 健康(端口 3456"
PROXY_PORT="${PROXY_PORT:-3456}"
if curl -sf "http://127.0.0.1:${PROXY_PORT}/__health" -o /tmp/proxy_health.json 2>/dev/null; then
SESSIONS=$(python3 -c "import json,sys; d=json.load(open('/tmp/proxy_health.json')); print(d.get('sessions',0))" 2>/dev/null || echo "?")
H2HOSTS=$(python3 -c "import json,sys; d=json.load(open('/tmp/proxy_health.json')); print(','.join(d.get('h2Hosts',[])))" 2>/dev/null || echo "?")
ok "Proxy 运行中 | sessions=$SESSIONS | h2Hosts=$H2HOSTS"
else
info "本地未运行 node-tls-proxy端口 $PROXY_PORT),跳过"
fi
# ── 6. Jitter 延迟分布(如果 proxy 运行中)────────────────
echo ""
echo "【6】Jitter 延迟测试5次请求通过本地 proxy"
if curl -sf "http://127.0.0.1:${PROXY_PORT:-3456}/__health" -o /dev/null 2>/dev/null; then
for i in {1..5}; do
START=$(date +%s%3N)
curl -sf -X POST "http://127.0.0.1:${PROXY_PORT:-3456}/v1/messages" \
-H "x-forwarded-host: api.anthropic.com" \
-H "content-type: application/json" \
-d '{"model":"claude-opus-4-5","max_tokens":1}' -o /dev/null 2>/dev/null || true
ELAPSED=$(($(date +%s%3N) - START))
echo " 请求 $i: ${ELAPSED}ms"
done
ok "延迟应在 80-1200ms 之间,非均匀分布"
else
info "本地未运行 proxy跳过 Jitter 测试"
fi
echo ""
echo "══════════════════════════════════════"
echo " Mac 验证完成"
echo " 关键指纹: $JA4"
echo "══════════════════════════════════════"