Skip to content

release v1.2.7

Latest

Choose a tag to compare

@github-actions github-actions released this 31 Jul 08:53

Release v1.2.7

Downloads

macOS (Universal) - Supports both Apple Silicon and Intel

Option 1: Installation Script (Recommended)

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

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

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.7-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.7-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.7-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.7 — одна нода с fp=HelloChrome_120 больше не роняет весь конфиг

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

A one-bug release. If any node in your subscription carried a raw uTLS identifier in fp=, sing-box refused to start at all — not just that node, the entire config. Nothing connected, and the log said unknown uTLS fingerprint.

EN

Highlights

  • A single node with an unknown fp= value no longer takes down the whole config. Some lists ship the uTLS library's Go identifier — fp=HelloChrome_120 — instead of the short name sing-box expects. The launcher only lowercased it, so hellochrome_120 landed in config.json verbatim. sing-box validates that field against a fixed set and aborts on anything else:

    FATAL create service: initialize outbound[26]: unknown uTLS fingerprint: hellochrome_120
    

    That is a config-load failure, not a per-node one: outbound #26 being bad meant outbounds #0–25 never started either. The value is now checked against the set sing-box actually accepts, and raw uTLS identifiers are mapped onto their browser family (HelloChrome_120chrome, HelloFirefox_Autofirefox, and so on).

  • Unrecognised fingerprints degrade the node instead of poisoning the config. Anything that cannot be mapped is dropped, and the node falls back to a valid fingerprint rather than carrying junk into config.json. Same policy as the REALITY pbk validation in v1.1.7 and the malformed ?ed= handling in v1.2.6.

Technical / Internal

  • The accepted set was taken from sing-box's own source, not from memory. uTLSClientHelloID in common/tls/utls_client.go accepts chrome, firefox, edge, safari, 360, qq, ios, android, random, randomized, ""plus five Chrome ClientHello variants that are easy to overlook: chrome_psk, chrome_psk_shuffle, chrome_padding_psk_shuffle, chrome_pq, chrome_pq_psk. Guessing the list would have silently broken nodes that legitimately use those.
  • Alias matching ignores separators. _, - and spaces are stripped before the prefix match, so HelloChrome_120, hellochrome-106 and HelloChrome 120 all resolve to chrome. Ordering matters: hellorandomized is tested before hellorandom, otherwise HelloRandomized would collapse into random.
  • The emitter needed its own fix. GenerateNodeJSON re-normalises the fingerprint, but previously would have written "fingerprint":"" for a rejected value. It now omits the key entirely, letting sing-box fall back to its default Chrome hello. This matters for templates: a tls.utls block placed by hand or seeded into wizard_template.json never passes through a parser, so the emitter is the only gate it meets.
  • Verified against sing-box's validator rather than by assertion. Every value the normaliser can emit was run through a verbatim copy of the upstream switch, confirming all outputs are accepted — and that the original hellochrome_120 really was rejected, so the check proves something.
  • Tests: 5 new cases — a normaliser table (sing-box names, Chrome variants, raw uTLS identifiers, junk), two parser regressions, and two emitter regressions. The existing QQ casing test from issue #45 still passes.

Notes

  • sing-box check did catch this one — unlike the ?ed= bug in v1.2.6, the failure was loud and at config-load time. The launcher surfaced it as RebuildConfigIfDirty: sing-box check failed, retrying every few seconds.
  • Nothing else changed. If no node in your subscription carries an unusual fp= value, this release is a no-op for you.

RU

Основное

  • Одна нода с неизвестным fp= больше не роняет весь конфиг. Некоторые списки кладут в fp= Go-идентификатор из библиотеки uTLS — fp=HelloChrome_120 — вместо короткого имени, которое ждёт sing-box. Лаунчер только приводил строку к нижнему регистру, и hellochrome_120 уезжал в config.json как есть. sing-box сверяет это поле с фиксированным набором и на всём остальном прекращает загрузку:

    FATAL create service: initialize outbound[26]: unknown uTLS fingerprint: hellochrome_120
    

    Это отказ загрузки всего конфига, а не одной ноды: из-за битого outbound #26 не поднимались и outbound'ы #0–25. Теперь значение проверяется по набору, который sing-box действительно принимает, а сырые uTLS-идентификаторы отображаются на своё семейство браузера (HelloChrome_120chrome, HelloFirefox_Autofirefox и т.д.).

  • Нераспознанный fingerprint деградирует ноду, а не портит конфиг. Всё, что не удалось сопоставить, отбрасывается, и нода откатывается на валидный fingerprint вместо того, чтобы тащить мусор в config.json. Та же политика, что при валидации REALITY pbk в v1.1.7 и при разборе битого ?ed= в v1.2.6.

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

  • Набор допустимых значений взят из исходников sing-box, а не по памяти. uTLSClientHelloID в common/tls/utls_client.go принимает chrome, firefox, edge, safari, 360, qq, ios, android, random, randomized, ""плюс пять вариантов Chrome ClientHello, которые легко пропустить: chrome_psk, chrome_psk_shuffle, chrome_padding_psk_shuffle, chrome_pq, chrome_pq_psk. Угадывание списка молча сломало бы ноды, которые их законно используют.
  • Сопоставление алиасов игнорирует разделители. _, - и пробелы вычищаются перед сравнением префикса, поэтому HelloChrome_120, hellochrome-106 и HelloChrome 120 одинаково дают chrome. Порядок важен: hellorandomized проверяется до hellorandom, иначе HelloRandomized схлопнулся бы в random.
  • Эмиттеру потребовалась отдельная правка. GenerateNodeJSON перенормализует fingerprint, но раньше на отклонённом значении записал бы "fingerprint":"". Теперь ключ не пишется вовсе, и sing-box берёт свой Chrome-hello по умолчанию. Это важно для шаблонов: блок tls.utls, положенный руками или засеянный в wizard_template.json, не проходит через парсер вообще — эмиттер для него единственный барьер.
  • Проверено против валидатора sing-box, а не на слово. Все значения, которые может вернуть нормализатор, прогнаны через дословную копию upstream-switch: подтверждено, что ядро принимает каждое — и что исходный hellochrome_120 действительно отвергался, иначе проверка ничего не доказывала бы.
  • Тесты: 5 новых кейсов — таблица нормализатора (имена sing-box, варианты Chrome, сырые uTLS-идентификаторы, мусор), две регрессии парсера и две регрессии эмиттера. Старый тест на регистр QQ из issue #45 продолжает проходить.

Примечания

  • sing-box check эту проблему как раз ловил — в отличие от бага с ?ed= из v1.2.6, отказ был громким и на этапе загрузки конфига. Лаунчер показывал его как RebuildConfigIfDirty: sing-box check failed и повторял попытку каждые несколько секунд.
  • Больше ничего не изменилось. Если ни в одной вашей ноде нет необычного fp=, этот релиз для вас пустой.