Skip to content

feat(services): add sing-box supervisor installer and tproxy integration - #12962

Open
rqzbeh wants to merge 8 commits into
cheaper-inference:release/v3.8.53from
rqzbeh:feat/v3.8.51-singbox-sidecar
Open

rqzbeh wants to merge 8 commits into
cheaper-inference:release/v3.8.53from
rqzbeh:feat/v3.8.51-singbox-sidecar

Conversation

@rqzbeh

@rqzbeh rqzbeh commented Sep 7, 2026 •

Copy link
Copy Markdown
Contributor

Summary

This PR adds support for sing-box as an embedded supervised service under ServiceSupervisor (src/lib/services/installers/singbox.ts) and integrates it into the src/mitm/tproxy/ network setup pipeline targeting release/v3.8.51.

  • Embedded Supervisor Adapter: src/lib/services/installers/singbox.ts installs, configures, and manages sing-box on loopback port 20140.
  • TPROXY Integration: src/mitm/tproxy/setup.ts provides ensureSingboxTproxy() for dynamic transparent proxying without requiring native C compilation / node-gyp build steps.
  • Service Registration: Registered in src/lib/services/bootstrap.ts under SERVICES[].
  • Unit Tests: Added tests/unit/services/installers/singbox.test.ts verifying lifecycle, config generation, and spawn argument formatting (100% passing).

⚠️ base-red inherited: #13866

@diegosouzapw

Copy link
Copy Markdown
Collaborator

Same structural issue as your llmlingua PR (#12967): SINGBOX_PORT is declared twice in
bootstrap.ts, which won't compile. More importantly, install() doesn't fetch the real
sing-box binary — it writes #!/bin/sh\necho 'sing-box mock binary' as the "binary", and
resolveSpawnArgs runs that mock. Since the mock script exits immediately instead of opening
the TPROXY listener, ensureSingboxTproxy() silently fails
(supervisor.start().catch(() => false)) and the feature never actually intercepts anything —
with no visible error to the operator. Could you wire this to a real sing-box release download
(with a pinned version + checksum), and surface a clear error/log when the supervisor fails to
start instead of swallowing it? Also worth a clean rebase to drop the ~15 duplicated
security/CI commits shared with #12967 and #12953 that have since diverged from the release
tip.

@diegosouzapw diegosouzapw added the protected-surface Touches an agent-instruction surface (AGENTS/CLAUDE/llm.txt/SKILL.md) — per-PR operator OK to merge label Sep 15, 2026
diegosouzapw added a commit to Bl0ck154/OmniRoute that referenced this pull request Sep 16, 2026
…ken)

Renamed 180_api_key_preferred_connections.sql to 184_api_key_preferred_connections.sql: the
release tip landed 180_memory_fts_au_conditional_memory_id.sql after this PR's previous
renumbering pass. Slot 184 is the owner-assigned number for this PR among the 7 PRs
that collided on the 180 slot (cheaper-inference#13610=181, cheaper-inference#12962=182, cheaper-inference#12967=183, cheaper-inference#13102=184,
cheaper-inference#13222=185, cheaper-inference#13373=186, cheaper-inference#13554=187).

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
diegosouzapw added a commit to ahmedhosnypro/OmniRoute that referenced this pull request Sep 16, 2026
Six open PRs claimed migration slot 180 after cheaper-inference#13331 landed it on the
release tip; the owner assigned cheaper-inference#13373 slot 186 in the sequence
(cheaper-inference#13610=181, cheaper-inference#12962=182, cheaper-inference#12967=183, cheaper-inference#13102=184, cheaper-inference#13222=185,
cheaper-inference#13373=186, cheaper-inference#13554=187).

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
@rqzbeh
rqzbeh force-pushed the feat/v3.8.51-singbox-sidecar branch from 0111ee5 to 367fb1e Compare September 18, 2026 23:10
@rqzbeh

rqzbeh commented Sep 18, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto upstream/release/v3.8.51 as a single isolated commit, dropping all diverged commits from main.

Changes implemented:

  • Real binary download & checksum verification: src/lib/services/installers/singbox.ts downloads the pinned release 1.14.1 directly from SagerNet/sing-box GitHub releases, verifies platform-specific SHA256 checksums (SINGBOX_CHECKSUMS covering linux-amd64, linux-arm64, darwin-amd64, darwin-arm64, and windows-amd64), and extracts the binary. Any unpinned version is rejected.
  • Supervisor error visibility: ensureSingboxTproxy() in src/mitm/tproxy/setup.ts logs error diagnostics if the supervisor is unregistered, if start() rejects, or if the process fails to transition to running, eliminating the silent .catch(() => false) failure mode.
  • Deduplicated bootstrap configuration: Removed duplicate SINGBOX_PORT in src/lib/services/bootstrap.ts, retaining a single declaration at port 20140 alongside existing services.
  • Migration & documentation: Seeded using migration slot 182_singbox_service_seed.sql, added the 8 /api/services/singbox/* management endpoints to docs/openapi.yaml, documented the sidecar in docs/frameworks/EMBEDDED-SERVICES.md and docs/reference/ENVIRONMENT.md, and added SINGBOX_PORT to .env.example.
  • Test coverage: Updated unit tests in tests/unit/services/installers/singbox.test.ts to verify archive extraction, checksum validation, and download failure handling.

…staller and lifecycle management

- Replace mock binary in sing-box installer with real release download
  from SagerNet/sing-box pinned to version 1.14.1 with verified SHA256 checksums
  across linux/darwin/windows platforms.
- Update ensureSingboxTproxy() in src/mitm/tproxy/setup.ts to log descriptive
  errors instead of swallowing start failures.
- Wire sing-box into src/lib/services/bootstrap.ts without duplicate SINGBOX_PORT
  declarations, preserving all existing embedded services.
- Seed version_manager row using collision-free migration slot 182.
- Implement 8 API management routes under /api/services/singbox/* and
  SingboxServiceTab in dashboard.
- Update OpenAPI schema, embedded services framework documentation, .env.example,
  and environment reference.
- Add unit tests for download and checksum verification and end-to-end lifecycle test.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
@rqzbeh
rqzbeh force-pushed the feat/v3.8.51-singbox-sidecar branch from 367fb1e to d8e2a9a Compare September 19, 2026 12:51
@diegosouzapw diegosouzapw changed the title feat(services): add sing-box supervisor installer and tproxy integration [defer] feat(services): add sing-box supervisor installer and tproxy integration Sep 25, 2026
@diegosouzapw diegosouzapw added the deferred-v3.8.52 Grande demais / suspeito para o lote atual; precisa de sessão dedicada no ciclo v3.8.52 label Sep 25, 2026
@diegosouzapw
diegosouzapw changed the base branch from release/v3.8.51 to release/v3.8.52 September 29, 2026 11:27
@diegosouzapw

Copy link
Copy Markdown
Collaborator

Re-homed to release/v3.8.52: v3.8.51 entered its release freeze, so the branch now belongs to the release captain and development continues on the next cycle. Nothing is wrong with this PR — it just needed a live base. No action needed from you; CI will re-run against the new base.

@diegosouzapw diegosouzapw removed the deferred-v3.8.52 Grande demais / suspeito para o lote atual; precisa de sessão dedicada no ciclo v3.8.52 label Oct 1, 2026
@diegosouzapw diegosouzapw changed the title [defer] feat(services): add sing-box supervisor installer and tproxy integration feat(services): add sing-box supervisor installer and tproxy integration Oct 1, 2026
rqzbeh and others added 2 commits October 7, 2026 23:18
… native TPROXY listener port

- renumber 182_singbox_service_seed.sql to 203 (182 exists on release/v3.8.52)
- sing-box listens on its own port (never cfg.onPort) and every outbound carries
  routing_mark = bypassMark, the mark the mangle OUTPUT rule excludes; without a
  bypassMark sing-box is not started
- ensureSingboxTproxy takes the TproxyConfig and keeps config-write errors inside its
  never-throws contract; drop the dead _targetHttpPort parameter
- tests: stubbed-downloader install contract (official URL, checksum mismatch, extraction
  path), TPROXY coexistence (generated JSON, iptables rule text, real socket binds),
  local-only classification of every /api/services/singbox/* route

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
@diegosouzapw

Copy link
Copy Markdown
Collaborator

Hi @rqzbeh — closing this pull request to clear the open queue. The branch feat/v3.8.51-singbox-sidecar is kept, so the commits stay. Comment here if it should be reopened.

@diegosouzapw

Copy link
Copy Markdown
Collaborator

Hi @rqzbeh — reopening this pull request. The close was a mistake, and it is back in the merge queue. The branch feat/v3.8.51-singbox-sidecar was kept.

@diegosouzapw diegosouzapw reopened this Oct 10, 2026
@diegosouzapw diegosouzapw added the deferred-v3.8.53 Feat PRs held for v3.8.53. Keep open. Do not merge into v3.8.52. label Oct 13, 2026
@diegosouzapw diegosouzapw changed the title feat(services): add sing-box supervisor installer and tproxy integration [defer] feat(services): add sing-box supervisor installer and tproxy integration Oct 13, 2026
@diegosouzapw
diegosouzapw changed the base branch from release/v3.8.52 to release/v3.8.53 October 19, 2026 13:37
@diegosouzapw

Copy link
Copy Markdown
Collaborator

Re-homed to release/v3.8.53: v3.8.52 entered its release freeze, so the branch now belongs to the release captain and development continues on the next cycle. Nothing is wrong with this PR — it just needed a live base. No action needed from you; CI will re-run against the new base.

@diegosouzapw diegosouzapw removed the deferred-v3.8.53 Feat PRs held for v3.8.53. Keep open. Do not merge into v3.8.52. label Oct 20, 2026
@diegosouzapw diegosouzapw changed the title [defer] feat(services): add sing-box supervisor installer and tproxy integration feat(services): add sing-box supervisor installer and tproxy integration Oct 20, 2026
rqzbeh and others added 5 commits October 28, 2026 21:07
…51-singbox-sidecar

Conflicts resolved hunk by hunk, keeping both the release's LLMLingua service and this PR's sing-box service: bootstrap.ts (import, port, SERVICES entry, spawn factory), services page.tsx (tab type, TABS entry, panels map on the kit Tabs component), EMBEDDED-SERVICES.md (both rows, eight services, LLMLingua 4.7 / sing-box 4.8 / reverse proxy 4.9), openapi.yaml (both path blocks) and ENVIRONMENT.md (release table plus the SINGBOX_PORT row).

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
…the status handler

203 is taken on release/v3.8.53 by 203_memory_fts_content_rowid.sql; 217 is the next free slot. The singbox status GET carried every fallback in one function (cyclomatic 34, ceiling 15), so it is split into runtime/merged/version/settings helpers with the same JSON body, pinned by a new route contract test.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
… with release 217)

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

This branch has not been deployed

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

Labels

protected-surface Touches an agent-instruction surface (AGENTS/CLAUDE/llm.txt/SKILL.md) — per-PR operator OK to merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants