feat(tls): surface pinnedPeerCertSha256 in panel, share links, and subs

Adds a panel-only `pinnedPeerCertSha256` field on TLS settings with a tags input and a random-hash generator. The hashes ride share links as `pcs` (v2rayN-compatible), Clash sub as `pin-sha256`, and JSON sub as `pinnedPeerCertSha256`, while remaining stripped from the run-config sent to xray-core.
This commit is contained in:
MHSanaei
2026-05-28 19:32:10 +02:00
parent c5b5606bf5
commit 3f0b7fbe97
23 changed files with 320 additions and 1 deletions
+33
View File
@@ -809,6 +809,9 @@ func applyShareTLSParams(stream map[string]any, params map[string]string) {
if fpValue, ok := searchKey(tlsSettings, "fingerprint"); ok {
params["fp"], _ = fpValue.(string)
}
if pins, ok := pinnedSha256List(tlsSettings); ok {
params["pcs"] = strings.Join(pins, ",")
}
}
}
@@ -831,9 +834,39 @@ func applyVmessTLSParams(stream map[string]any, obj map[string]any) {
if fpValue, ok := searchKey(tlsSettings, "fingerprint"); ok {
obj["fp"], _ = fpValue.(string)
}
if pins, ok := pinnedSha256List(tlsSettings); ok {
obj["pcs"] = strings.Join(pins, ",")
}
}
}
// pinnedSha256List extracts tlsSettings.settings.pinnedPeerCertSha256 as a
// []string. The field is panel-only (stripped before the run-config reaches
// xray-core via web/service/xray.go) but flows into share links so clients
// can pin the server's certificate hash.
func pinnedSha256List(tlsClientSettings any) ([]string, bool) {
raw, ok := searchKey(tlsClientSettings, "pinnedPeerCertSha256")
if !ok {
return nil, false
}
arr, ok := raw.([]any)
if !ok || len(arr) == 0 {
return nil, false
}
out := make([]string, 0, len(arr))
for _, v := range arr {
s, ok := v.(string)
if !ok || s == "" {
continue
}
out = append(out, s)
}
if len(out) == 0 {
return nil, false
}
return out, true
}
func applyShareRealityParams(stream map[string]any, params map[string]string) {
params["security"] = "reality"
realitySetting, _ := stream["realitySettings"].(map[string]any)