Версия 0.5.3
CI / Линт и типы (push) Canceled after 0s
CI / Сборка (Windows) (push) Canceled after 0s
CI / Сборка (Linux) (push) Canceled after 0s

Добавлена сборка под Linux: nfqws + правила nftables (NFQUEUE) вместо
socks-прокси или службы Windows. Повышение прав — pkexec на каждое
включение/выключение, без службы и без автозапуска.

Стратегии переиспользуют существующий набор Flowseal (strategies.win32.generated.ts):
--wf-tcp/--wf-udp уходят в правила nftables, остальное — в nfqws как есть.
Все правила nftables держат bypass, поэтому упавший или выключенный демон
не рвёт пользователю сеть.

Помощник (resources/linux-helper/rknboost-helper.sh) и бинарник nfqws перед
каждым запуском копируются в userData: root не может прочитать файлы внутри
AppImage (FUSE-примонтирован без allow_other), а обычная файловая система
на диске ему доступна независимо от прав.

Заодно:
- починен баг генератора стратегий (^! не разэкранировался в !, ломало
  fake-tls-auto и на Windows тоже);
- карточка обхода теперь показывает текст ошибки независимо от state;
- счётчик auto-hostlist в настройках больше не привязан к !isWindows;
- CI: отдельная джоба сборки под Linux на ubuntu-latest.
This commit is contained in:
2026-09-04 10:26:00 +03:00
parent 0842c4d4a5
commit 2df1c00516
20 changed files with 956 additions and 78 deletions
+43
View File
@@ -0,0 +1,43 @@
import { access, constants } from 'node:fs/promises'
/**
* `pkexec` из состава polkit — им поднимаем root для nftables/nfqws. Проверяем по конкретным
* путям, а не через `PATH`: тот же мотив, что у `find_nft()` в `rknboost-helper.sh` — санитайз
* окружения инструментами вроде pkexec/env-с-урезанным-PATH встречается достаточно часто,
* чтобы не полагаться на переменную окружения при поиске самого пути к элевации.
*/
const PKEXEC_CANDIDATES = ['/usr/bin/pkexec', '/bin/pkexec']
/** `nft` — тот же список путей, что перебирает `find_nft()` в помощнике (держим в синхроне). */
const NFT_CANDIDATES = ['/usr/sbin/nft', '/sbin/nft', '/usr/local/sbin/nft', '/usr/bin/nft']
async function findExecutable(candidates: readonly string[]): Promise<string | null> {
for (const candidate of candidates) {
try {
await access(candidate, constants.X_OK)
return candidate
} catch {
// пробуем следующий путь
}
}
return null
}
/**
* Проверка окружения до первого запроса пароля — тот же мотив, что у `assertExecutable()`
* в `paths.ts`: без неё пользователь увидел бы «spawn pkexec ENOENT» или пустой отказ nft
* внутри чужого stderr и не понял бы, что установить.
*/
export async function assertLinuxDependencies(): Promise<void> {
if (!(await findExecutable(PKEXEC_CANDIDATES))) {
throw new Error(
'Не найден pkexec — установите пакет polkit ' +
'(Debian/Ubuntu: «sudo apt install policykit-1»).'
)
}
if (!(await findExecutable(NFT_CANDIDATES))) {
throw new Error(
'Не найдена утилита nft — установите пакет nftables (Debian/Ubuntu: «sudo apt install nftables»).'
)
}
}