Skip to content

fix(sub): apply host Allow Insecure to Hysteria2 subscription links#5866

Merged
MHSanaei merged 1 commit into
mainfrom
fix/issue-5865-hysteria2-host-allow-insecure
Jul 9, 2026
Merged

fix(sub): apply host Allow Insecure to Hysteria2 subscription links#5866
MHSanaei merged 1 commit into
mainfrom
fix/issue-5865-hysteria2-host-allow-insecure

Conversation

@MHSanaei

@MHSanaei MHSanaei commented Jul 8, 2026

Copy link
Copy Markdown
Owner

What changed

A subscription host's Allow Insecure setting (Host.AllowInsecure in internal/database/model/model.go) was never applied to Hysteria/Hysteria2 links, even though the same setting works for VLESS/VMess/Trojan/Shadowsocks.

  • internal/sub/service.goapplyExternalProxyHysteriaParams (used by genHysteriaLink's per-external-proxy/per-host loop) only carried over the cert pin. It now also emits insecure=1 in the raw hysteria2:// link when the host/external-proxy entry has allowInsecure: true.
  • internal/sub/clash_service.gobuildHysteriaProxy builds the Clash/Mihomo proxy entry by re-reading the TLS settings straight from inbound.StreamSettings, ignoring the per-host ep override entirely (unlike every other protocol's Clash builder). It now also sets skip-cert-verify: true when the host/external-proxy entry has allowInsecure: true.

Why

For a Hysteria2 inbound fronted with a self-signed certificate, an admin can only express "skip certificate verification" through a subscription Host (there is no such field on the inbound's own TLS settings). Both Hysteria link generators build one link per host by projecting the Host row onto an externalProxy-shaped map (hostToExternalProxyMap in internal/sub/host_sub.go, which already sets ep["allowInsecure"] = true), but neither Hysteria-specific renderer looked at that key, so the flag was silently dropped:

  • raw subscription: no insecure=1 query param.
  • Clash/Mihomo subscription: no skip-cert-verify: true.

This left Hysteria2 nodes behind a self-signed cert unusable from the generated subscription until the user manually edited the client and enabled insecure certificate trust.

Scope

Both changes are additive if blocks gated on ep["allowInsecure"]/ep's absence of that key, so behavior for hosts/external proxies without Allow Insecure set is unchanged (verified against the existing TestApplyExternalProxyHysteriaParams_* and TestChar_C6_HysteriaExternalProxy cases, none of which set that key).

Fixes #5865.

Host.AllowInsecure was only wired into the shared VLESS/VMess/Trojan/Shadowsocks
endpoint path (applyEndpointAllowInsecure). Hysteria/Hysteria2 builds its links
through its own applyExternalProxyHysteriaParams (raw hysteria2:// link) and
buildHysteriaProxy (Clash/Mihomo proxy), neither of which read the host's
allowInsecure flag, so a self-signed Hysteria2 host never got insecure=1 or
skip-cert-verify: true. Fixes #5865.
@MHSanaei MHSanaei merged commit f3e9905 into main Jul 9, 2026
34 checks passed
@MHSanaei MHSanaei deleted the fix/issue-5865-hysteria2-host-allow-insecure branch July 9, 2026 00:03
@github-actions github-actions Bot added the go Pull requests that update Go code label Jul 9, 2026
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Reviewed the diff against the surrounding subscription-rendering code (hostToExternalProxyMap, genHysteriaLink, buildProxy/getProxies, and the JSON-format equivalent) and it's correctly scoped and wired:

  • insecure=1 matches the query-param name the frontend's TS genHysteriaLink and Hysteria2's own URI scheme already use (frontend/src/lib/xray/inbound-link.ts), so raw-link clients will parse it as expected.
  • Both call sites are reachable end-to-end from hostEndpoints/injectExternalProxy, i.e. a real Host row with Allow Insecure on a Hysteria2 inbound now actually produces insecure=1 (raw) and skip-cert-verify: true (Clash).
  • Checked whether the JSON subscription format (internal/sub/json_service.go) needed the same fix: it doesn't — genHy reuses the stream already processed by the shared applyExternalProxyTLSToStream, which already writes allowInsecure into tlsSettings.settings for every protocol including Hysteria. Clash's buildHysteriaProxy needed its own fix specifically because it deliberately bypasses that shared pipeline (documented in its own comment) to avoid losing allowInsecure/salamander obfs fields that streamData/tlsData prune.
  • Confirmed the deliberate design choice that Hysteria external-proxy/host entries don't override SNI/fingerprint (only pin + now allowInsecure) is untouched and still locked in by the existing TestApplyExternalProxyHysteriaParams_PinIsHexNormalized case.

The one gap: neither change had a test asserting the new behavior itself (the existing tests only proved the old pin/SNI behavior was undisturbed). Added in 726fc3e7:

  • TestApplyExternalProxyHysteriaParams_AllowInsecureSetsInsecureParam / _NoAllowInsecureOmitsParam in internal/sub/service_test.go.
  • TestBuildHysteriaProxy_HostAllowInsecureSetsSkipCertVerify / _NoHostAllowInsecureOmitsSkipCertVerify in internal/sub/clash_service_test.go.

Nothing else needed changing — no new routes, DB fields, or i18n keys are involved, and I didn't find any correctness issues in the original two hunks.

This review was generated automatically; @MHSanaei may want to follow up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

go Pull requests that update Go code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Hysteria2 subscription ignores Allow Insecure setting

1 participant