feat(tls-fingerprint): 新增 TLS 指纹 Profile 数据库管理及代码质量优化

新增功能:
- 新增 TLS 指纹 Profile CRUD 管理(Ent schema + 迁移 + Admin API + 前端管理界面)
- 支持账号绑定数据库中的自定义 TLS Profile,或随机选择(profile_id=-1)
- HTTPUpstream.DoWithTLS 接口从 bool 改为 *tlsfingerprint.Profile,支持按账号指定 Profile
- AccountUsageService 注入 TLSFingerprintProfileService,统一 usage 场景与网关的 Profile 解析逻辑

代码优化:
- 删除已被 TLSFingerprintProfileService 完全取代的 registry.go 死代码(418 行)
- 提取 3 个 dialer 的重复 TLS 握手逻辑为 performTLSHandshake() 共用函数
- 修复 GetTLSFingerprintProfileID 缺少 json.Number 处理的 bug
- gateway_service.Forward 中 ResolveTLSProfile 从重试循环内重复调用改为预解析局部变量
- 删除冗余的 buildClientHelloSpec() 单行 wrapper 和 int64(e.ID) 无效转换
- tls_fingerprint_profile_cache.go 日志从 log.Printf 改为 slog 结构化日志
- dialer_capture_test.go 添加 //go:build integration 标签,防止 CI 失败
- 去重 TestProfileExpectation 类型至共享 test_types_test.go
- 修复 9 个测试文件缺少 tlsfingerprint import 的编译错误
- 修复 error_policy_integration_test.go 中 handleError 回调签名被错误替换的问题
This commit is contained in:
shaw
2026-03-27 14:23:28 +08:00
parent ef5c8e6839
commit 1854050df3
70 changed files with 8095 additions and 1037 deletions

View File

@@ -2169,6 +2169,14 @@
/>
</button>
</div>
<!-- Profile selector -->
<div v-if="tlsFingerprintEnabled" class="mt-3">
<select v-model="tlsFingerprintProfileId" class="input">
<option :value="null">{{ t('admin.accounts.quotaControl.tlsFingerprint.defaultProfile') }}</option>
<option v-if="tlsFingerprintProfiles.length > 0" :value="-1">{{ t('admin.accounts.quotaControl.tlsFingerprint.randomProfile') }}</option>
<option v-for="p in tlsFingerprintProfiles" :key="p.id" :value="p.id">{{ p.name }}</option>
</select>
</div>
</div>
<!-- Session ID Masking -->
@@ -3082,6 +3090,8 @@ const umqModeOptions = computed(() => [
{ value: 'serialize', label: t('admin.accounts.quotaControl.rpmLimit.umqModeSerialize') },
])
const tlsFingerprintEnabled = ref(false)
const tlsFingerprintProfileId = ref<number | null>(null)
const tlsFingerprintProfiles = ref<{ id: number; name: string }[]>([])
const sessionIdMaskingEnabled = ref(false)
const cacheTTLOverrideEnabled = ref(false)
const cacheTTLOverrideTarget = ref<string>('5m')
@@ -3247,6 +3257,10 @@ watch(
() => props.show,
(newVal) => {
if (newVal) {
// Load TLS fingerprint profiles
adminAPI.tlsFingerprintProfiles.list()
.then(profiles => { tlsFingerprintProfiles.value = profiles.map(p => ({ id: p.id, name: p.name })) })
.catch(() => { tlsFingerprintProfiles.value = [] })
// Modal opened - fill related models
allowedModels.value = [...getModelsByPlatform(form.platform)]
// Antigravity: 默认使用映射模式并填充默认映射
@@ -3747,6 +3761,7 @@ const resetForm = () => {
rpmStickyBuffer.value = null
userMsgQueueMode.value = ''
tlsFingerprintEnabled.value = false
tlsFingerprintProfileId.value = null
sessionIdMaskingEnabled.value = false
cacheTTLOverrideEnabled.value = false
cacheTTLOverrideTarget.value = '5m'
@@ -4825,6 +4840,9 @@ const handleAnthropicExchange = async (authCode: string) => {
// Add TLS fingerprint settings
if (tlsFingerprintEnabled.value) {
extra.enable_tls_fingerprint = true
if (tlsFingerprintProfileId.value) {
extra.tls_fingerprint_profile_id = tlsFingerprintProfileId.value
}
}
// Add session ID masking settings
@@ -4940,6 +4958,9 @@ const handleCookieAuth = async (sessionKey: string) => {
// Add TLS fingerprint settings
if (tlsFingerprintEnabled.value) {
extra.enable_tls_fingerprint = true
if (tlsFingerprintProfileId.value) {
extra.tls_fingerprint_profile_id = tlsFingerprintProfileId.value
}
}
// Add session ID masking settings