Always-on и kill switch стоят в двух строках друг от друга на одном экране настроек, поэтому люди читают их как два названия одной функции. Это не так. Always-on — это политика переподключения: запускать туннель при загрузке, возвращать его после сбоя или смены сети и продолжать попытки, пока он не поднимется. Kill switch — это политика трафика: он называет пакеты, которым всё ещё разрешено покидать машину, пока туннель лежит. Первое можно включить без второго, и на большинстве платформ результат по умолчанию всё равно выпускает трафик в этот промежуток.

Проверка 1: блокировка — это отдельный переключатель?

На Android 10 и новее сохранённый профиль VPN открывает за значком шестерёнки два независимых переключателя: Always-on VPN и Block connections without VPN. Только второй и есть kill switch. При одном always-on туннель действительно возвращается после обрыва, а любое приложение посреди запроса может выйти в сеть через Wi-Fi или мобильные данные, пока это не произойдёт.

Управляемые устройства сохраняют то же разделение в API политик. setAlwaysOnVpnPackage() принимает имя пакета и флаг lockdownEnabled; администратор, который задал пакет и оставил флаг false, построил постоянный туннель, а не закрытое устройство. Формулировки в консоли редко делают эту разницу заметной.

Читайте состояние с устройства, а не из консоли: adb shell settings get global always_on_vpn_app и adb shell settings get global always_on_vpn_lockdown. Если первая возвращает null, на уровне платформы не навязан ни один пакет; если вторая возвращает 0, платформа ничего не блокирует. Руководство по VPN для Android описывает это как отдельные возможности, а не один режим.

Проверка 2: какой слой владеет блокировкой?

Надписи живут в клиенте, а блокировки обычно в межсетевом экране, поэтому одно и то же слово на каждой платформе значит разное. Строки ниже стоит подтвердить, прежде чем доверять любой из них.

Where you see the labelWhat the label promisesWhat actually blocks
Android VPN profileAlways-on VPNBlock connections without VPN
Android device policyAlways-on packagelockdownEnabled flag
Windows built-in VPNAlways On tunnelOutbound firewall rules
WireGuard for WindowsTunnel serviceBlock untunneled traffic option
wg-quick on LinuxRoute via AllowedIPsYour own nftables or iptables rules

Windows — самый ясный пример надписи, которая не блокирует. Там Always On описывает устойчивость туннеля: туннель устройства для аутентификации машины и пользовательский туннель для вошедшей учётной записи, настроенные через XML профиля или Add-VpnConnection. Ничто в этом профиле не останавливает исходящий пакет, когда туннеля нет, а исходящая фильтрация по умолчанию не включена, поэтому ноутбук в Wi-Fi продолжает работать, пока VPN лежит.

WireGuard делится так же, но по клиенту. WireGuard for Windows имеет параметр Block untunneled traffic для каждого туннеля, который ставит правила фильтра; в инструментах Linux такого переключателя нет. wg-quick добавляет маршрут для каждой записи AllowedIPs и правило fwmark, а wg-quick down удаляет и то и другое, поэтому физический маршрут по умолчанию снова берёт работу на себя, не потеряв ни одного пакета.

На платформах Apple always-on приходит как функция профиля управления для наблюдаемых устройств и выражается правилами on-demand, а не флажком. Вопрос, на который нужно ответить по полезной нагрузке: отказывает ли несостоявшийся туннель в трафике или только просит другое соединение. Название пункта меню об этом не скажет.

Проверка 3: измеряйте промежуток, а не значок

Важны четыре перехода, и они ломаются по-разному: загрузка до того, как кто-то войдёт, сон и пробуждение, переход с Wi-Fi на мобильные данные и сбой клиента, который оставляет интерфейс туннеля наполовину настроенным. Чистое переподключение на одном из них ничего не доказывает про остальные три.

Самая дешёвая проверка намеренно останавливает туннель и затем пытается выйти. Когда туннель лежит, curl -m 5 -sS -o /dev/null -w '%{http_code}' https://example.com, возвращающий 200, означает, что политика fail-open; тайм-аут или отказ в соединении означают, что что-то всё ещё блокирует. ip route get 1.1.1.1 называет интерфейс, который понёс бы пакет, и это обычно информативнее значка в трее, а systemctl status wg-quick@wg0 показывает, был ли интерфейс аккуратно удалён.

Запустите ту же проверку во втором окне, пока сеть меняется, а не только после того, как она устоялась. Интервал между обрывом и повторной попыткой — это и есть главное, а разрешение имён — самый быстрый способ заметить, что трафик ушёл: если локальный резолвер отвечает, пока туннель лежит, блокировка неполная.

Проверка 4: определите исключения до того, как запрёте

Два исключения структурные. Клиент должен дойти до самого сервера VPN, поэтому набор правил, который отбрасывает всё, мешает и переподключению, которое вернуло бы защиту. Captive portal тоже недоступен через туннель, который не поднят, поэтому заблокированному устройству в гостиничном Wi-Fi нужен задокументированный способ открыть портал, а не импровизированный.

Минимальная форма: конечная точка разрешена, всё остальное отброшено:

table inet vpnlock {
  chain output {
    type filter hook output priority 0; policy drop;
    oifname "lo" accept
    ip daddr 203.0.113.10 udp dport 51820 accept
    oifname "wg0" accept
  }
}

Относитесь к этой строке конечной точки как к переменной, а не константе. Провайдеры меняют адреса, и устаревшее исключение — обычная причина, по которой работающий kill switch превращается в устройство, которое не может переподключиться. Локальные принтеры, общие ресурсы NAS и сервисы разработки входят в тот же записанный список, иначе они обнаруживаются по одному обращению в поддержку.

Проверка 5: запишите, что вы на самом деле доказали

Держите таблицу с четырьмя столбцами и заполняйте её тестами: состояние, ожидаемое поведение, наблюдённое поведение, доказательство. Строки — это переходы из проверки 3 плюс один намеренный сбой. Строка, которую нельзя заполнить выводом команды, — это непроверенная строка, а устройство, которое проходит строку переподключения и падает на строке загрузки, встречается достаточно часто, чтобы оправдать лишние десять минут.

Прежде чем считать готовым:

  • Убедитесь, что настройка блокировки отделена от настройки переподключения, и прочитайте её значение на устройстве.
  • Знайте, какой слой применяет блокировку - параметр клиента, политика устройства или межсетевой экран - и где этот слой настраивается.
  • Сохраните одну проверочную команду, доказывающую блокировку, и запускайте её во время перехода, а не после.
  • Запишите список исключений, включая конечную точку, и отметьте, кто его обновляет.
  • На управляемом оборудовании не трогайте навязанную политику; удаление блокировки меняет требование, а не чинит туннель.

Похожие статьи