feat(tailscale): нативный режим tailscaled и компонент Tailscale

- новый компонент Tailscale: установка пакета из фида, карточка в Обновлениях
- режим native для секций Tailscale: системный tailscaled вместо sing-box endpoint
- доступ к тейлнету с LAN без клиента: маршруты 100.64.0.0/10 и MagicDNS через dnsmasq
- masquerade и exit-node (opt-in) с обходом tproxy по зарезервированной маске
- validator: требование tailscaled и auth-key для native; bypass-правила в mangle
- тесты: генерация конфига, смоук рантайма с моками, обновлена сигнатура состояния
This commit is contained in:
Dushnilin
2026-08-26 11:30:52 +03:00
parent 3532fa4280
commit 7f0b085a07
27 changed files with 1138 additions and 22 deletions
+15 -2
View File
@@ -416,9 +416,18 @@ function add_tailscale_endpoint(config, section, tag_name) {
push(config.endpoints, endpoint);
}
function is_native_tailscale(section) {
return option(section, "protocol", "vless") == "tailscale" &&
option(section, "tailscale_mode", "singbox") == "native";
}
function add_dns_bypass(config, section) {
if (option(section, "protocol", "vless") != "tailscale")
return;
// Native mode runs tailscaled outside sing-box; MagicDNS is served by
// dnsmasq instead of a sing-box DNS server.
if (is_native_tailscale(section))
return;
let section_name = section[".name"];
let inbound = runtime_constants.server_inbound_tag(section_name);
@@ -443,8 +452,11 @@ function add_server(config, section) {
let protocol = option(section, "protocol", "vless");
let tag_name = runtime_constants.server_inbound_tag(section_name);
if (protocol == "tailscale")
if (protocol == "tailscale") {
if (is_native_tailscale(section))
return;
add_tailscale_endpoint(config, section, tag_name);
}
else if (protocol == "json_inbound")
add_json_inbound(config, section, tag_name);
else
@@ -517,5 +529,6 @@ function clone_rules_for_inbound(config, source_inbound, target_inbound, skip_do
return {
add_server,
add_sniff_rule,
clone_rules_for_inbound
clone_rules_for_inbound,
is_native_tailscale
};