feat(singbox): bump to v1.13.9 + fix VLESS xtls-rprx-vision flow for injected users#41
Open
abpestov-cpu wants to merge 3 commits into
Open
feat(singbox): bump to v1.13.9 + fix VLESS xtls-rprx-vision flow for injected users#41abpestov-cpu wants to merge 3 commits into
abpestov-cpu wants to merge 3 commits into
Conversation
sing-box strictly validates that VLESS user flow matches inbound flow (sagernet/sing-vmess vless/service.go:68-69). When an inbound advertises "flow: xtls-rprx-vision" but the VLESSUser entry is injected without it, the handshake fails with "flow mismatch". Previously, marznode's sing-box backend never set flow on users. This meant REALITY+Vision inbounds were unusable via marznode — only the xray backend was fixed (PR marzneshin#30). This patch mirrors that behavior: - In _resolve_inbounds(): detect VLESS+REALITY over raw TCP and set the inbound's flow to "xtls-rprx-vision" (mirroring xray _config.py). - In append_user(): when the resolved inbound carries a flow, pass it as kwarg to the account constructor so sing-box sees the flow on the injected VLESSUser. Also: add sing-box config pre-check in _runner.start() — fail fast with a clear error instead of a silent crash-loop on invalid configs. Overlay Dockerfile (Dockerfile.patch) provided for deploying patched files on top of dawsh/marznode:latest — upstream Dockerfile pulls jklolixxs/sing-box:latest which is no longer publicly available. Refs: marzneshin#29 (report), marzneshin#30 (xray fix) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The old overlay layered dawsh/marznode:latest (sing-box 1.11.3) with
patched Python only. 1.11.3 is incompatible with recent Xray-core
REALITY clients — they get "[EOF]" right after the TLS handshake and
the server log shows "REALITY: processed invalid connection". The fix
is to move to v1.13.9, where the TLS stack has been reworked.
The official ghcr.io/sagernet/sing-box:v1.13.9 image ships without
`with_v2ray_api` (needed for FetchUsersStats) and `with_grpc` (v2ray
gRPC transports), so we build our own from source — keeping full tag
parity with the base dawsh image, minus tags that 1.13.x absorbed:
- with_reality_server → merged into with_utls
- with_ech → migrated to Go stdlib
Build specifics learned the hard way:
- -checklinkname=0 is required: sing-box uses `//go:linkname` into
crypto/tls internals (`handlePostHandshakeMessage`) which Go 1.23+
rejects without the flag.
- -X internal/godebug.defaultGODEBUG=multipathtcp=0 matches upstream
release/LDFLAGS.
- GOTOOLCHAIN=local pins us to the image's Go (go.mod may request a
newer patch version).
Consumer-side effect: 1.13.x drops the legacy WireGuard `outbound`
format — it must be migrated to the new top-level `endpoints: [{ type:
wireguard, address, peers: [...] }]`. Our Router/marzneshin configs
have been updated in a parallel commit.
- drop redundant isinstance(inbound.config, dict) guard: models.Inbound declares `config: dict` via pydantic, so the type is enforced at parse time and the isinstance branch was dead. - fold the two nested ifs into a single walrus expression. - extend the comment on settings["flow"]="xtls-rprx-vision" to name the affected clients (xray-core, v2rayN, NekoBox) and the concrete rejection path (sagernet/sing-vmess "flow mismatch"), plus the precedent marznode#30 (fix(xray): consider flow when transport is raw). No functional change — just prep for an upstream PR.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Problem
Two distinct issues addressed by this branch:
1. VLESS
xtls-rprx-visionflow not propagated to injected userssing-box strictly validates that VLESS user
flowmatches inboundflow(sagernet/sing-vmessvless/service.go:68-69). When an inbound advertisesflow: xtls-rprx-visionbut marznode injects aVLESSUserentry without it, the handshake fails with "flow mismatch".Previously, marznode's sing-box backend never set
flowon users. This left REALITY+Vision inbounds unusable via the sing-box backend — only the xray backend was fixed (#30).This PR mirrors that behaviour for sing-box.
2. sing-box 1.11.3 (from
dawsh/marznode:latest) cannot serve modern Xray-core REALITY clientsThe old overlay base image ships sing-box 1.11.3, which is incompatible with recent Xray-core REALITY clients — they receive
[EOF]right after TLS handshake, and the server log showsREALITY: processed invalid connection. sing-box 1.13.x reworked the TLS stack and fixes this.The official
ghcr.io/sagernet/sing-box:v1.13.9image is built withoutwith_v2ray_api(needed forFetchUsersStats) andwith_grpc(v2ray gRPC transports), so we build from source keeping full tag parity withdawsh/marznode, minus tags that 1.13.x absorbed:with_reality_server→ merged intowith_utlswith_ech→ migrated to Go stdlibChanges
Code
_resolve_inbounds: detect VLESS+REALITY over raw TCP, set the inbound'sflowtoxtls-rprx-vision(mirrors xray_config.py).append_user: when the resolved inbound carries aflow, pass it as kwarg to the account constructor so sing-box sees it on the injectedVLESSUser._runner.start(): add sing-box config pre-check — fail fast with a clear error instead of silent crash-loop on invalid configs.Build / Dockerfile
Dockerfile.patch: builder compiles sing-box v1.13.9 from source with full tag set, stage-1 layers patched Python on top ofdawsh/marznode:latest.-checklinkname=0is required — sing-box uses//go:linknameintocrypto/tlsinternals (handlePostHandshakeMessage) which Go 1.23+ rejects by default.-X internal/godebug.defaultGODEBUG=multipathtcp=0matches upstreamrelease/LDFLAGS.GOTOOLCHAIN=localpins to the image's Go (go.mod may request a newer patch version).Consumer-side effect (BREAKING for 1.13.x)
sing-box 1.13.x drops the legacy WireGuard
outboundformat. It must be migrated to top-levelendpoints:Refs
Commits:
0573b82fix(sing-box): support VLESS xtls-rprx-vision flow for injected users65fc377feat(singbox): bump to v1.13.9, build from source with required tags1943032refactor(singbox): simplify VLESS flow injection before upstream PR