feat(doctor): честный вердикт по мёртвым WireGuard/AWG-туннелям

Жалобы вида «AWG не работает» (#39, #42) почти всегда означают: конфиг
секции применён корректно, но пир не отвечает (сервер лежит, провайдер
режет UDP до эндпоинта). Раньше доктор об этом молчал, и виноватым
выглядел Tachyon.

Новый чек 6c сканирует свежий лог ядра на ошибки outbound/wireguard
(operation timed out / handshake timeout): при свидетельствах мёртвого
туннеля - явный вердикт «проблема вне Tachyon» с подсказкой проверить
сервер и UDP-порт у провайдера. Если wireguard-трафика в логе нет вовсе,
чек не выдаёт ни одной строки - без шума для пользователей без AWG.
This commit is contained in:
Dushnilin
2026-08-22 10:46:36 +03:00
parent 44016ec95b
commit 0241e1898f
2 changed files with 50 additions and 0 deletions
@@ -2777,6 +2777,25 @@ function run_doctor_checks_impl(repair) {
} }
} }
// 6c. WireGuard/AWG tunnel health from recent core logs. A userspace
// wireguard outbound whose peer never answers produces a steady stream
// of "operation timed out" connection errors - the config is applied
// correctly, the failure is outside Tachyon (server down, ISP filtering
// the UDP endpoint). Surfacing this as its own check stops the classic
// "Tachyon broke my AWG" misattribution.
if (pid != "") {
let wg_log = lc(command_capture("logread -l 400 2>/dev/null | grep -i 'outbound/wireguard' | tail -n 8").output);
let wg_failures = index(wg_log, "operation timed out") >= 0 ||
(index(wg_log, "handshake") >= 0 && index(wg_log, "timeout") >= 0);
if (wg_log != "" && wg_failures) {
issues++;
doc_check("⚠️", "WireGuard/AWG tunnel", "peer not answering through core",
"→ ядро не получает ответов от пира (запросы уходят, ответы нет): проверьте доступность AWG/WARP-сервера и UDP-порта у провайдера. Конфигурация секции применена корректно — проблема вне Tachyon");
} else if (wg_log != "") {
doc_check("✅", "WireGuard/AWG tunnel", "no recent failures in core log", "");
}
}
// 7. Free RAM Check // 7. Free RAM Check
let free_mb = -1; let free_mb = -1;
let mem_info = fs.readfile("/proc/meminfo") || ""; let mem_info = fs.readfile("/proc/meminfo") || "";
+31
View File
@@ -0,0 +1,31 @@
#!/usr/bin/env bash
set -eo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
RT="$ROOT_DIR/tachyon/files/usr/lib/diagnostics/runtime.uc"
fail() {
printf 'FAIL: %s\n' "$1" >&2
exit 1
}
[ -f "$RT" ] || fail "runtime.uc not found"
# Doctor must attribute dead WireGuard/AWG tunnels to the outside world based
# on core log evidence, instead of leaving users to blame Tachyon for a peer
# that never answers (issues #39/#42 complaint pattern).
grep -Fq 'outbound/wireguard' "$RT" ||
fail "doctor must scan core logs for wireguard outbound failures"
grep -Fq '"WireGuard/AWG tunnel"' "$RT" ||
fail "doctor must report a dedicated WireGuard/AWG tunnel check"
grep -Fq 'проблема вне Tachyon' "$RT" ||
fail "the verdict must state the failure is outside Tachyon"
# The check only speaks when there is evidence: no wireguard lines in the
# core log means no check line at all (no noise for non-AWG users).
grep -Fq 'if (wg_log != "" && wg_failures) {' "$RT" ||
fail "failure verdict must require actual log evidence"
grep -Fq '} else if (wg_log != "") {' "$RT" ||
fail "success line must be skipped entirely when no wireguard traffic exists"
printf 'doctor wireguard tunnel checks passed\n'