НазадДобавить комментарий
Linux: kill switch не снимается после отключения — isEngaged() вызывает iptables без root
БагГотовоКритичноПубличныйDesktop
Автор: u**********@g***.com
Продукт: Приложение INCY
Создан: 02.11.2026, 12:55:18
Версия приложения: 3.9.0 (incy-linux-x64.pkg.tar.zst)
Версия ОС: CachyOS (Arch Linux) x64, ядро 7.2, iptables 1.8.13 (nf_tables), polkit 128
Шаги:
1. Включить Kill Switch в настройках, режим TUN.
2. Подключиться. В логе: [LinuxKillSw] Kill switch engaged (server=…, lan=true, dns=2), в iptables появляется цепочка INCY_KILLSWITCH.
3. Отключиться (или выйти из приложения).
4. sudo iptables -S | grep INCY
Ожидаемый результат:
после отключения и после выхода из приложения цепочка INCY_KILLSWITCH и переход -A OUTPUT -j INCY_KILLSWITCH удалены.
Фактический результат:
цепочка остаётся до перезагрузки. Весь трафик, кроме LAN, сервера и DNS 1.1.1.1/8.8.8.8, получает REJECT --reject-with icmp-admin-prohibited: после отключения INCY интернета нет, другие VPN-клиенты тоже не подключаются. В логах при каждом подключении есть «Kill switch engaged» и нет ни одного «Kill switch released» или «release failed».
Причина (по байткоду 3.9.0, номера строк из LineNumberTable):
LinuxKillSwitch.isEngaged() (LinuxKillSwitch.kt:123–124) запускает iptables -nL INCY_KILLSWITCH через ProcessBuilder напрямую, без pkexec. От обычного пользователя iptables всегда завершается с кодом 4 («Could not fetch rule set generation id: Permission denied (you must be root)»), поэтому isEngaged() всегда возвращает false. А все вызовы release() стоят за проверкой isEngaged():
- VpnServiceManager.kt:629 — cleanupConnection (отключение);
- VpnServiceManager.kt:664 — синхронная остановка при выходе (вызывается из Main.kt:473 и Main.kt:563);
- VpnServiceManager.kt:379–380 и 560 — откат при ошибке подключения;
- KillSwitchRecovery.kt:5–7 — reset() считает, что снимать нечего.
Единственный вызов release() без проверки — LinuxKillSwitch.kt:93, внутри engage() при ошибке.
Предлагаемое исправление, два варианта:
Вариант 1 — флаг состояния в памяти:
@Volatile private var engaged = false
// engage(): после успешного runPkexec(buildEngageScript(...))
engaged = true
// release(): после runPkexec(buildReleaseScript())
engaged = false
override fun isEngaged(): Boolean = engaged
Минус: после падения или kill -9 приложения флаг теряется, и KillSwitchRecovery при следующем запуске не увидит оставшиеся правила. Для recovery всё равно нужна проверка в ядре, то есть вариант 2 (или оба: флаг в обычной работе, проверка с правами при старте).
Вариант 2 — проверять через тот же runPkexec:
override fun isEngaged(): Boolean {
if (!Platform.isLinux) return false
return runPkexec("iptables -w -S INCY_KILLSWITCH >/dev/null 2>&1").exitCode == 0
}
Минус: ещё один вызов pkexec. runPkexec запускает pkexec sh -c "...", а это общий action org.freedesktop.policykit.exec, не cc.incy.vpn.run-helper из cc.incy.vpn.policy, поэтому кэш auth_admin_keep на него не действует. Удобнее добавить в incy-helper-linux.sh подкоманды killswitch-engage / killswitch-release / killswitch-status и вызывать их как остальные — тогда хватит одного запроса пароля на сессию.
Временное решение:
sudo iptables -D OUTPUT -j INCY_KILLSWITCH; sudo iptables -F INCY_KILLSWITCH; sudo iptables -X INCY_KILLSWITCH
или выключить Kill Switch в настройках.Комментарии (1)
Команда INCYadmin04.11.2026, 22:56:22
будет ретег 2.9.0 там будет исправлено