Скрипт отключения или правило брандмауэра: что останавливает утечку?
Опускать интерфейсы при разрыве — грубо, и часто это выполняется без прав. Сравните с правилом брандмауэра, которое переживает обрыв и закрывает щель.
Две схемы обещают одно и то же: когда туннель падает, ничего не уходит наружу в открытом виде. Одна запускает при разборе скрипт и режет интерфейсы. Другая оставляет правило брандмауэра в силе и ничего не требует от клиента VPN. Они различаются тем, у кого есть право действовать, что происходит в щели и как машина потом возвращается в сеть. Сравнивать их по этим трём пунктам полезнее, чем спорить, какая схема строже.
Одна и та же работа двумя механизмами
Клиент может запускать хуки при поднятии туннеля и при его разборе, если профиль разрешает выполнение скриптов. Этот хук работает внутри жизненного цикла клиента, в момент, когда соединение закрывается. Правило брандмауэра, напротив, принадлежит системе и не интересуется, работает ли клиент, упал он или был убит.
| Property | Teardown script | Firewall unit |
|---|---|---|
| Runs when the client is killed | No | Yes |
| Needs privilege at teardown time | Usually yes | Configured once, at boot |
| Acts on the whole machine | Often, including recovery paths | Only on the flows it matches |
Эта таблица — весь аргумент. Скрипт, который работает только при аккуратном завершении, покрывает случай, который беспокоил вас меньше всего; важный случай — падение или исчезновение сети, и ни один из них не даёт чистого разбора.
Что хук разбора может и чего не может
Задокументированный шаблон обходит сетевые интерфейсы и опускает всё, кроме loopback. Если физическое устройство опущено, ничто не может уйти за пределы туннеля, и это именно то, что нужно.
#!/bin/sh
for dev in /sys/class/net/*; do
name=$(basename "$dev")
[ "$name" = lo ] || ip link set dev "$name" down
done
Он опускает и локальную сеть, любую службу, которую держит машина, и путь, которым вы стали бы чинить проблему. На ноутбуке беспроводному устройству иногда нужен ручной переключатель потом, так что короткий сбой превращается в сеанс ремонта. Хуже того, хуку может быть вообще не разрешено ничего из этого: когда клиент сбрасывает права, скрипт разбора работает под непривилегированной учётной записью, и любое изменение интерфейса падает с ошибкой прав, записанной в тот самый момент, когда никто не читает журнал.
Проверьте, как запускается клиент, прежде чем доверять хуку. Скрипт, который работает при ручном запуске от root, ничего не доказывает о службе, которая стартует при загрузке.
Что правило брандмауэра делает иначе
Правило, разрешающее только трафик туннеля, продолжает работать, когда процесс клиента исчез, потому что ядро не зависит от этого процесса. Правило ещё и уже: оно блокирует ровно те потоки, которым соответствует, и оставляет в покое loopback, локальную подсеть и путь восстановления, поэтому машина не оказывается в тупике.
Цена в том, что правило должен написать и поддерживать тот, кто владеет брандмауэром хоста, и оно должно назвать устройство туннеля, которое клиент действительно создаёт. Это значит, что правило и профиль нужно поддерживать вместе; переименованный интерфейс оставляет брандмауэр, который блокирует всё и ничего не объясняет.
Ни один механизм не делает другой лишним. Правило брандмауэра, которое после правки никогда не перечитывается, так же выдумано, как скрипт, который никогда не запускается.
persist-tun решает, есть ли щель
Когда устройство туннеля переживает разрыв, переживают и маршруты, ведущие в него. Тогда трафик отбрасывается, а не перенаправляется, поэтому маршрут по умолчанию не возвращается на физический шлюз. Именно это поведение делает утечку маловероятной ещё до участия любого правила брандмауэра.
Без этой настройки устройство удаляется вместе с маршрутами, и маршрут по умолчанию может снова указывать на физический шлюз. Сделает ли он это, зависит от платформы и клиента, и именно поэтому состояние нужно наблюдать, а не предполагать. Считайте настройку частью kill switch, а не параметром производительности.
Сохраните путь переподключения живым, затем проверьте четыре состояния
Строгая блокировка может помешать и переподключению, ведь клиенту по-прежнему нужен маршрут к серверу через физический шлюз, пока всё остальное запрещено. Установите маршрут хоста для этого одного адреса до поднятия туннеля и сначала разрешите имя, поскольку DNS может быть заблокирован к тому моменту, когда он понадобится.
ip route add 198.51.100.20/32 via 192.168.0.1 dev wlan0
Затем проверяйте состояния, а не ярлык. Пройдите четыре момента намеренно: холодный старт без туннеля, здоровая сессия, обрыв, которого никто не просил, и сессия после восстановления. В каждый момент прочитайте маршрут по умолчанию и сделайте один запрос, чей адрес выхода виден. Приложение, которое сдаётся, пока туннель опущен, ничего не говорит о почтовом клиенте или обновляторе, поэтому повторите последнюю проверку с одним фоновым приложением. Запишите правило, имена интерфейсов и шаги восстановления, потому что kill switch, который никто не может проверить, — это слух.