Release v1.6.0
Downloads
macOS (Universal) - Supports both Apple Silicon and Intel
Option 1: Installation Script (Recommended)
Install with a single command (version v1.6.0):
curl -fsSL https://raw.githubusercontent.com/Leadaxe/singbox-launcher/develop/scripts/install-macos.sh | bash -s -- v1.6.0The 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
- Download:
singbox-launcher-v1.6.0-macos.zip - Extract the ZIP file
- Remove quarantine attribute (required):
xattr -cr "singbox-launcher.app" && chmod +x "singbox-launcher.app/Contents/MacOS/singbox-launcher"
- Double-click
singbox-launcher.appto 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)
- Download:
singbox-launcher-v1.6.0-win64.zip- or
singbox-launcher-v1.6.0-win64-full.zip— full bundle:sing-box.exe,wintun.dll, the config template and Mesa3D (mesa3d/, used only when no hardware OpenGL — RDP, VMs) are already inside, nothing is downloaded on first launch
- or
- Extract the ZIP file to a folder, for example:
C:\Program Files\singbox-launcher\ - Run
singbox-launcher.exefrom that folder- You may need administrator rights to install to Program Files
- The regular archive downloads
sing-boxandwintun.dllon first launch
Windows 7 (x86, legacy)
- Download:
singbox-launcher-v1.6.0-win7-32.zip - 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.
Release notes — v1.6.0
EN
Highlights
-
The launcher state moves to schema v8 on its own, and the config stays the same. On the first start
state.jsonis converted in place and the original file stays next to it asstate.json.v7.bak. In v8 every record has one shape: the launcher's own fields on the record, the sing-box object as is inbody. The launcher and the phone app (LxBox) agreed on this shape as the common one for both apps' state and for the backup. You don't need to do anything by hand, and nothing changes in what reaches the core: aconfig.jsonbuilt from a real, long-lived state by the previous code and by this release is byte-for-byte identical. The profiles of the machines on the Remote tab are kept by this launcher and convert the same way, each with its own.v7.bak. The machines themselves never receive the state file: Deploy ships them a built config. The step is one-way. A 1.5.x launcher does not know v8 and cannot read such a file correctly: DNS settings, WARP accounts and the conditions of routing rules sit under names it does not look for. To go back to 1.5.x, putstate.json.v7.bakin place ofstate.json. Anything you changed after the upgrade is not in that copy. -
Tailscale: the tailnet bundle is complete, a bare node gets it by default, and the device identity follows the node. The bundle's route rule now catches names and addresses at once: a single rule carries both
domain_suffix [".ts.net"]andip_cidr ["100.64.0.0/10", "fd7a:115c:a1e0::/48"]. In 1.5.6 it held only100.64.0.0/10. With FakeIP, a connection to a*.ts.netname arrives as a name, the address rule did not match it, and the traffic silently went past the tailnet: the name resolved, but the wrong route was chosen. The tailnet's IPv6 range was not routed at all. Inside one sing-box rule the fields are joined by OR, which is why this is one rule and not two.A bare
tailscalenode now arrives with the bundle: the MagicDNS server, the.ts.netDNS rule and that route rule. "Bare" means pasted on its own, or part of a config where no DNS or route entry points at it. Before, such a node raised a tailnet that nothing was sent to. Add server → Tailscale produces the same bundle. The default applies only when a node is added. To drop the bundle, apply the node's document withoutdns/routeon its JSON tab, and it stays dropped. A bundle a node already carries is never rewritten, so a node added in 1.5.6 keeps its address-only rule until you edit it on that tab. In a config with several nodes, atailscalenode now takes the entries that point at its own tag; before, only a config with exactly one node kept them. Atailscalenode from a subscription stays, but without a bundle, because the bundle refers to the node's tag on this machine and the device identity is local. The node carries the info codetailscale_from_subscriptioninstead.The node's state directory (
bin/tailscale/<name>) now moves with the node. Renaming the node, moving it into or out of a folder, or changing a folder's tag policy renames the directory instead of orphaning it, so the tailnet keeps seeing the same device and no new auth key is needed. Deleting the node or its folder removes the directory. Every build also sweeps the directories of nodes that are no longer stored; disabled nodes and nodes dropped for lack of core support keep theirs. A rename that bypasses the launcher's windows (a backup import, a subscription refresh, a hand-editedstate.json) is only caught by that sweep, and it costs a new login. Astate_directoryset in the node body is never touched, and the directory never goes into a backup. -
Backup format 1.0: the file is the launcher state itself. Everything the state holds therefore travels: the rule and DNS sections of individual nodes, folders with their settings and contents, chain hops addressed at a folder, and the subscription identity. Format 1.0 is now the only format the launcher exports: Export writes it straight away, with no format checkbox. The phone app reads and writes the same format starting with LxBox 2.24.0, which is due shortly after this release; until you update the phone, a backup made on the desktop will not import into LxBox 2.23.2 and older, while a backup from the phone still imports into the launcher. Import reads both formats, including 0.12 files saved by earlier releases, and never asks which one you have. A record of a kind that node sections do not allow is dropped on import and named in the import report, instead of disappearing into the log. Scripts get the same export and import through the debug API (
/backup/*, see below). -
Core
1.14.0-lx.39: switching a nested Direction can no longer freeze all traffic. The launcher nests one selector inside another whenever a Direction is offered inside another Direction, like the template'svpn ①andvpn ②, which includeproxy-out. In that setup, switching the inner selector at the moment a connection dialed through the outer one was closing could deadlock both groups; a DNS server sent through that Direction is one example of such a connection. After that, every new TCP and UDP connection hung, later switches hung too, the UI already showed the new choice, and only a core restart helped. The cause: the groups closed connections while holding their own lock, and the two close paths took the two locks in opposite orders. Since lx.38 the lock is released before connections are closed.
Fixes
-
Upgrading no longer deletes the config template, and a failed rebuild no longer hides behind the old config. On the first start of a new version the launcher used to delete
wizard_template.json, and the template came back only when you pressed Download or opened the Configurator. Until then every config rebuild failed, and Start silently ran the previousconfig.json: your latest settings were not applied, and nothing said so. Now the template for the new version is downloaded right at launch, before the core starts, and it replaces the old file only once it has arrived whole and parses. If the download fails, the old template keeps working and the next launch tries again. The first core start after the upgrade rebuildsconfig.jsonfrom the new template. If a rebuild before a start fails for any reason, a dialog shows the cause and the core is not started. -
Xray JSON subscriptions: VLESS nodes with VLESS Encryption now connect (#121). The
users[0].encryptionvalue of VLESS nodes (VLESS Encryption / ML-KEM,mlkem768x25519plus…) is now carried into the sing-box outbound as is. Before, the converter dropped it, and a server that requires VLESS Encryption refused the connection (bad http protocol version). An empty value ornonestill emits no field, the same rule as for share links. -
UDP through SOCKS5 proxies that answer
0.0.0.0/::(core lx.39). Somesocksservers (version 5) answer UDP ASSOCIATE with an unspecified relay address; most public proxies and any server behind NAT do. A node on such a server carried TCP but no UDP at all: no DNS over UDP, QUIC, calls or games, and nothing in the log, while the same proxy worked in Xray-based clients. The core dialed the relay at exactly that address, which for Go means the local machine. Now it substitutes the proxy server's address from the config, as Xray does. TCP andudp_over_tcpare unchanged. The fix is covered by tests; confirmation on the reporter's own proxies is still pending. -
Backup import: a rule whose body is a list of sing-box rules becomes separate rules instead of being lost. A route rule record holds exactly one sing-box rule in
body, and what to do with a list in that place is now a rule shared with the phone app (LxBox). When an imported file carries a list there (a rawkind: jsonrule from an older 0.x backup, or a hand-edited 1.0 record), every object of the list becomes its own rule, in order:name,name #2,name #3… They share the on/off state and take the original rule's place in the rule order, so the builtconfig.jsonis exactly what the same rules written one by one would give. Before, a raw 0.x rule was skipped whole. An element that is not an object is dropped and named in the import report, like any other rule the launcher cannot read. The rule editor now refuses a pasted list with a clear message instead of a raw JSON error: paste one rule at a time. -
Backup import keeps routing rules in their places. Import used to renumber all routing rules from 1000 in a row. The order stayed, but the rule that sniffs traffic (
traffic-processing) and the template's rules above your own left their places. A preset enabled after the import then landed in front of sniffing, so rules that match by domain could miss, and a new rule of yours landed after catch-all rules such asrussian. Now every rule keeps its position from the file, and importing a backup of the same machine leaves the order untouched. Rules that arrive without a position go to the end. -
Backup import brings in every DNS entry of the file. Two identical DNS rules in a backup arrived as one. Duplicates are now looked for only among the entries you already have: a file entry identical to one of yours is skipped, while identical entries inside the file all arrive, so importing into a fresh install gives exactly what was backed up.
-
A subscription's own User-Agent survives an update from a pre-release build. A pre-release build of 1.6.0 kept a subscription's User-Agent and HWID settings in an older layout that this release did not read, and the next save erased them, so the provider answered as to the launcher. They are now picked up when the state loads.
-
A working chain is no longer reported as a source without nodes. A top-level chain that did reach the config still showed "No nodes from this source" in the Sources list, counted as a warning on the Final tab and turned the message after a subscription refresh into "Subscriptions partially refreshed … (1 failed)". Only a chain that really did not build is reported now, with the reason the chain failed.
-
Backup import: a link to a node inside a folder, written only by its config tag, now finds that node. A
detouror a chain hop that points at a folder member has to carry the folder's id. Older and foreign files may name the member by its final tag alone, like[P] Amsterdam. The build looks such a link up only among top-level names, so the node that dialed through it, or the chain with that hop, dropped out of the config on every build. Importing a 1.0 file now rewrites such a link to point at the folder member, but only when exactly one member of a folder or subscription has that final tag and no top-level node, Direction or known outbound carries the name. If several members match, the link stays as it is, and the build reports it as before. -
Two chains in one folder both reach the config. Each chain inside a folder is now built as its own outbound. Before, two chains in the same folder became one outbound with the first chain's name and the last chain's hops, and the other chain was lost without a word.
-
Backup import keeps links pointing at the right nodes. When the imported file meets what you already have, the import may keep your subscription (matched by URL), rename an incoming node (
X→X-2) or recognize it as a node you already have under another name. Links from the file — a node's detour, chain hops, members and the default of a group — now follow these nodes. Before, such a link kept the file's address: it pointed at nothing, or silently at your own node with the same name. Links in older 0.12 backups that named a server by its id now arrive as a link to that server instead of a link that never resolves. -
Renaming or deleting a node no longer leaves broken links. Renaming a top-level server or chain now updates everything that uses it: detours, chain hops, group members, rule targets, the default route, Direction options, preset variables and DNS detours. Before, the detours were cleared and the rest was left pointing at the old name. The new name must be free. Deleting a node, in a folder or at the top level, removes the detours, hops, group members and Direction options that used it and lists what was affected; a rule, the default route or a DNS detour that named the node keeps the name, as when you delete a Direction, and needs a new target. Renaming a Direction now also updates chain hops and detours inside folders, and renaming a folder's group (
fold_tag) updates links to it the same way. -
A folder filled from a subscription keeps its relays inside the folder. A copied node that dials through the subscription's BYPASS relay now dials through the relay's copy in the same folder. Before, it kept dialing through the subscription's node and dropped out of the config once the subscription was disabled or deleted. If the relay has no copy in the folder, the node still uses the subscription's relay.
-
Backup export: Directions keep their node filter and options. A Direction that comes from the config template or a preset, or that you changed on top of one (
proxy-out,vpn ②,ru VPN 🇷🇺), went into the backup file as a bare name: no node filter, no direct connection or other options, no auto-select. On the phone or on another machine such a Direction then picked a different set of nodes;proxy-out, for example, took in Russian nodes that it skips here. Export now writes every Direction the way it is actually built, the template or preset plus your changes, and recognizes the block option by your template's block tag, the same one the Direction form offers. -
A chain hop or detour on a provider's group survives a prefix change, and a selector keeps its default when a member moves. A chain position or a detour that points at a group from a subscription or folder now names the group by its own name inside that source, like any other node there, so changing the source's tag prefix no longer breaks it. A position saved by an earlier 1.6.0 build under the group's full config name is picked up automatically when the state loads; if it cannot be matched unambiguously, the build warning names the group so you can pick it again. A selector group's default now points at exactly the member it names: moving one member to another folder no longer silently drops the default that sat on a different member.
-
A Direction no longer holds nodes directly. A node gets into a Direction through its filter; the extra options of a Direction are only other Directions, folder replacements, direct and block. Saving a Direction from the JSON tab with a node or an unknown name among its options is now refused with a clear message. A state that already has such an option builds the same way as before, and the build report tells you which option is a node (use the filter) or no longer exists. A backup carries only other Directions in
include; the other options stay on this machine and are listed after export. -
A provider's group no longer takes a node's name. When a subscription had a group and a server with the same name, and the group came first in the subscription body (Xray balancer entries do this), the group took the name and the server became
name-2. Servers now get their names first and a same-named group becomesname-2, whatever the order. On the first update of such a subscription the server gets its name back without-2; links and switched-off marks follow the server again. -
The launcher no longer crashes on a Mac whose display is asleep. Started without
-traywhile the display slept (by a script or over SSH, for example), it crashed as soon as it opened the main window. Started with-trayin that state, it crashed later, on the first window you opened, even after the display had woken up. Such windows now open without the launcher's own centering, and macOS places them near the middle of the screen itself. -
Restoring a backup on a new machine keeps DNS inside the VPN. A template DNS server (such as
google_udp) sent through a Direction likeproxy-outcame back on the new machine sending its queries directly: the choice of channel was not in the backup at all. Now the channel and the name resolver of the template DNS servers travel with the backup. The Configurator's Import… on a machine where nothing has been saved yet also no longer lets the template's defaults win over the file: before, the DNS servers you had enabled stayed disabled, the default DNS silently fell back to the system resolver, and yourproxy-outand other Directions were reported as "already exists" and not applied. -
Restoring a backup on a new machine no longer turns off rules that go direct. Importing into a fresh install through the debug API turned off every rule going to
direct-outand ignored a default route set todirect-out; rules going toblock-outor to an endpoint of the template were turned off the same way. These are the template's own outbounds and always exist, so such rules now stay as they were in the file. Only a rule whose target really is missing arrives turned off. The Configurator's Import… also no longer quietly switches a rule going toblock-outover todirect-outwhen the result is loaded. And the debug API import no longer fails with500on a fresh install where the Configurator has never been saved. -
Sniffing and domain resolving keep their inbound list when the TUN and local proxy settings were never changed. A setting you never touched (the TUN switch, the local proxy switch, the resolve strategy) takes the template's default. The config's inbounds already used that default, but the rules that sniff traffic and resolve domains read the same setting as "off": they came out with
inbound: [], so they no longer said which inbounds they were for, and the resolve strategy went missing. This happened on any machine where these settings were never changed, and after every import into a fresh install, since they are not carried between machines. Now the rules, the preset preview, the DNS tab and Convert to user rule(s) see the same default as the inbounds. -
Routing rules moved by a backup import in 1.5.3–1.5.6 get their sniffing rule back in first place. Those releases renumbered all routing rules from 1000 when importing a backup, and the rule that sniffs traffic (
traffic-processing) left its place at the top. A preset enabled after such an import landed in front of it, so rules that match by domain could miss. The sniffing rule is fixed in place by the template, so the launcher now puts it back on its template position whenever the state is loaded or the config is built; the next save keeps it there. Your own rules and their order are not touched. Presets that the same import moved below your rules stay where they are, because you could have put them there yourself; to return one to its template place, remove it and add it again with 📚 Add from library. -
Stopping the launcher with a signal no longer leaves a crash record. On
kill <pid>or Ctrl+C in a terminal the launcher went through its normal shutdown, but crashed at the very end and wrote a panic tologs/crash.log— a report that looked like a real crash. It now exits cleanly, and the log says the stop came from a signal. -
On macOS, Cmd+Q, Quit in the Dock and logging out stop the core before the launcher quits. macOS used to end the launcher at once, past its normal shutdown, so in classic mode the core could stay running without the launcher, TUN routes included. These quits now go the same way as Quit in the tray menu: the core stops and the logs are closed. The launcher waits for that at most 5 seconds and then quits anyway, so a logout, restart or shutdown is never held up or cancelled. In daemon mode the core keeps running, as with Quit in the tray. The same fix brings back the launcher's reaction to display changes that macOS reports, which it had lost along with the quit handling.
-
Subscriptions with a rare URLTest interval no longer break the core startup. A provider asking for
"interval": "3h"produced a config the core rejected withinterval must be less or equal than idle_timeout: the group had noidle_timeout, and the core used its 30m default. The build now pairs such a group with a matchingidle_timeout; the provider's interval itself is never shortened, so servers are not probed more often than they asked (#118). The same fix covers the launcher's own1hURLTest interval setting, which failed the same way. -
Template DNS server settings travel with a backup, and the phone app reads them. A template DNS server now keeps its own settings in its record — the channel it goes through, the provider address, the Safe DNS profile — in
state.json, in the backup file and in the phone app alike. Before, only the channel travelled, and only between launchers: a restore turned "8.8.4.4 · Secondary v4" back into 8.8.8.8, and the phone app ignored the launcher's DNS route altogether. A setting left at the template default is not stored, so it follows the template of the device that reads it. Settings saved by earlier builds move into the record on their own, and the config stays the same. -
A DNS server routed through a Direction that no longer exists stops being used instead of going around the VPN. When a server's channel pointed at a missing tag — a Direction renamed or deleted — the build quietly dropped the channel, and the server resolved directly. Now the server is left out: the DNS rules aimed at it refuse their queries, a default DNS server set to it gives way to a final refusing rule, and resolvers that pointed at it switch to the template's default resolver, so the core still starts. Renaming a Direction now also carries a template DNS server's channel along.
Technical / Internal
-
State v8, record by record. Route rules carry
num(formerlyorder_num),name,refs[](formerlysrs_url+srs_urls) andvarsas fields, whilebodyholds the sing-box rule itself: the matchers together with the target (outbound/action). A preset record has no body at all. DNS servers and DNS rules keep their sing-box body inbody, and the server tag stays in thetagfield. Two root keys were renamed,dns_options→dnsandwarp_accounts→warp, and a subscription's identity is now oneidentityobject. The conversion works on the raw document, so matcher keys keep their bytes and order, and nothing is dropped. Rules of an unknown kind, standalone actions (sniff,hijack-dns), DNS bodies, node sections, order numbers, toggles and preset variables all travel across, and rule-set tags and the SRS cache keep their names. The debug API follows the file:GET /state/fullreturns the v8 shape, andPATCH /state/rules/PATCH /state/dnstake v8 records. A script written againstorder_num, flat DNS bodies ordns_optionsneeds updating. -
The schema gate now guards major 8. The gate covers
PATCH /state/rules,PATCH /state/dns,POST /backup/importand a profile copy between machines (POST /remote/machines/{id}/profile/copy-from), locally and for machines alike. When the state file involved was written by a newer schema major than the build knows, these calls answer409and name both versions, instead of reading the file with losses and writing the losses back. The same gate in a 1.5.x launcher answers409for a v8 file. -
Settings transfer over the debug API, at parity with the Export… / Import… buttons on the Configurator's Final tab.
GET /backup/exportreturns the file itself, with losses in theX-Backup-Warningsheader, or in the body with?envelope=1;?format=may be left out or set to1.0, and?format=0.12answers400("format 0.12 is no longer written; import still reads it").POST /backup/importmerges a file of either format and rebuildsconfig.json.GET /backup/formatsreports what this build reads and writes:{"reads":[1,2],"writes":["1.0"],"default":"1.0"}. Machines on the Remote tab mirror export and import under/remote/machines/{id}/backup/*. An import into a machine's profile does not rebuild that machine's config (config_rebuilt: false); it is still built by Save in that machine's Configurator. -
The shared LX contract moves to 1.0.2. The data agreement with the phone app (LxBox) now describes backup 1.0 in
contract/schema/backup.schema.json: markerlx_backup: 2, onesources[]section with akinddiscriminator. The previous schema is kept, frozen, asbackup-0.12.schema.json, so older files stay checkable.docs/BACKUP.md§11 lists every key that moved, anddocs/NODE_SECTIONS.md(including the Tailscale bundle rule above) anddocs/ONE_NAMESPACE.mdare no longer drafts. The corpus gained four 1.0 backup cases and two sing-box body cases: a bare Tailscale endpoint that must come out with the canonical bundle, and a whole config whose single node keeps its bundle.contract/VERSIONis now 1.0.2 (D-110), and the planned transition window with a second writer for 0.12 was dropped. -
The shared LX contract moves to 1.0.1. A link to a provider's group is
{folder_id, raw group tag}, a group'sdefaultis a node link object (a string is still read), a Direction'sincludeholds only Direction tags, anddetouris supported by both apps. The import names droppedincludeentries with the newbackup_direction_include_droppedcode. New corpus cases:v10_group_links,v10_dev_forms,v10_direction_include(D-115). The phone app's own settings (subscription detour policy and import rules, folder ping budget, rule-group definitions, rule update intervals, DNS server descriptions) are now declared in the backup schema: the launcher ignores them quietly on import, and a group defined only by a matching rule, which the launcher cannot express, is skipped with the newbackup_group_degradedwarning. The contract also records how an import into a fresh install reproduces the file (D-117,contract/VERSIONnot raised): the targets an import accepts are one list, counted after the merge and including the receiving template's own tags (docs/BACKUP.md§3); the channel of the template DNS servers travels with the file (in 1.0.2 — inside the DNS server record, see below); a preset that cannot be moved takes the receiving template's position (§9, item 7). -
The shared LX contract moves to 1.0.2. A template DNS server record carries the values of its own variables in
vars, by the local names its template entry declares, on both sides (D-118). One set of record rules covers these values and a preset rule'svars: only declared names, trimmed values, nothing equal to the template default (docs/TEMPLATE_LANG.md§6.4). The import overlays a matching record'svarsname by name, skips a record whose tag the receiving template does not declare (backup_dns_entry_skipped) and turns off a server whose channel is unknown (backup_unknown_outboundwith aserverparameter);backup_var_skippednow names the record and a reason (not_portable,undeclared,superseded,no_record). The five glued names of D-117 are no longer portable; readers move them into the record. The corpus gainsv10_dns_template_varswith a template declaration fixture both runners normalize against. -
The rest of the core update.
RequiredCoreVersionmoves from1.14.0-lx.36to1.14.0-lx.39. Besides the two fixes above, lx.37 syncs the fork with upstream sing-boxv1.14.0+ 33 commits (sing-tunv0.9.3,wireguard-gov0.0.6). WireGuard/AmneziaWG endpoints no longer go down when the device sleeps, only on a real network pause. On macOS they reopen their socket after a network change instead of staying dead until a restart. Checked withsing-box checkon the golden build config, on a real config (WireGuard, AmneziaWG, MASQUE, local rule-sets) and on the same config with a Tailscale node and its bundle. The core gates are unchanged:tailscalefrom lx.31, AmneziaWG 3.x from lx.32.
RU
Основное
-
Состояние лаунчера переходит на схему v8 само, а конфиг остаётся прежним. При первом запуске
state.jsonконвертируется на месте, а исходный файл остаётся рядом какstate.json.v7.bak. В v8 у каждой записи одна форма: собственные поля лаунчера лежат на записи, объект sing-box как есть — вbody. Эту форму лаунчер и мобильное приложение (LxBox) согласовали как общую для состояния обоих приложений и для бэкапа. Руками делать ничего не нужно, и в том, что уходит ядру, ничего не меняется:config.json, собранный из настоящего долгоживущего состояния прежним кодом и кодом этого релиза, совпадает байт-в-байт. Профили машин вкладки Remote хранит этот лаунчер, и они конвертируются так же, каждый со своей копией.v7.bak. Сами машины файл состояния не получают никогда: Deploy отправляет им собранный конфиг. Шаг односторонний. Лаунчер 1.5.x схему v8 не знает и правильно такой файл не прочтёт: настройки DNS, аккаунты WARP и условия правил маршрутизации лежат под именами, которых он не ищет. Чтобы вернуться на 1.5.x, положитеstate.json.v7.bakна местоstate.json. Всего, что вы поменяли после обновления, в этой копии нет. -
Tailscale: связка tailnet полная, голый узел получает её сам, а идентичность устройства ездит вместе с узлом. Правило маршрута в связке теперь ловит и имена, и адреса сразу: одно правило несёт и
domain_suffix [".ts.net"], иip_cidr ["100.64.0.0/10", "fd7a:115c:a1e0::/48"]. В 1.5.6 в нём был только100.64.0.0/10. При FakeIP соединение к имени*.ts.netприходит именем, правило по адресу его не матчило, и трафик молча уходил мимо tailnet: имя резолвилось, но выбирался не тот маршрут. IPv6-подсеть tailnet не маршрутизировалась вовсе. Внутри одного правила sing-box поля соединяются по ИЛИ, поэтому правило одно, а не два.Голый узел
tailscaleтеперь приезжает со связкой: DNS-сервер MagicDNS, DNS-правило на.ts.netи это правило маршрута. Голый — значит вставленный сам по себе или пришедший в конфиге, где на него не ссылается ни одна запись DNS или маршрута. Раньше такой узел поднимал tailnet, в которую ничего не направлялось. Add server → Tailscale выдаёт ту же связку. Подстановка срабатывает только при заведении узла. Чтобы снять связку, примените на вкладке JSON документ узла безdns/route— и она не вернётся. Уже имеющуюся у узла связку лаунчер никогда не переписывает, поэтому узел, заведённый в 1.5.6, сохраняет правило только по адресам, пока вы не поправите его на той же вкладке. В конфиге с несколькими узлами узелtailscaleтеперь забирает записи, которые ссылаются на его тег; раньше их сохранял только конфиг ровно с одним узлом. Узелtailscaleиз подписки остаётся, но без связки: связка ссылается на тег узла на этой машине, а идентичность устройства локальна. Вместо связки узел несёт info-кодtailscale_from_subscription.Каталог состояния узла (
bin/tailscale/<имя>) теперь переезжает вместе с узлом. Переименование узла, перенос в папку и из папки, смена тег-политики папки переименовывают каталог, а не бросают его, поэтому tailnet видит то же устройство и новый ключ авторизации не нужен. Удаление узла или его папки уносит каталог. Каждая сборка вдобавок подчищает каталоги узлов, которых в состоянии больше нет; выключенные узлы и узлы, снятые из-за ядра без поддержки, свои каталоги сохраняют. Переименование в обход окон лаунчера (импорт бэкапа, обновление подписки, ручная правкаstate.json) замечает только эта чистка, и оно стоит нового входа. Каталог, заданный в теле узла (state_directory), лаунчер не трогает, а в бэкап каталог не попадает никогда. -
Формат бэкапа 1.0: файл — это и есть состояние лаунчера. Поэтому переносится всё, что хранит состояние: секции правил и DNS у отдельных узлов, папки с их настройками и составом, хопы цепочек, адресованные в папку, и идентификация подписки. Формат 1.0 теперь единственный формат экспорта: «Экспорт…» пишет его сразу, чекбокса формата нет. Телефонное приложение читает и пишет тот же формат начиная с LxBox 2.24.0, который выйдет вскоре после этого релиза; пока телефон не обновлён, бэкап с десктопа в LxBox 2.23.2 и старше не импортируется, а бэкап с телефона в лаунчер по-прежнему импортируется. Импорт читает оба формата, в том числе файлы 0.12, сохранённые прежними релизами, и не спрашивает, какой у вас. Запись вида, которого секции узла не допускают, при импорте отбрасывается и называется в отчёте импорта, а не исчезает в логе. Скриптам тот же экспорт и импорт доступны через debug API (
/backup/*, см. ниже). -
Ядро
1.14.0-lx.39: переключение вложенного Направления больше не может заморозить весь трафик. Лаунчер вкладывает один selector в другой, когда Направление предложено внутри другого Направления, — какvpn ①иvpn ②шаблона, в которые входитproxy-out. В такой схеме переключение внутреннего selector'а в момент, когда закрывалось соединение, поднятое через внешний, могло заблокировать обе группы; пример такого соединения — DNS-сервер, отправленный через это Направление. После этого вставало каждое новое TCP- и UDP-соединение, следующие переключения тоже висли, UI уже показывал новый выбор, и помогал только перезапуск ядра. Причина: группы закрывали соединения, удерживая собственный замок, а два пути закрытия брали два замка в противоположном порядке. С lx.38 замок отпускается до закрытия соединений.
Исправления
-
Обновление больше не удаляет шаблон конфигурации, а провал пересборки больше не прячется за старым конфигом. При первом запуске новой версии лаунчер удалял
wizard_template.json, и шаблон возвращался, только когда вы нажимали Download или открывали Configurator. До тех пор каждая пересборка конфига падала, а Start молча запускал прежнийconfig.json: последние настройки не применялись, и ничто об этом не говорило. Теперь шаблон новой версии скачивается сразу при запуске, до старта ядра, и заменяет старый файл, только когда скачан целиком и разобран. Если скачать не вышло, работает старый шаблон, а следующий запуск попробует снова. Первый старт ядра после обновления пересобираетconfig.jsonиз нового шаблона. Если пересборка перед стартом падает по любой причине, диалог показывает причину, и ядро не запускается. -
Подписки Xray JSON: VLESS-узлы с VLESS Encryption теперь подключаются (#121). Значение
users[0].encryptionу VLESS-узлов (VLESS Encryption / ML-KEM,mlkem768x25519plus…) теперь переносится в outbound sing-box как есть. Раньше конвертер его терял, и сервер с обязательным VLESS Encryption рвал соединение (bad http protocol version). Пустое значение илиnoneпо-прежнему не даёт поля — то же правило, что у share-ссылок. -
UDP через SOCKS5-прокси, отвечающие
0.0.0.0/::(ядро lx.39). Некоторые серверыsocks(version 5) отвечают на UDP ASSOCIATE неопределённым адресом релея; так делают большинство публичных прокси и любой сервер за NAT. Узел на таком сервере носил TCP и не носил UDP вовсе: ни DNS по UDP, ни QUIC, ни звонков, ни игр, и в логе было пусто, хотя тот же прокси работал в клиентах на Xray. Ядро диалило релей ровно по этому адресу, а для Go это локальная машина. Теперь ядро подставляет адрес прокси-сервера из конфига, как это делает Xray. TCP иudp_over_tcpне меняются. Исправление покрыто тестами; подтверждения на прокси автора репорта пока нет. -
Импорт бэкапа: правило, у которого тело — список правил sing-box, раскладывается на отдельные правила, а не теряется. В записи правила маршрута
body— ровно одно правило sing-box, а что делать со списком на этом месте, теперь записано общей нормой с мобильным приложением (LxBox). Если в импортируемом файле там список (сырое правилоkind: jsonиз старого бэкапа 0.x или запись 1.0, поправленная руками), каждый объект списка становится отдельным правилом по порядку:имя,имя #2,имя #3… У них общий тумблер, и они встают на место исходного правила в порядке правил, поэтому собранныйconfig.json— ровно тот, что дали бы те же правила, записанные по одному. Раньше сырое правило 0.x пропускалось целиком. Элемент, который не объект, отбрасывается и называется в отчёте импорта — как любое правило, которое лаунчер прочесть не может. Редактор правила на вставленный список отвечает понятным сообщением, а не сырой ошибкой JSON: правила вставляются по одному. -
Импорт бэкапа оставляет правила маршрутизации на своих местах. Импорт перенумеровывал все правила маршрутизации подряд с 1000. Порядок сохранялся, но правило, извлекающее домен из трафика (
traffic-processing), и правила шаблона выше ваших уходили со своих мест. Пресет, включённый после импорта, вставал перед ним, и правила по доменам могли не срабатывать, а ваше новое правило вставало после перехватывающих правил вродеrussian. Теперь каждое правило сохраняет позицию из файла, и импорт бэкапа этой же машины порядок не трогает. Правила без позиции встают в конец. -
Импорт бэкапа ввозит все DNS-записи файла. Два одинаковых DNS-правила в бэкапе приезжали одним. Теперь дубли ищутся только среди записей, которые у вас уже есть: запись файла, совпавшая с вашей, пропускается, а одинаковые записи внутри файла приезжают все, поэтому импорт в чистую установку даёт ровно то, что было сохранено.
-
Собственный User-Agent подписки переживает обновление с предрелизной сборки. Предрелизная сборка 1.6.0 хранила User-Agent и настройки HWID подписки в прежней раскладке, которую этот релиз не читал, и следующее сохранение их стирало — провайдер отвечал как лаунчеру. Теперь они подхватываются при загрузке состояния.
-
Рабочая цепочка больше не числится источником без узлов. Цепочка верхнего уровня, которая попала в конфиг, всё равно показывала «Узлов из этого источника нет» в списке Sources, считалась предупреждением на вкладке «Итог», а сообщение после обновления подписок говорило «Subscriptions partially refreshed … (1 failed)». Теперь о цепочке сообщается, только если она действительно не собралась, и с причиной из её сборки.
-
Импорт бэкапа: ссылка на узел внутри папки, записанная одним тегом конфига, теперь находит этот узел.
detourили хоп цепочки, указывающий на член папки, обязан нести id папки. Старые и чужие файлы могут называть член папки только финальным тегом, например[P] Amsterdam. Сборка ищет такую ссылку только среди имён верхнего уровня, поэтому узел, дозванивавшийся через неё, или цепочка с таким хопом выпадали из конфига на каждой сборке. Импорт файла 1.0 теперь переписывает такую ссылку на член папки, но только если этот финальный тег ровно у одного члена папки или подписки и ни корневой узел, ни Направление, ни известный outbound так не называются. Если совпало несколько, ссылка остаётся как есть, и сборка сообщает о ней, как раньше. -
Две цепочки в одной папке обе попадают в конфиг. Каждая цепочка внутри папки теперь собирается своим outbound'ом. Раньше две цепочки одной папки становились одним outbound'ом с именем первой и позициями последней, а вторая пропадала без единого слова.
-
Импорт бэкапа не уводит ссылки с их узлов. Когда файл встречается с тем, что у вас уже есть, импорт может оставить вашу подписку (узнав её по URL), переименовать приехавший узел (
X→X-2) или узнать в нём ваш узел под другим именем. Ссылки из файла — detour узла, позиции цепочки, члены и умолчание группы — теперь идут за такими узлами. Раньше ссылка сохраняла адрес из файла: она указывала в никуда или молча на ваш узел с тем же именем. Ссылки старых бэкапов 0.12, называвшие сервер по его id, приезжают ссылкой на этот сервер, а не ссылкой, которая никогда не разрешится. -
Переименование и удаление узла больше не оставляют битых ссылок. Переименование сервера или цепочки верхнего уровня теперь обновляет всё, что его использует: detour, позиции цепочек, членов групп, цели правил, маршрут по умолчанию, опции Направлений, переменные пресетов и detour DNS. Раньше detour сбрасывались, а остальное продолжало указывать на старое имя. Новое имя должно быть свободным. Удаление узла — в папке или на верхнем уровне — снимает detour, позиции, членов групп и опции Направлений, которые его использовали, и называет задетое; правило, маршрут по умолчанию или detour DNS, выбравшие этот узел, сохраняют имя — как при удалении Направления — и ждут новой цели. Переименование Направления теперь обновляет и позиции цепочек, и detour внутри папок, а переименование группы свёртки папки (
fold_tag) обновляет ссылки на неё так же. -
Папка, залитая из подписки, держит релеи у себя. Скопированный узел, который дозванивался через релей BYPASS подписки, теперь дозванивается через копию релея в той же папке. Раньше он продолжал ходить через узел подписки и выпадал из конфига, как только подписку выключали или удаляли. Если копии релея в папке нет, узел по-прежнему идёт через релей подписки.
-
Экспорт бэкапа: Направления сохраняют фильтр узлов и опции. Направление из шаблона конфигурации или пресета, а также поправленное поверх них (
proxy-out,vpn ②,ru VPN 🇷🇺), уезжало в файл бэкапа одним именем: без фильтра узлов, без прямого соединения и других опций, без автовыбора. На телефоне или на другой машине такое Направление собирало другой набор узлов — например,proxy-outполучал российские узлы, которые здесь отсекает. Теперь экспорт пишет каждое Направление таким, каким оно собирается, — шаблон или пресет плюс ваши правки, а опцию блокировки узнаёт по тегу блокировки вашего шаблона, тому же, что предлагает форма Направления. -
Хоп цепочки или detour на группу провайдера переживает смену префикса, а селектор сохраняет умолчание при переносе члена. Позиция цепочки или detour на группу из подписки или папки теперь называет группу её собственным именем внутри источника, как любой другой узел там, поэтому правка префикса тегов источника её больше не рвёт. Позиция, сохранённая ранней сборкой 1.6.0 полным именем группы из конфига, подхватывается сама при загрузке состояния; если сопоставить однозначно нельзя, предупреждение сборки называет группу, чтобы выбрать её заново. Умолчание группы-селектора теперь указывает ровно на тот член, который называет: перенос одного члена в другую папку больше не снимает молча умолчание, стоявшее на другом члене.
-
Направление больше не держит узлы напрямую. Узел попадает в Направление через его фильтр; дополнительные варианты Направления — только другие Направления, замены папок, direct и block. Сохранение Направления с вкладки JSON, где среди вариантов узел или неизвестное имя, теперь отклоняется с понятным сообщением. Состояние, где такой вариант уже есть, собирается как раньше, а отчёт сборки говорит, какой вариант — узел (используйте фильтр) или больше не существует. В бэкап в
includeедут только другие Направления; остальные варианты остаются на этой машине и перечисляются после экспорта. -
Группа провайдера больше не отбирает имя у узла. Если в подписке были группа и сервер с одним именем, и группа стояла в теле подписки раньше (так бывает у балансировщиков Xray), имя забирала группа, а сервер становился
имя-2. Теперь имена сперва получают серверы, а группа-тёзка становитсяимя-2, в каком бы порядке они ни шли. При первом обновлении такой подписки сервер вернёт себе имя без-2, и ссылки и отметки выключения снова ведут на него. -
Лаунчер больше не падает на Mac со спящим дисплеем. Запущенный без
-tray, пока дисплей спал (например, скриптом или по SSH), он падал сразу, как только открывал главное окно. Запущенный в таком состоянии с-tray, падал позже — на первом открытом окне, даже когда дисплей уже проснулся. Теперь такие окна открываются без центрирования от лаунчера, и macOS сама ставит их ближе к середине экрана. -
Восстановление бэкапа на новой машине не выводит DNS из VPN. Шаблонный DNS-сервер (например,
google_udp), отправленный через Направление вродеproxy-out, на новой машине слал запросы напрямую: выбора канала в бэкапе не было вовсе. Теперь канал и резолвер имени шаблонных DNS-серверов переносятся с бэкапом. А Импорт… в Конфигураторе на машине, где ещё ничего не сохранено, больше не отдаёт победу умолчаниям шаблона: раньше включённые вами DNS-серверы оставались выключенными, DNS по умолчанию молча уходил на системный резолвер, а вашproxy-outи другие Направления объявлялись «уже существующими» и не применялись. -
Восстановление бэкапа на новой машине больше не выключает правила на прямое соединение. Импорт в чистую установку через debug API выключал каждое правило на
direct-outи не применял маршрут по умолчанию наdirect-out; так же выключались правила наblock-outи на endpoint шаблона. Это собственные outbound'ы шаблона, они есть всегда, поэтому такие правила теперь приезжают такими, какими были в файле. Выключенным приезжает только правило, чьей цели действительно нет. Импорт… в Конфигураторе тоже больше не переводит молча правило наblock-outнаdirect-out, когда загружает результат. А импорт через debug API больше не падает с500на чистой установке, где Конфигуратор ни разу не сохраняли. -
Извлечение домена и резолв сохраняют список inbound, когда настройки TUN и локального прокси не меняли. Настройка, которую вы не трогали (переключатель TUN, переключатель локального прокси, стратегия резолва), берёт умолчание шаблона. inbounds конфига уже брали это умолчание, а правила, извлекающие домен из трафика и резолвящие домены, читали ту же настройку как «выключено»: они выходили с
inbound: [], то есть без указания, для каких inbound они, и стратегия резолва пропадала. Так было на любой машине, где эти настройки не меняли, и после каждого импорта в чистую установку — их между машинами не переносят. Теперь правила, превью пресета, вкладка DNS и Преобразовать в пользовательское видят то же умолчание, что и inbounds. -
Правилам маршрутизации, сдвинутым импортом бэкапа в 1.5.3–1.5.6, возвращается правило извлечения домена на первое место. Эти релизы при импорте бэкапа перенумеровывали все правила маршрутизации подряд с 1000, и правило, извлекающее домен из трафика (
traffic-processing), уходило с первого места. Пресет, включённый после такого импорта, вставал перед ним, и правила по доменам могли не срабатывать. Место этого правила закреплено шаблоном, поэтому лаунчер теперь возвращает его на позицию шаблона при каждой загрузке состояния и сборке конфига; следующее сохранение его там и оставит. Ваши правила и их порядок не трогаются. Пресеты, которые тот же импорт увёл ниже ваших правил, остаются на месте — туда вы могли поставить их и сами; чтобы вернуть пресет на место шаблона, удалите его и добавьте снова через 📚 Добавить из библиотеки. -
Остановка лаунчера сигналом больше не оставляет запись о падении. При
kill <pid>или Ctrl+C в терминале лаунчер проходил обычную остановку, но на самом выходе падал и писал панику вlogs/crash.log— отчёт, неотличимый от настоящего падения. Теперь выход чистый, а в логе видно, что остановку прислал сигнал. -
На macOS Cmd+Q, «Завершить» в Dock и выход из системы останавливают ядро до выхода лаунчера. Раньше macOS завершал лаунчер сразу, мимо его обычной остановки, и в classic-режиме ядро могло остаться работать без лаунчера вместе с маршрутами TUN. Теперь такой выход идёт тем же путём, что Quit в меню трея: ядро останавливается, логи закрываются. Лаунчер ждёт этого не дольше 5 секунд и после выходит всё равно, так что выход из системы, перезагрузку и выключение он не задерживает и не отменяет. В daemon-режиме ядро продолжает работать, как и при Quit в трее. Тот же фикс возвращает лаунчеру реакцию на смену дисплеев, о которой сообщает macOS: она пропала вместе с обработкой выхода.
-
Подписки с редким интервалом URLTest больше не ломают старт ядра. Провайдерский
"interval": "3h"давал конфиг, который ядро отвергало сinterval must be less or equal than idle_timeout: у группы не былоidle_timeout, и ядро подставляло свои 30 минут. Теперь сборка достраивает такой группеidle_timeoutпод интервал, а сам интервал остаётся провайдерским — сервер не опрашивается чаще, чем он просил (#118). Тот же фикс закрывает собственную настройку лаунчера1h, которая падала так же. -
Настройки шаблонных DNS-серверов переносятся бэкапом, и мобильное приложение их читает. Шаблонный DNS-сервер теперь хранит свои настройки в своей записи — канал, через который он ходит, адрес провайдера, профиль Safe DNS — одинаково в
state.json, в файле бэкапа и в мобильном приложении. Раньше переносился только канал и только между лаунчерами: восстановление превращало «8.8.4.4 · Secondary v4» обратно в 8.8.8.8, а мобильное приложение маршрут DNS лаунчера не видело вовсе. Настройка, оставленная по умолчанию шаблона, не хранится и следует шаблону того устройства, которое её читает. Настройки, сохранённые прежними сборками, переезжают в запись сами, конфиг при этом не меняется. -
DNS-сервер, направленный через исчезнувшее Направление, перестаёт использоваться, а не ходит мимо VPN. Когда канал сервера указывал на тег, которого нет, — Направление переименовали или удалили, — сборка молча снимала канал, и сервер резолвил напрямую. Теперь сервер не попадает в конфиг: DNS-правила, направленные на него, отказывают, DNS-сервер по умолчанию, указывавший на него, уступает место отказывающему правилу в конце, а резолверы, ссылавшиеся на него, переключаются на резолвер по умолчанию шаблона — ядро по-прежнему стартует. Переименование Направления теперь переписывает и канал шаблонного DNS-сервера.
Техническое / Внутреннее
-
Состояние v8 по записям. У правил маршрута полями лежат
num(бывшийorder_num),name,refs[](бывшиеsrs_url+srs_urls) иvars, а вbody— само правило sing-box: матчеры вместе с целью (outbound/action). У записи пресета тела нет вовсе. У DNS-серверов и DNS-правил тело sing-box лежит вbody, тег сервера — в полеtag. Два корневых ключа переименованы (dns_options→dns,warp_accounts→warp), а идентификация подписки стала одним объектомidentity. Конвертация идёт по сырому документу, поэтому ключи матчеров сохраняют байты и порядок, и ничего не теряется. Правила неизвестного вида, самостоятельные действия (sniff,hijack-dns), тела DNS, секции узлов, номера порядка, тумблеры и переменные пресетов переезжают как есть, а теги rule-set и кэш SRS сохраняют имена. Debug API следует за файлом:GET /state/fullотдаёт форму v8, аPATCH /state/rules/PATCH /state/dnsпринимают записи v8. Скрипт, написанный подorder_num, плоские тела DNS илиdns_options, придётся обновить. -
Гейт схемы теперь стережёт мажор 8. Гейт охраняет
PATCH /state/rules,PATCH /state/dns,POST /backup/importи копирование профиля между машинами (POST /remote/machines/{id}/profile/copy-from) — локально и для машин одинаково. Если затронутый файл состояния написан схемой новее той, что знает сборка, эти вызовы отвечают409с обеими версиями в тексте, а не читают файл с потерями и не записывают потери обратно. Тот же гейт в лаунчере 1.5.x отвечает409на файл v8. -
Перенос настроек через debug API — наравне с кнопками Экспорт… / Импорт… на вкладке «Итог» Конфигуратора.
GET /backup/exportотдаёт сам файл, а потери — заголовкомX-Backup-Warningsлибо в теле при?envelope=1;?format=можно не указывать или указать1.0, а?format=0.12отвечает400(«format 0.12 is no longer written; import still reads it»).POST /backup/importсливает файл любого формата и пересобираетconfig.json.GET /backup/formatsсообщает, что эта сборка читает и пишет:{"reads":[1,2],"writes":["1.0"],"default":"1.0"}. У машин вкладки Remote есть зеркала экспорта и импорта под/remote/machines/{id}/backup/*. Импорт в профиль машины не пересобирает её конфиг (config_rebuilt: false): его по-прежнему собирает Save в Конфигураторе этой машины. -
Общий контракт LX переходит на 1.0.2. Соглашение о данных с мобильным приложением (LxBox) теперь описывает бэкап 1.0 в
contract/schema/backup.schema.json: маркерlx_backup: 2, одна секцияsources[]с видом записиkind. Прежняя схема сохранена замороженной какbackup-0.12.schema.json, чтобы старые файлы по-прежнему проверялись.docs/BACKUP.md§11 перечисляет каждый переехавший ключ, аdocs/NODE_SECTIONS.md(вместе с правилом связки Tailscale выше) иdocs/ONE_NAMESPACE.mdвышли из черновика. В корпус добавлены четыре кейса бэкапа 1.0 и два кейса тела sing-box: голый endpoint Tailscale, который обязан выйти с канонической связкой, и целый конфиг, единственный узел которого сохраняет свою связку.contract/VERSIONтеперь 1.0.2 (D-110), а задуманное переходное окно со вторым писателем 0.12 отменено. -
Общий контракт LX переходит на 1.0.1. Ссылка на группу провайдера —
{folder_id, сырой тег группы},defaultгруппы — объект ссылки на узел (строка по-прежнему читается),includeНаправления несёт только теги Направлений,detourподдерживают оба приложения. Импорт называет отброшенные строкиincludeновым кодомbackup_direction_include_dropped. Новые кейсы корпуса:v10_group_links,v10_dev_forms,v10_direction_include(D-115). Собственные настройки мобильного приложения (политика detour и правила импорта подписки, бюджет замера папки, группы по правилу, период обновления наборов, описания DNS-серверов) объявлены в схеме бэкапа: лаунчер при импорте молча их игнорирует, а группу, заданную только правилом отбора, которую лаунчер выразить не может, пропускает с новым предупреждениемbackup_group_degraded. Ещё контракт фиксирует, как импорт в чистую установку воспроизводит файл (D-117,contract/VERSIONне поднят): цели, которые принимает импорт, — один список, считаемый после слияния и включающий собственные теги шаблона приёмника (docs/BACKUP.md§3); канал шаблонных DNS-серверов едет с файлом (в 1.0.2 — в записи DNS-сервера, ниже); пресет, который нельзя двигать, встаёт на позицию шаблона приёмника (§9 п. 7). -
Общий контракт LX переходит на 1.0.2. Запись шаблонного DNS-сервера несёт значения своих переменных в
varsпо локальным именам своей записи в шаблоне, у обеих сторон (D-118). Одни нормы записи для этих значений и дляvarsправила-пресета: только объявленные имена, значения подрезаны, ничего равного умолчанию шаблона (docs/TEMPLATE_LANG.md§6.4). Импорт накладываетvarsсовпавшей записи по именам, не ввозит запись с тегом, которого шаблон приёмника не объявил (backup_dns_entry_skipped), и выключает сервер с неизвестным каналом (backup_unknown_outboundс параметромserver);backup_var_skippedназывает запись и причину (not_portable,undeclared,superseded,no_record). Пять склеенных имён D-117 больше не переносимы, читатели переносят их в запись. В корпусе — кейсv10_dns_template_varsс фикстурой объявлений шаблона, по которой нормализуют оба раннера. -
Остальное из обновления ядра.
RequiredCoreVersionподнят с1.14.0-lx.36до1.14.0-lx.39. Помимо двух исправлений выше, lx.37 синхронизирует форк с апстримом sing-boxv1.14.0+ 33 коммита (sing-tunv0.9.3,wireguard-gov0.0.6). Endpoint'ы WireGuard/AmneziaWG больше не опускаются на сон устройства, только на настоящую паузу сети. На macOS после смены сети они переоткрывают сокет, а не висят до перезапуска. Провереноsing-box checkна golden-конфиге сборки, на реальном конфиге (WireGuard, AmneziaWG, MASQUE, локальные rule-set) и на нём же с узлом Tailscale и его связкой. Пороги гейтов ядра не меняются:tailscale— с lx.31, AmneziaWG 3.x — с lx.32.