github Leadaxe/singbox-launcher v1.2.3
release v1.2.3

latest releases: v1.2.5, v1.2.4
5 hours ago

Release v1.2.3

Downloads

macOS (Universal) - Supports both Apple Silicon and Intel

Option 1: Installation Script (Recommended)

Install with a single command (version v1.2.3):

curl -fsSL https://raw.githubusercontent.com/Leadaxe/singbox-launcher/develop/scripts/install-macos.sh | bash -s -- v1.2.3

The script will:

  • Download the release archive
  • Extract and install to /Applications/
  • Fix macOS quarantine attributes and permissions
  • Launch the application automatically

Option 2: Manual Installation

  1. Download: singbox-launcher-v1.2.3-macos.zip
  2. Extract the ZIP file
  3. Remove quarantine attribute (required):
    xattr -cr "singbox-launcher.app" && chmod +x "singbox-launcher.app/Contents/MacOS/singbox-launcher"
  4. Double-click singbox-launcher.app to run
    • If macOS blocks the app, go to System Settings → Privacy & Security and click "Open Anyway"
    • Alternatively, right-click the app and select "Open" (first time only)

Windows (amd64)

  1. Download: singbox-launcher-v1.2.3-win64.zip
  2. Extract the ZIP file to a folder, for example: C:\Program Files\singbox-launcher\
  3. Run singbox-launcher.exe from that folder
    • You may need administrator rights to install to Program Files
    • The launcher will automatically download sing-box and wintun.dll on first launch

Windows 7 (x86, legacy)

  1. Download: singbox-launcher-v1.2.3-win7-32.zip
  2. Extract the ZIP file to a folder and run singbox-launcher-win7-32.exe
    • For Windows 7 / 32-bit or legacy compatibility only

Linux Support

⚠️ Linux build temporarily unavailable - мы ищем тестировщика для ручного тестирования перед включением автоматической сборки.

Checksums

See checksums.txt for SHA256 checksums of all files.

v1.2.3 — MASQUE SNI fix, WARP registration cache

Core pinned: sing-box-lx 1.14.0-lx.5 (unchanged from v1.2.2). No config migration needed.

A WARP release: MASQUE nodes generated by the wizard came out with an empty SNI and could not pass traffic — that is fixed, and repeated «Add WARP» now reuses the registration you already have instead of enrolling a new device on every click.

EN

Highlights

  • MASQUE nodes generated by the wizard now carry an SNI — without it they could not pass traffic. The MASQUE section left its SNI field empty (only a placeholder was set, so sni.Text stayed empty and the generated masque:// URI had no sni=), while the WireGuard section next to it has always defaulted its masquerade domain to www.google.com. With no SNI the core falls back to consumer-masque.cloudflareclient.com: the tunnel establishes and DNS resolves, so the node looks healthy — but data never flows and the node reads as -1 in the proxy list. The field is now pre-filled with a random name from the pool (🎲 still re-rolls), and RegisterMasque substitutes a random one if it is ever handed an empty string, so no call path can produce an SNI-less node again. Measured on one machine, same node, only the SNI changing: no SNI → timeout, sni=www.google.com → 199 ms. (SPEC 086)
  • «Add WARP» reuses your existing registration; a checkbox forces new keys. Every click used to enroll a brand-new device: adding MASQUE H2 and then H3 produced two independent registrations, each with its own key and IPv6 — where LxBox on Android puts both nodes on a single one. Registrations are now cached in state.json (warp_accounts, WG and MASQUE separately) and reused, so H2 and H3 share one key. Create new keys — unchecked by default, shown only once a cached registration exists — goes to Cloudflare for a fresh one and replaces the cached entry.

Technical / Internal

  • core/state: new optional warp_accounts section in the v6 on-disk schema (disk_v6.goWarpAccountsSection/WarpWGAccount/WarpMasqueAccount, wired through save.go and load_v6.go, mirrored on State). omitempty — the key is absent for anyone who never registered WARP. No schema-version bump and no migration: an older file simply has no section, and an older launcher ignores an unknown key. The section holds the registration only (keys, addresses, token) — transport, SNI and timeouts are node parameters and stay out, which is exactly why one cached entry serves both H2 and H3.
  • core/warp/cache.go (new): conversion between warp.Account/warp.MasqueAccount and the state section. Endpoint and the AmneziaWG obfuscation fields are deliberately not cached — the UI sets them per build (preset, 🎲).
  • core/warp/client.go: the endpoint-resolution and obfuscation-field logic was inlined in Register between two HTTP calls; extracted into resolveEndpoint + the exported ApplyNodeOptions, so a cached account is assembled by exactly the same rules as a freshly registered one instead of a UI-side copy that could drift.
  • core/warp/masque.go: transport/SNI/timeout assignment extracted from RegisterMasque into MasqueAccount.ApplyNodeOptions(network, sni) — the same call now serves both a fresh and a cached account.
  • ui/configurator: WizardModel.WarpAccounts mirrors the state section (loaded in restoreParserConfig, written back in CreateStateFromModel); warp_dialog.go reads the cache, registers only on a miss, stores the result and marks the wizard changed.
  • Locale: wizard.warp.new_keys / wizard.warp.new_keys_note added (ru + en). wizard.warp.masque_sni_placeholder no longer says "empty = core default" — an empty SNI is no longer a reachable state.

Notes

  • Existing MASQUE nodes are not rewritten. The fix applies to nodes generated from now on; a node already in Sources keeps its stored URI. To repair one, re-add it via Add WARP (or append &sni=<name> to the source URI by hand).
  • The h3 transport is a separate, still-open problem. In our testing an h3 MASQUE node fails to pass traffic with every SNI tried, on desktop and on Android alike, while h2 works — this release does not address that, and no launcher-side setting affects it.

RU

Основное

  • MASQUE-ноды из визарда теперь получают SNI — без него они не пропускали трафик. MASQUE-секция оставляла поле SNI пустым (стоял только placeholder, поэтому sni.Text оставался пустым и в сгенерированном masque:// URI не было sni=), тогда как соседняя WireGuard-секция всегда подставляла домен маскировки www.google.com по умолчанию. Без SNI ядро использует consumer-masque.cloudflareclient.com: туннель встаёт и DNS резолвится — нода выглядит живой, но данные не идут, и в списке прокси она показывает -1. Теперь поле заранее заполнено случайным именем из пула (🎲 по-прежнему перевыбирает), а RegisterMasque подставляет случайное, если ему всё же передали пустую строку — так что ни один путь вызова больше не создаст ноду без SNI. Замер на одной машине, та же нода, менялся только SNI: без SNI — таймаут, sni=www.google.com — 199 мс. (SPEC 086)
  • «Add WARP» переиспользует уже выданную регистрацию; галочка заставляет создать новые ключи. Раньше каждый клик регистрировал новое устройство: MASQUE H2 и следом H3 давали две независимые регистрации, каждую со своим ключом и IPv6 — тогда как LxBox на Android держит обе ноды на одной. Теперь регистрации кешируются в state.json (секция warp_accounts, WG и MASQUE раздельно) и переиспользуются, поэтому H2 и H3 сидят на одном ключе. Создать новые ключи — снята по умолчанию, показывается только когда кеш уже есть — идёт в Cloudflare за свежей регистрацией и заменяет кешированную.

Техническое / Внутреннее

  • core/state: новая необязательная секция warp_accounts в v6-схеме на диске (disk_v6.goWarpAccountsSection/WarpWGAccount/WarpMasqueAccount, проводка через save.go и load_v6.go, зеркало на State). omitempty — у того, кто WARP не заводил, ключа в файле нет. Версия схемы не поднята, миграция не нужна: в старом файле секции просто нет, а старый лаунчер игнорирует незнакомый ключ. В секции лежит только регистрация (ключи, адреса, токен) — транспорт, SNI и таймауты относятся к узлу и в кеш не входят, именно поэтому одна запись обслуживает и H2, и H3.
  • core/warp/cache.go (новый): конверсия между warp.Account/warp.MasqueAccount и секцией состояния. Endpoint и поля обфускации AmneziaWG сознательно не кешируются — их задаёт UI на каждую сборку (пресет, 🎲).
  • core/warp/client.go: логика резолва endpoint'а и полей обфускации жила внутри Register между двумя HTTP-вызовами; вынесена в resolveEndpoint + экспортируемый ApplyNodeOptions, чтобы кешированный аккаунт собирался ровно теми же правилами, что и свежезарегистрированный, а не копией логики на стороне UI, которая могла разъехаться.
  • core/warp/masque.go: проставление транспорта/SNI/таймаутов вынесено из RegisterMasque в MasqueAccount.ApplyNodeOptions(network, sni) — теперь один и тот же вызов обслуживает и свежий, и кешированный аккаунт.
  • ui/configurator: WizardModel.WarpAccounts зеркалит секцию состояния (читается в restoreParserConfig, пишется обратно в CreateStateFromModel); warp_dialog.go читает кеш, регистрируется только при промахе, сохраняет результат и помечает визард изменённым.
  • Локализация: добавлены wizard.warp.new_keys / wizard.warp.new_keys_note (ru + en). wizard.warp.masque_sni_placeholder больше не обещает «пусто = дефолт ядра» — пустой SNI перестал быть достижимым состоянием.

Примечания

  • Существующие MASQUE-ноды не переписываются. Фикс действует на ноды, создаваемые начиная с этой версии; нода, уже лежащая в Sources, сохраняет свой URI. Чтобы починить — пересоздайте её через Add WARP (или допишите &sni=<имя> в URI источника руками).
  • Транспорт h3 — отдельная, всё ещё открытая проблема. В наших тестах MASQUE-нода на h3 не пропускает трафик ни с одним из проверенных SNI — одинаково и на десктопе, и на Android, тогда как h2 работает. Этот релиз её не решает, и никакая настройка лаунчера на неё не влияет.

Don't miss a new singbox-launcher release

NewReleases is sending notifications on new releases.