release: 1.3.24 — тест утечки IP/DNS из роутера, оптимизация запуска списков хостов и локализация
- feat(diagnostics): router-level IP & DNS leak detection * одновременный опрос прямого WAN сокета (SO_MARK 0x08000000) и локального прокси (127.0.0.1:4534) * выявление утечки реального публичного IP адреса * тестирование восходящих DNS-резолверов по протоколу bash.ws и обнаружение DNS провайдера * CLI команды: tachyon leak_check [--pretty], check_ip_leak, check_dns_leak * LuCI модальное окно с детализированными таблицами изоляции IP и анализа резолверов - fix(hosts): устранение ложного предупреждения [warn] No hosts list URLs configured * запуск HOSTS_UC в lifecycle.uc только при наличии активных списков хостов * hosts.uc возвращает success:true и код 0 без лишних записей в syslog при отсутствии URL * добавлена проверка has-hosts-list-update-sources в state.uc - i18n: полная синхронизация русской локализации в каталогах gettext PO/POT - bump: версия пакета 1.3.24
This commit is contained in:
@@ -3433,6 +3433,9 @@ var Tachyon;
|
||||
AvailableMethods2["DNS_BENCHMARK_STATUS"] = "dns_benchmark_status";
|
||||
AvailableMethods2["DNS_BENCHMARK_STOP"] = "dns_benchmark_stop";
|
||||
AvailableMethods2["DNS_BENCHMARK_APPLY"] = "dns_benchmark_apply";
|
||||
AvailableMethods2["LEAK_CHECK"] = "leak_check";
|
||||
AvailableMethods2["CHECK_IP_LEAK"] = "check_ip_leak";
|
||||
AvailableMethods2["CHECK_DNS_LEAK"] = "check_dns_leak";
|
||||
})(AvailableMethods = Tachyon2.AvailableMethods || (Tachyon2.AvailableMethods = {}));
|
||||
let AvailableClashAPIMethods;
|
||||
((AvailableClashAPIMethods2) => {
|
||||
@@ -4724,6 +4727,26 @@ var TachyonShellMethods = {
|
||||
recommendation: parsed.recommendation
|
||||
}
|
||||
};
|
||||
},
|
||||
leakCheck: async () => {
|
||||
const response = await executeShellCommand({
|
||||
command: "/usr/bin/tachyon",
|
||||
args: [Tachyon.AvailableMethods.LEAK_CHECK],
|
||||
timeout: 25e3
|
||||
});
|
||||
const parsed = parseJsonObjectOutput(
|
||||
response.stdout
|
||||
);
|
||||
if ((response.code ?? 0) !== 0 || !parsed) {
|
||||
return {
|
||||
success: false,
|
||||
error: response.stderr || _("Failed to execute IP and DNS leak check")
|
||||
};
|
||||
}
|
||||
return {
|
||||
success: true,
|
||||
data: parsed
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -11320,7 +11343,8 @@ function renderAvailableActions({
|
||||
viewLogs,
|
||||
showSingBoxConfig,
|
||||
generateBugReport,
|
||||
checkServices
|
||||
checkServices,
|
||||
testLeaks
|
||||
}) {
|
||||
return E("div", { class: "tachyon_diagnostic-page__right-bar__actions" }, [
|
||||
E("b", {}, _("Available actions")),
|
||||
@@ -11442,6 +11466,16 @@ function renderAvailableActions({
|
||||
disabled: checkServices.disabled
|
||||
})
|
||||
]),
|
||||
...insertIf(!!testLeaks?.visible, [
|
||||
renderButton({
|
||||
classNames: ["cbi-button-action"],
|
||||
onClick: testLeaks.onClick,
|
||||
icon: renderCircleCheckBigIcon24,
|
||||
text: _("\u{1F6E1}\uFE0F IP & DNS Leak Test"),
|
||||
loading: testLeaks.loading,
|
||||
disabled: testLeaks.disabled
|
||||
})
|
||||
]),
|
||||
...insertIf(viewLogs.visible, [
|
||||
renderButton({
|
||||
onClick: viewLogs.onClick,
|
||||
@@ -14709,6 +14743,336 @@ function renderDnsBenchmarkModal() {
|
||||
startBenchmark();
|
||||
}
|
||||
|
||||
// src/tachyon/tabs/diagnostic/partials/renderLeakCheckModal.ts
|
||||
function renderLeakCheckModal() {
|
||||
let isRunning = false;
|
||||
const progressBar = E("div", {
|
||||
style: "width: 0%; height: 6px; background: linear-gradient(90deg, #007bff, #28a745); border-radius: 3px; transition: width 0.4s ease;"
|
||||
});
|
||||
const progressContainer = E(
|
||||
"div",
|
||||
{
|
||||
style: "width: 100%; height: 6px; background: rgba(128,128,128,0.2); border-radius: 3px; overflow: hidden; margin-bottom: 14px;"
|
||||
},
|
||||
[progressBar]
|
||||
);
|
||||
const statusLabel = E(
|
||||
"div",
|
||||
{
|
||||
style: "font-size: 13px; font-weight: 500; margin-bottom: 12px; color: var(--text-color-medium, #6c757d);"
|
||||
},
|
||||
_("Initializing router-level IP & DNS leak test...")
|
||||
);
|
||||
const resultsContainer = E("div", {
|
||||
style: "display: none; margin-bottom: 16px;"
|
||||
});
|
||||
const startTest = async () => {
|
||||
if (isRunning) return;
|
||||
isRunning = true;
|
||||
resultsContainer.style.display = "none";
|
||||
progressContainer.style.display = "block";
|
||||
progressBar.style.width = "30%";
|
||||
statusLabel.textContent = _(
|
||||
"Querying WAN direct socket and proxy outbound on 127.0.0.1:4534..."
|
||||
);
|
||||
if (retryBtn) retryBtn.disabled = true;
|
||||
const timer = setTimeout(() => {
|
||||
progressBar.style.width = "70%";
|
||||
statusLabel.textContent = _(
|
||||
"Testing DNS leak upstream resolvers with bash.ws protocol..."
|
||||
);
|
||||
}, 1500);
|
||||
try {
|
||||
const response = await TachyonShellMethods.leakCheck();
|
||||
clearTimeout(timer);
|
||||
progressBar.style.width = "100%";
|
||||
if (response.success && response.data) {
|
||||
statusLabel.textContent = _("Leak detection completed");
|
||||
setTimeout(() => {
|
||||
progressContainer.style.display = "none";
|
||||
progressBar.style.width = "0%";
|
||||
}, 400);
|
||||
renderResults(response.data);
|
||||
} else {
|
||||
const err = !response.success && response.error ? response.error : _("Leak detection failed to complete");
|
||||
progressContainer.style.display = "none";
|
||||
statusLabel.textContent = err;
|
||||
resultsContainer.innerHTML = "";
|
||||
resultsContainer.appendChild(
|
||||
E(
|
||||
"div",
|
||||
{ class: "alert-message warning" },
|
||||
err || _(
|
||||
"Could not contact leak test endpoints. Please ensure router has internet access."
|
||||
)
|
||||
)
|
||||
);
|
||||
resultsContainer.style.display = "block";
|
||||
}
|
||||
} catch (e) {
|
||||
clearTimeout(timer);
|
||||
progressContainer.style.display = "none";
|
||||
statusLabel.textContent = _("An unexpected error occurred during test");
|
||||
resultsContainer.innerHTML = "";
|
||||
resultsContainer.appendChild(
|
||||
E(
|
||||
"div",
|
||||
{ class: "alert-message warning" },
|
||||
e instanceof Error ? e.message : String(e)
|
||||
)
|
||||
);
|
||||
resultsContainer.style.display = "block";
|
||||
} finally {
|
||||
isRunning = false;
|
||||
if (retryBtn) retryBtn.disabled = false;
|
||||
}
|
||||
};
|
||||
const renderResults = (data) => {
|
||||
resultsContainer.innerHTML = "";
|
||||
const { ip_leak, dns_leak } = data;
|
||||
const ipAlertClass = !ip_leak.proxy_online ? "alert-message warning" : ip_leak.leaked ? "alert-message danger" : "alert-message success";
|
||||
const ipAlertText = !ip_leak.proxy_online ? _("Proxy is offline or unreachable on 127.0.0.1:4534.") : ip_leak.leaked ? _(
|
||||
"\u26A0\uFE0F CRITICAL IP LEAK: Your real public IP is exposed through the proxy outbound!"
|
||||
) : _(
|
||||
"\u{1F6E1}\uFE0F SECURE: No IP leak detected. Real WAN IP is concealed behind proxy outbound."
|
||||
);
|
||||
const ipTable = E(
|
||||
"table",
|
||||
{
|
||||
class: "table cbi-section-table",
|
||||
style: "width: 100%; margin-bottom: 12px; font-size: 12px;"
|
||||
},
|
||||
[
|
||||
E("thead", {}, [
|
||||
E("tr", { class: "tr cbi-section-table-titles" }, [
|
||||
E("th", { class: "th" }, _("Connection Path")),
|
||||
E("th", { class: "th" }, _("Observed Public IP")),
|
||||
E("th", { class: "th" }, _("Location")),
|
||||
E("th", { class: "th" }, _("ISP / Organization")),
|
||||
E("th", { class: "th", style: "text-align: center;" }, _("Status"))
|
||||
])
|
||||
]),
|
||||
E("tbody", {}, [
|
||||
E("tr", { class: "tr cbi-section-table-row" }, [
|
||||
E("td", { class: "td" }, [
|
||||
E("b", {}, _("Direct WAN (ISP)")),
|
||||
E(
|
||||
"div",
|
||||
{
|
||||
style: "font-size: 11px; color: var(--text-color-medium, #6c757d);"
|
||||
},
|
||||
_("Bypasses proxy (SO_MARK 0x08000000)")
|
||||
)
|
||||
]),
|
||||
E("td", { class: "td" }, [E("code", {}, ip_leak.direct_ip || "\u2014")]),
|
||||
E(
|
||||
"td",
|
||||
{ class: "td" },
|
||||
[ip_leak.direct_country, ip_leak.direct_city].filter(Boolean).join(", ") || "\u2014"
|
||||
),
|
||||
E("td", { class: "td" }, ip_leak.direct_isp || "\u2014"),
|
||||
E("td", { class: "td", style: "text-align: center;" }, [
|
||||
E(
|
||||
"span",
|
||||
{
|
||||
class: "badge",
|
||||
style: "background: var(--text-color-medium, #6c757d); color: #fff; padding: 2px 6px; border-radius: 4px; font-size: 11px;"
|
||||
},
|
||||
_("Baseline")
|
||||
)
|
||||
])
|
||||
]),
|
||||
E("tr", { class: "tr cbi-section-table-row" }, [
|
||||
E("td", { class: "td" }, [
|
||||
E("b", {}, _("Proxy Outbound")),
|
||||
E(
|
||||
"div",
|
||||
{
|
||||
style: "font-size: 11px; color: var(--text-color-medium, #6c757d);"
|
||||
},
|
||||
_("127.0.0.1:4534 (sing-box mixed)")
|
||||
)
|
||||
]),
|
||||
E("td", { class: "td" }, [E("code", {}, ip_leak.proxy_ip || "\u2014")]),
|
||||
E(
|
||||
"td",
|
||||
{ class: "td" },
|
||||
[ip_leak.proxy_country, ip_leak.proxy_city].filter(Boolean).join(", ") || "\u2014"
|
||||
),
|
||||
E("td", { class: "td" }, ip_leak.proxy_org || "\u2014"),
|
||||
E("td", { class: "td", style: "text-align: center;" }, [
|
||||
!ip_leak.proxy_online ? E(
|
||||
"span",
|
||||
{
|
||||
class: "badge",
|
||||
style: "background: #fd7e14; color: #fff; padding: 2px 6px; border-radius: 4px; font-size: 11px;"
|
||||
},
|
||||
_("OFFLINE")
|
||||
) : ip_leak.leaked ? E(
|
||||
"span",
|
||||
{
|
||||
class: "badge",
|
||||
style: "background: #dc3545; color: #fff; padding: 2px 6px; border-radius: 4px; font-size: 11px;"
|
||||
},
|
||||
_("LEAKED")
|
||||
) : E(
|
||||
"span",
|
||||
{
|
||||
class: "badge",
|
||||
style: "background: #28a745; color: #fff; padding: 2px 6px; border-radius: 4px; font-size: 11px;"
|
||||
},
|
||||
_("SECURE")
|
||||
)
|
||||
])
|
||||
])
|
||||
])
|
||||
]
|
||||
);
|
||||
const ipSection = E(
|
||||
"div",
|
||||
{
|
||||
class: "cbi-section",
|
||||
style: "margin-bottom: 20px; border: 1px solid var(--border-color, rgba(128,128,128,0.2)); border-radius: 6px; padding: 12px;"
|
||||
},
|
||||
[
|
||||
E("h4", { style: "margin-top: 0; margin-bottom: 8px;" }, [
|
||||
"\u{1F310} ",
|
||||
_("Public IP Address Isolation")
|
||||
]),
|
||||
E("div", { class: ipAlertClass, style: "margin-bottom: 12px;" }, [
|
||||
ipAlertText
|
||||
]),
|
||||
ipTable
|
||||
]
|
||||
);
|
||||
const dnsAlertClass = dns_leak.dns_leaked ? "alert-message danger" : dns_leak.dns_servers.length > 0 ? "alert-message success" : "alert-message info";
|
||||
const dnsAlertText = dns_leak.dns_leaked ? _(
|
||||
"\u26A0\uFE0F DNS LEAK DETECTED: DNS queries are leaking to your local Internet Service Provider!"
|
||||
) : dns_leak.dns_servers.length > 0 ? _(
|
||||
"\u{1F6E1}\uFE0F SECURE: No DNS leaks detected. All queries resolve through non-ISP upstream resolvers."
|
||||
) : _(
|
||||
"No DNS resolvers captured via proxy test. Proxy may be offline or blocking test subdomains."
|
||||
);
|
||||
const dnsTableRows = (dns_leak.dns_servers || []).map(
|
||||
(s) => E("tr", { class: "tr cbi-section-table-row" }, [
|
||||
E("td", { class: "td" }, [E("code", {}, s.ip)]),
|
||||
E("td", { class: "td" }, s.country || "\u2014"),
|
||||
E("td", { class: "td" }, s.isp || "\u2014"),
|
||||
E("td", { class: "td", style: "text-align: center;" }, [
|
||||
s.is_isp ? E(
|
||||
"span",
|
||||
{
|
||||
class: "badge",
|
||||
style: "background: #dc3545; color: #fff; padding: 2px 6px; border-radius: 4px; font-size: 11px;"
|
||||
},
|
||||
_("ISP DNS LEAK")
|
||||
) : E(
|
||||
"span",
|
||||
{
|
||||
class: "badge",
|
||||
style: "background: #28a745; color: #fff; padding: 2px 6px; border-radius: 4px; font-size: 11px;"
|
||||
},
|
||||
_("SAFE")
|
||||
)
|
||||
])
|
||||
])
|
||||
);
|
||||
const dnsTable = E(
|
||||
"table",
|
||||
{
|
||||
class: "table cbi-section-table",
|
||||
style: "width: 100%; font-size: 12px; margin-bottom: 12px;"
|
||||
},
|
||||
[
|
||||
E("thead", {}, [
|
||||
E("tr", { class: "tr cbi-section-table-titles" }, [
|
||||
E("th", { class: "th" }, _("Resolver IP")),
|
||||
E("th", { class: "th" }, _("Country")),
|
||||
E("th", { class: "th" }, _("Upstream Provider / ASN")),
|
||||
E(
|
||||
"th",
|
||||
{ class: "th", style: "text-align: center;" },
|
||||
_("Verdict")
|
||||
)
|
||||
])
|
||||
]),
|
||||
E(
|
||||
"tbody",
|
||||
{},
|
||||
dnsTableRows.length > 0 ? dnsTableRows : [
|
||||
E("tr", { class: "tr" }, [
|
||||
E(
|
||||
"td",
|
||||
{
|
||||
class: "td",
|
||||
colSpan: 4,
|
||||
style: "text-align: center; opacity: 0.7;"
|
||||
},
|
||||
_("No DNS resolvers recorded")
|
||||
)
|
||||
])
|
||||
]
|
||||
)
|
||||
]
|
||||
);
|
||||
const dnsSection = E(
|
||||
"div",
|
||||
{
|
||||
class: "cbi-section",
|
||||
style: "border: 1px solid var(--border-color, rgba(128,128,128,0.2)); border-radius: 6px; padding: 12px;"
|
||||
},
|
||||
[
|
||||
E("h4", { style: "margin-top: 0; margin-bottom: 8px;" }, [
|
||||
"\u{1F50D} ",
|
||||
_("DNS Upstream Resolver Analysis (bash.ws protocol)")
|
||||
]),
|
||||
E("div", { class: dnsAlertClass, style: "margin-bottom: 12px;" }, [
|
||||
dnsAlertText
|
||||
]),
|
||||
dnsTable
|
||||
]
|
||||
);
|
||||
resultsContainer.appendChild(ipSection);
|
||||
resultsContainer.appendChild(dnsSection);
|
||||
resultsContainer.style.display = "block";
|
||||
};
|
||||
const retryBtn = renderButton({
|
||||
classNames: ["cbi-button-action"],
|
||||
onClick: startTest,
|
||||
text: `\u{1F504} ${_("Re-run Leak Test")}`
|
||||
});
|
||||
const closeBtn = renderButton({
|
||||
classNames: ["cbi-button"],
|
||||
onClick: () => {
|
||||
if (ui.hideModal) ui.hideModal();
|
||||
},
|
||||
text: _("Close")
|
||||
});
|
||||
const modalContent = E("div", { style: "padding: 8px;" }, [
|
||||
E(
|
||||
"p",
|
||||
{
|
||||
style: "font-size: 13px; color: var(--text-color-medium, #6c757d); margin-bottom: 14px;"
|
||||
},
|
||||
_(
|
||||
"Performs simultaneous outbound checks via direct WAN (bypassing Sing-box redirect) and via proxy (127.0.0.1:4534) to verify that your real IP and DNS queries are not leaking to your ISP."
|
||||
)
|
||||
),
|
||||
statusLabel,
|
||||
progressContainer,
|
||||
resultsContainer,
|
||||
E(
|
||||
"div",
|
||||
{
|
||||
style: "display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px; border-top: 1px solid var(--border-color, rgba(128,128,128,0.2)); padding-top: 12px;"
|
||||
},
|
||||
[retryBtn, closeBtn]
|
||||
)
|
||||
]);
|
||||
ui.showModal(`\u{1F6E1}\uFE0F ${_("Tachyon IP & DNS Leak Detection")}`, modalContent);
|
||||
startTest();
|
||||
}
|
||||
|
||||
// src/helpers/normalizeCompiledVersion.ts
|
||||
function normalizeCompiledVersion(version, commitSha) {
|
||||
if (!version || version.includes("COMPILED")) {
|
||||
@@ -16424,6 +16788,9 @@ async function handleRunAiDoctor() {
|
||||
function handleOpenAiChat() {
|
||||
renderAiChatModal();
|
||||
}
|
||||
function handleOpenLeakCheck() {
|
||||
renderLeakCheckModal();
|
||||
}
|
||||
function handleOpenStrategyFuzzer() {
|
||||
getConfigSections().then((sections) => {
|
||||
const ruleNames = sections.filter((s) => s[".type"] === "section" || s[".type"] === "rule").map((s) => s.name || s[".name"]).filter((n) => Boolean(n));
|
||||
@@ -16711,6 +17078,12 @@ function renderDiagnosticAvailableActionsWidget() {
|
||||
disabled: utilityActionsDisabled,
|
||||
onClick: handleCheckServicesAction
|
||||
},
|
||||
testLeaks: {
|
||||
visible: true,
|
||||
loading: false,
|
||||
disabled: false,
|
||||
onClick: handleOpenLeakCheck
|
||||
},
|
||||
viewLogs: {
|
||||
loading: diagnosticsActions.viewLogs.loading,
|
||||
visible: true,
|
||||
|
||||
@@ -7,8 +7,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: TACHYON\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-09-08 09:57+0300\n"
|
||||
"PO-Revision-Date: 2026-09-08 09:57+0300\n"
|
||||
"POT-Creation-Date: 2026-09-09 17:09+0300\n"
|
||||
"PO-Revision-Date: 2026-09-09 17:09+0300\n"
|
||||
"Last-Translator: Dushnilin\n"
|
||||
"Language-Team: none\n"
|
||||
"Language: ru\n"
|
||||
@@ -50,6 +50,12 @@ msgstr "⚠️ Бенчмарк завершен. Не найдено рабоч
|
||||
msgid "⚠️ Benchmark stopped"
|
||||
msgstr "⚠️ Бенчмарк остановлен"
|
||||
|
||||
msgid "⚠️ CRITICAL IP LEAK: Your real public IP is exposed through the proxy outbound!"
|
||||
msgstr "⚠️ КРИТИЧЕСКАЯ УТЕЧКА IP: Ваш реальный публичный IP раскрыт через исходящий прокси!"
|
||||
|
||||
msgid "⚠️ DNS LEAK DETECTED: DNS queries are leaking to your local Internet Service Provider!"
|
||||
msgstr "⚠️ ОБНАРУЖЕНА УТЕЧКА DNS: DNS-запросы утекают к вашему местному интернет-провайдеру!"
|
||||
|
||||
msgid "⚠️ If all Bootstrap DNS fail 3 times, queries will be sent to your ISP's DNS in plaintext. Only use as a last resort to prevent complete internet loss."
|
||||
msgstr "⚠️ Если все Bootstrap DNS завершатся с ошибкой 3 раза, запросы будут отправлены в DNS вашего провайдера в открытом виде. Используйте только в крайнем случае для предотвращения полной потери интернета."
|
||||
|
||||
@@ -155,9 +161,21 @@ msgstr "🛑 Остановить бенчмарк"
|
||||
msgid "🛠️ My Custom Strategies Only"
|
||||
msgstr "🛠️ Только мои стратегии"
|
||||
|
||||
msgid "🛡️ IP & DNS Leak Test"
|
||||
msgstr "🛡️ Проверка утечек IP и DNS"
|
||||
|
||||
msgid "🛡️ SECURE: No DNS leaks detected. All queries resolve through non-ISP upstream resolvers."
|
||||
msgstr "🛡️ ЗАЩИЩЕНО: Утечек DNS не обнаружено. Все запросы обрабатываются независимыми резолверами."
|
||||
|
||||
msgid "🛡️ SECURE: No IP leak detected. Real WAN IP is concealed behind proxy outbound."
|
||||
msgstr "🛡️ ЗАЩИЩЕНО: Утечек IP не обнаружено. Реальный WAN IP скрыт за исходящим прокси."
|
||||
|
||||
msgid "🟣 Twitch Suite (Live Stream + HLS CDN)"
|
||||
msgstr "🟣 Twitch Набор (Прямой эфир + HLS CDN)"
|
||||
|
||||
msgid "127.0.0.1:4534 (sing-box mixed)"
|
||||
msgstr "127.0.0.1:4534 (смешанный sing-box)"
|
||||
|
||||
msgid "Блокировка по IP (Таймаут TCP SYN)"
|
||||
msgstr "Блокировка по IP (Таймаут TCP SYN)"
|
||||
|
||||
@@ -485,6 +503,9 @@ msgstr "Генератор AmneziaWG"
|
||||
msgid "AmneziaWG Version"
|
||||
msgstr "Версия AmneziaWG"
|
||||
|
||||
msgid "An unexpected error occurred during test"
|
||||
msgstr "Произошла непредвиденная ошибка во время проверки"
|
||||
|
||||
msgid "Anonymized support report copied to clipboard"
|
||||
msgstr "Анонимизированный отчет скопирован в буфер обмена"
|
||||
|
||||
@@ -641,6 +662,9 @@ msgstr "Ср. задержка"
|
||||
msgid "Backend validation failed: %s"
|
||||
msgstr "Ошибка проверки бэкенда: %s"
|
||||
|
||||
msgid "Baseline"
|
||||
msgstr "Базовый уровень"
|
||||
|
||||
msgid "Basic connectivity"
|
||||
msgstr "Базовая связность"
|
||||
|
||||
@@ -791,6 +815,9 @@ msgstr "Стратегия ByeDPI"
|
||||
msgid "ByeDPI strategy cannot be empty"
|
||||
msgstr "Стратегия ByeDPI не может быть пустой"
|
||||
|
||||
msgid "Bypasses proxy (SO_MARK 0x08000000)"
|
||||
msgstr "В обход прокси (SO_MARK 0x08000000)"
|
||||
|
||||
msgid "Bypasses UDP traffic for selected game consoles (PS5/Xbox) to achieve NAT Type 1 / 2 (Full Cone NAT) for P2P matchmaking, while keeping TCP (PSN/Auth) routed through the proxy."
|
||||
msgstr "Обходит UDP-трафик для выбранных игровых консолей (PS5/Xbox) для достижения NAT Type 1 / 2 (Full Cone NAT) для P2P-матчмейкинга, сохраняя TCP (PSN/Auth) через прокси."
|
||||
|
||||
@@ -1055,6 +1082,9 @@ msgstr "Подключено"
|
||||
msgid "Connected Devices"
|
||||
msgstr "Подключенные устройства"
|
||||
|
||||
msgid "Connection Path"
|
||||
msgstr "Маршрут соединения"
|
||||
|
||||
msgid "Connection URL"
|
||||
msgstr "URL подключения"
|
||||
|
||||
@@ -1100,6 +1130,12 @@ msgstr "Основные настройки и параметры"
|
||||
msgid "Could not compare FakeIP and control public IPs"
|
||||
msgstr "Не удалось сравнить публичные IP FakeIP и контрольной проверки"
|
||||
|
||||
msgid "Could not contact leak test endpoints. Please ensure router has internet access."
|
||||
msgstr "Не удалось связаться с серверами проверки утечек. Убедитесь, что у роутера есть доступ в интернет."
|
||||
|
||||
msgid "Country"
|
||||
msgstr "Страна"
|
||||
|
||||
msgid "Country code (e.g. ru, us, de)"
|
||||
msgstr "Код страны (напр. ru, us, de)"
|
||||
|
||||
@@ -1271,6 +1307,9 @@ msgstr "Прямой прокси"
|
||||
msgid "Direct WAN"
|
||||
msgstr "Прямой WAN"
|
||||
|
||||
msgid "Direct WAN (ISP)"
|
||||
msgstr "Напрямую в WAN (провайдер)"
|
||||
|
||||
msgid "Disable"
|
||||
msgstr "Отключить"
|
||||
|
||||
@@ -1382,6 +1421,9 @@ msgstr "Быстрый DNS-кэш"
|
||||
msgid "DNS Unavailability Timeout"
|
||||
msgstr "Таймаут недоступности DNS"
|
||||
|
||||
msgid "DNS Upstream Resolver Analysis (bash.ws protocol)"
|
||||
msgstr "Анализ восходящих DNS-резолверов (протокол bash.ws)"
|
||||
|
||||
msgid "Do not panic, everything can be fixed, just..."
|
||||
msgstr "Не паникуйте, всё можно исправить, просто..."
|
||||
|
||||
@@ -1524,7 +1566,7 @@ msgid "e.g. SHA256 — leave empty for default"
|
||||
msgstr "напр. SHA256 — оставьте пустым для значения по умолчанию"
|
||||
|
||||
msgid "Each entry must be \"proto\", \"proto:port\" or \"proto:port-port\" (tcp/udp), e.g. tcp:6881,udp:6881-6889"
|
||||
msgstr "Каждая запись — \"proto\", \"proto:port\" или \"proto:port-port\" (tcp/udp), напр. tcp:6881,udp:6881-6889"
|
||||
msgstr "Каждая запись должна быть \"proto\", \"proto:port\" или \"proto:port-port\" (tcp/udp), например: tcp:6881,udp:6881-6889"
|
||||
|
||||
msgid "Edit"
|
||||
msgstr "Изменить"
|
||||
@@ -1802,6 +1844,9 @@ msgstr "Не удалось определить тип DPI"
|
||||
msgid "Failed to execute"
|
||||
msgstr "Не удалось выполнить"
|
||||
|
||||
msgid "Failed to execute IP and DNS leak check"
|
||||
msgstr "Не удалось выполнить проверку утечек IP и DNS"
|
||||
|
||||
msgid "Failed to fetch releases"
|
||||
msgstr "Не удалось получить список релизов"
|
||||
|
||||
@@ -2348,6 +2393,9 @@ msgstr "Полезный груз init (I1)"
|
||||
msgid "Init timeout (Itime)"
|
||||
msgstr "Таймаут init (Itime)"
|
||||
|
||||
msgid "Initializing router-level IP & DNS leak test..."
|
||||
msgstr "Инициализация проверки утечек IP и DNS с роутера..."
|
||||
|
||||
msgid "Install"
|
||||
msgstr "Установить"
|
||||
|
||||
@@ -2517,7 +2565,7 @@ msgid "Invalid Shadowsocks URL: missing credentials"
|
||||
msgstr "Неверный URL Shadowsocks: отсутствуют учетные данные"
|
||||
|
||||
msgid "Invalid Shadowsocks URL: missing method and password separator \":\""
|
||||
msgstr "Неверный Shadowsocks URL: отсутствует разделитель метода и пароля \":\""
|
||||
msgstr "Неверный URL Shadowsocks: отсутствует разделитель метода и пароля \":\""
|
||||
|
||||
msgid "Invalid Shadowsocks URL: missing port"
|
||||
msgstr "Неверный URL Shadowsocks: отсутствует порт"
|
||||
@@ -2660,6 +2708,12 @@ msgstr "Изолировать трафик BitTorrent и направить е
|
||||
msgid "Isolate Local LAN"
|
||||
msgstr "Изолировать локальную сеть"
|
||||
|
||||
msgid "ISP / Organization"
|
||||
msgstr "Провайдер / Организация"
|
||||
|
||||
msgid "ISP DNS LEAK"
|
||||
msgstr "УТЕЧКА DNS К ПРОВАЙДЕРУ"
|
||||
|
||||
msgid "Issues"
|
||||
msgstr "Проблемы"
|
||||
|
||||
@@ -2780,6 +2834,15 @@ msgstr "Установлена последняя версия"
|
||||
msgid "Latest version:"
|
||||
msgstr "Последняя версия:"
|
||||
|
||||
msgid "Leak detection completed"
|
||||
msgstr "Проверка утечек завершена"
|
||||
|
||||
msgid "Leak detection failed to complete"
|
||||
msgstr "Не удалось завершить проверку утечек"
|
||||
|
||||
msgid "LEAKED"
|
||||
msgstr "УТЕЧКА"
|
||||
|
||||
msgid "Leave empty to omit this header"
|
||||
msgstr "Оставьте пустым, чтобы пропустить этот заголовок"
|
||||
|
||||
@@ -2858,6 +2921,9 @@ msgstr "Загрузка..."
|
||||
msgid "Local Address"
|
||||
msgstr "Локальный адрес"
|
||||
|
||||
msgid "Location"
|
||||
msgstr "Местоположение"
|
||||
|
||||
msgid "Log Level"
|
||||
msgstr "Уровень логирования"
|
||||
|
||||
@@ -3078,13 +3144,13 @@ msgid "No active routing sections found."
|
||||
msgstr "Активные секции маршрутизации не найдены."
|
||||
|
||||
msgid "No benchmark data yet. Click \"Start Benchmark\" to begin."
|
||||
msgstr "Нет данных бенчмарка. Нажмите «Начать тест», чтобы запустить проверку."
|
||||
msgstr "Данные тестирования отсутствуют. Нажмите \"Запустить тест\" для начала."
|
||||
|
||||
msgid "No benchmark history yet. Run a benchmark to see results here."
|
||||
msgstr "История бенчмарков пуста. Запустите бенчмарк, чтобы увидеть результаты здесь."
|
||||
|
||||
msgid "No benchmark results yet. Configure options and click \"Start Benchmark\"."
|
||||
msgstr "Результатов бенчмарка пока нет. Настройте параметры и нажмите «Запустить бенчмарк»."
|
||||
msgstr "Результаты тестирования пока отсутствуют. Настройте параметры и нажмите \"Запустить тест\"."
|
||||
|
||||
msgid "No check targets found in the configuration."
|
||||
msgstr "Цели для проверки не найдены в конфигурации."
|
||||
@@ -3113,6 +3179,12 @@ msgstr "DHCP-клиенты не обнаружены"
|
||||
msgid "No diagnostic history available yet."
|
||||
msgstr "История проверок пока пуста."
|
||||
|
||||
msgid "No DNS resolvers captured via proxy test. Proxy may be offline or blocking test subdomains."
|
||||
msgstr "В тесте через прокси резолверы не зафиксированы. Возможно, прокси не работает или блокирует тестовые поддомены."
|
||||
|
||||
msgid "No DNS resolvers recorded"
|
||||
msgstr "DNS-резолверы не зафиксированы"
|
||||
|
||||
msgid "No domains detected yet"
|
||||
msgstr "Домены пока не обнаружены"
|
||||
|
||||
@@ -3242,6 +3314,12 @@ msgstr "Обфускация"
|
||||
msgid "Obfuscation password"
|
||||
msgstr "Пароль обфускации"
|
||||
|
||||
msgid "Observed Public IP"
|
||||
msgstr "Внешний публичный IP"
|
||||
|
||||
msgid "OFFLINE"
|
||||
msgstr "ОФЛАЙН"
|
||||
|
||||
msgid "Ollama (Local PC / Server)"
|
||||
msgstr "Ollama (локальный ПК / сервер)"
|
||||
|
||||
@@ -3312,13 +3390,13 @@ msgid "Optimize RAM memory"
|
||||
msgstr "Оптимизировать память (RAM)"
|
||||
|
||||
msgid "Option \"%s\" contains an invalid input value."
|
||||
msgstr "Параметр \"%s\" содержит недопустимое значение."
|
||||
msgstr "Опция \"%s\" содержит недопустимое значение."
|
||||
|
||||
msgid "Optional — leave empty for default"
|
||||
msgstr "Опционально — оставьте пустым для значения по умолчанию"
|
||||
|
||||
msgid "Optional context (e.g. \"Rostelecom, YouTube 4K buffering is slow\")..."
|
||||
msgstr "Дополнительный контекст (напр. «Ростелеком, YouTube 4K долго буферизуется»)..."
|
||||
msgstr "Дополнительный контекст (напр. \"Ростелеком, долго грузится YouTube 4K\")..."
|
||||
|
||||
msgid "Optional tls-auth or tls-crypt key"
|
||||
msgstr "Опциональный ключ tls-auth или tls-crypt"
|
||||
@@ -3440,6 +3518,9 @@ msgstr "Ожидает запуска"
|
||||
msgid "Pending..."
|
||||
msgstr "Ожидание..."
|
||||
|
||||
msgid "Performs simultaneous outbound checks via direct WAN (bypassing Sing-box redirect) and via proxy (127.0.0.1:4534) to verify that your real IP and DNS queries are not leaking to your ISP."
|
||||
msgstr "Выполняет одновременные исходящие запросы напрямую в WAN (в обход правил Sing-box) и через прокси (127.0.0.1:4534), проверяя, что ваш реальный IP и DNS-запросы не утекают провайдеру."
|
||||
|
||||
msgid "Periodically check the current level and switch to a faster server even when the current one works."
|
||||
msgstr "Периодически проверять текущий уровень и переключаться на более быстрый сервер, даже если текущий работает."
|
||||
|
||||
@@ -3462,7 +3543,7 @@ msgid "Pin on dashboard"
|
||||
msgstr "Закрепить на дашборде"
|
||||
|
||||
msgid "Pin P2P isolation to the torrent client's own ports, comma separated. Each entry is \"proto\", \"proto:port\" or \"proto:port-port\" (tcp/udp). Without a port the whole protocol is routed direct."
|
||||
msgstr "Закрепить изоляцию P2P за портами торрент-клиента, через запятую. Каждая запись — \"протокол\", \"протокол:порт\" или \"протокол:порт-порт\" (tcp/udp). Без порта весь протокол уходит напрямую."
|
||||
msgstr "Привязка изоляции P2P к портам торрент-клиента через запятую. Каждая запись: \"proto\", \"proto:port\" или \"proto:port-port\" (tcp/udp). Без указания порта весь протокол направляется напрямую."
|
||||
|
||||
msgid "Plain-UDP DNS servers used as a last resort when all primary DNS fail. These are always unencrypted (no DoH/DoT). Example: 1.1.1.1, 8.8.8.8. Unlike the ISP fallback toggle, these are your own chosen servers."
|
||||
msgstr "Обычные UDP DNS-серверы, используемые как резерв при недоступности всех основных DNS. Всегда работают без шифрования (без DoH/DoT). Пример: 1.1.1.1, 8.8.8.8. В отличие от аварийного DNS провайдера, это выбранные вами серверы."
|
||||
@@ -3620,9 +3701,15 @@ msgstr "Интервал проверки здоровья прокси (с)"
|
||||
msgid "Proxy Health Check URL"
|
||||
msgstr "URL проверки здоровья прокси"
|
||||
|
||||
msgid "Proxy is offline or unreachable on 127.0.0.1:4534."
|
||||
msgstr "Прокси выключен или недоступен на 127.0.0.1:4534."
|
||||
|
||||
msgid "Proxy link is unavailable"
|
||||
msgstr "Ссылка прокси недоступна"
|
||||
|
||||
msgid "Proxy Outbound"
|
||||
msgstr "Исходящий прокси (туннель)"
|
||||
|
||||
msgid "Proxy Section for Bot"
|
||||
msgstr "Секция прокси для бота"
|
||||
|
||||
@@ -3635,9 +3722,15 @@ msgstr "PSK"
|
||||
msgid "Public host"
|
||||
msgstr "Публичный хост"
|
||||
|
||||
msgid "Public IP Address Isolation"
|
||||
msgstr "Изоляция публичного IP-адреса"
|
||||
|
||||
msgid "QR code is too large"
|
||||
msgstr "QR-код слишком большой"
|
||||
|
||||
msgid "Querying WAN direct socket and proxy outbound on 127.0.0.1:4534..."
|
||||
msgstr "Опрос прямого WAN-сокета и исходящего прокси на 127.0.0.1:4534..."
|
||||
|
||||
msgid "QUIC (HTTP/3)"
|
||||
msgstr "QUIC (HTTP/3)"
|
||||
|
||||
@@ -3653,6 +3746,9 @@ msgstr "Оценка"
|
||||
msgid "RDP"
|
||||
msgstr "RDP"
|
||||
|
||||
msgid "Re-run Leak Test"
|
||||
msgstr "Повторить проверку утечек"
|
||||
|
||||
msgid "Read error"
|
||||
msgstr "Ошибка чтения"
|
||||
|
||||
@@ -3791,6 +3887,9 @@ msgstr "Определить шлюз"
|
||||
msgid "Resolve real IP for routing"
|
||||
msgstr "Разрешать реальный IP для маршрутизации"
|
||||
|
||||
msgid "Resolver IP"
|
||||
msgstr "IP резолвера"
|
||||
|
||||
msgid "Resource selection by hostname inside nfqws is not supported here; sing-box selects resources before NFQUEUE."
|
||||
msgstr "Выбор ресурсов по имени хоста внутри nfqws не поддерживается здесь; sing-box выбирает ресурсы до NFQUEUE."
|
||||
|
||||
@@ -3884,6 +3983,12 @@ msgstr "Направлять весь не-локальный LAN-трафик
|
||||
msgid "Route bot API requests through this section. Leave empty to use the default mixed proxy."
|
||||
msgstr "Маршрутизировать запросы API бота через эту секцию. Оставьте пустым для использования смешанного прокси по умолчанию."
|
||||
|
||||
msgid "Route community list subnets (IP/CIDR)"
|
||||
msgstr "Маршрутизировать подсети списков сообщества (IP/CIDR)"
|
||||
|
||||
msgid "Route IP subnets associated with built-in community lists (e.g. Discord voice/media). Disable this if community subnets overlap with CDN/Anycast networks (such as Cloudflare/Google Cloud) and interfere with unrelated services (e.g. game launchers)."
|
||||
msgstr "Маршрутизировать IP-подсети из списков сообщества (например, голос/медиа Discord). Отключите, если подсети сообщества пересекаются с CDN/Anycast сетями (Cloudflare/Google Cloud) и мешают другим сервисам."
|
||||
|
||||
msgid "Route main DNS requests through the selected section."
|
||||
msgstr "Маршрутизировать основные DNS-запросы через выбранную секцию."
|
||||
|
||||
@@ -3971,6 +4076,9 @@ msgstr "Выполняется диагностика…"
|
||||
msgid "Russia (ru)"
|
||||
msgstr "Россия (ru)"
|
||||
|
||||
msgid "SAFE"
|
||||
msgstr "БЕЗОПАСНО"
|
||||
|
||||
msgid "SafeSearch"
|
||||
msgstr "SafeSearch"
|
||||
|
||||
@@ -4040,6 +4148,9 @@ msgstr "Секция для регистрации Cloudflare WARP API. Если
|
||||
msgid "Sections"
|
||||
msgstr "Секции"
|
||||
|
||||
msgid "SECURE"
|
||||
msgstr "ЗАЩИЩЕНО"
|
||||
|
||||
msgid "Security"
|
||||
msgstr "Безопасность"
|
||||
|
||||
@@ -4625,6 +4736,9 @@ msgstr "Tachyon: Бенчмарк и автоподбор DNS"
|
||||
msgid "Tachyon Error"
|
||||
msgstr "Ошибка Tachyon"
|
||||
|
||||
msgid "Tachyon IP & DNS Leak Detection"
|
||||
msgstr "Проверка утечек IP и DNS Tachyon"
|
||||
|
||||
msgid "Tachyon manages ciadpi pid files itself, so pidfile options are not allowed here."
|
||||
msgstr "Tachyon управляет файлами pid ciadpi самостоятельно, поэтому параметры pidfile здесь не допускаются."
|
||||
|
||||
@@ -4769,6 +4883,9 @@ msgstr "Тестирование"
|
||||
msgid "Testing bypass strategies in isolated sandbox..."
|
||||
msgstr "Тестирование стратегий обхода в изолированной песочнице..."
|
||||
|
||||
msgid "Testing DNS leak upstream resolvers with bash.ws protocol..."
|
||||
msgstr "Тестирование восходящих DNS-резолверов по протоколу bash.ws..."
|
||||
|
||||
msgid "Testing strategy"
|
||||
msgstr "Тестирование стратегии"
|
||||
|
||||
@@ -5156,6 +5273,9 @@ msgstr "Отдано"
|
||||
msgid "Upstream Mode"
|
||||
msgstr "Режим DNS Upstream"
|
||||
|
||||
msgid "Upstream Provider / ASN"
|
||||
msgstr "Восходящий провайдер / ASN"
|
||||
|
||||
msgid "URL must start with vless://, vmess://, ss://, trojan://, socks4://, socks4a://, socks5://, http://, https://, hysteria2://, hy2://, or tuic://"
|
||||
msgstr "URL должен начинаться с vless://, vmess://, ss://, trojan://, socks4://, socks4a://, socks5://, http://, https://, hysteria2://, hy2:// или tuic://"
|
||||
|
||||
@@ -5273,6 +5393,9 @@ msgstr "Значение должно быть положительным цел
|
||||
msgid "Value must not contain control characters"
|
||||
msgstr "Значение не должно содержать символы управления"
|
||||
|
||||
msgid "Verdict"
|
||||
msgstr "Статус"
|
||||
|
||||
msgid "Verifying router and service readiness..."
|
||||
msgstr "Проверка готовности роутера и служб..."
|
||||
|
||||
@@ -5837,9 +5960,6 @@ msgstr "Маршрут"
|
||||
msgid "Resolved IP / DNS"
|
||||
msgstr "IP / DNS"
|
||||
|
||||
msgid "Verdict"
|
||||
msgstr "Статус"
|
||||
|
||||
msgid "Check domain or IP (e.g. example.com)..."
|
||||
msgstr "Проверить домен или IP (напр. example.com)..."
|
||||
|
||||
|
||||
+2149
-1942
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user