diff --git a/internal/sub/service.go b/internal/sub/service.go index 6bc436601..e5c777b92 100644 --- a/internal/sub/service.go +++ b/internal/sub/service.go @@ -1025,11 +1025,10 @@ func (s *SubService) genHysteriaLink(inbound *model.Inbound, email string) strin } } - // salamander obfs (Hysteria2). The panel-side link generator already - // emits these; keep the subscription output in sync so a client has - // the obfs password to match the server. + // salamander obfs (Hysteria2). Emit only the standard URI fields; + // the non-standard fm= finalmask dump breaks mihomo and other + // Hysteria2 clients that reject unknown query params. if finalmask, ok := stream["finalmask"].(map[string]any); ok { - applyFinalMaskParams(finalmask, params) if udpMasks, ok := finalmask["udp"].([]any); ok { for _, m := range udpMasks { mask, _ := m.(map[string]any) diff --git a/internal/sub/service_test.go b/internal/sub/service_test.go index 1b8d926c7..32f9ebe87 100644 --- a/internal/sub/service_test.go +++ b/internal/sub/service_test.go @@ -1110,3 +1110,32 @@ func TestHysteriaHopPorts(t *testing.T) { }) } } + +func TestGenHysteriaLinkOmitsFinalMaskQueryParam(t *testing.T) { + stream := `{ + "security":"tls", + "tlsSettings":{"serverName":"hy.sni","alpn":["h3"],"settings":{"fingerprint":"chrome"}}, + "finalmask":{"udp":[{"type":"salamander","settings":{"password":"obfs-secret"}}]} + }` + in := &model.Inbound{ + Listen: "203.0.113.1", + Port: 443, + Protocol: model.Hysteria, + Remark: "hy2", + Settings: `{"version":2,"clients":[{"auth":"hyauth","email":"user"}]}`, + StreamSettings: stream, + } + got := (&SubService{}).genHysteriaLink(in, "user") + if got == "" { + t.Fatal("expected hysteria2 link") + } + if strings.Contains(got, "fm=") { + t.Fatalf("hysteria2 subscription URI must not include non-standard fm param: %s", got) + } + if !strings.Contains(got, "obfs=salamander") { + t.Fatalf("missing standard obfs=salamander: %s", got) + } + if !strings.Contains(got, "obfs-password=obfs-secret") { + t.Fatalf("missing standard obfs-password: %s", got) + } +}