Kill switch для VPN: настройка на Windows, Linux и macOS
VPN-туннель рвётся молча: процесс упал, Wi-Fi моргнул, сервер перезагрузился — а система тем временем спокойно переключается на обычное соединение и отправляет трафик напрямую, в открытом виде. Если вам важно, чтобы разрыв туннеля не превращался в утечку реального IP и незашифрованного трафика, единственный надёжный способ — блокировать интернет на уровне firewall при отсутствии VPN-соединения. Ниже — рабочие конфигурации kill switch для Linux, Windows и macOS с конкретными правилами и командами.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Зачем нужен kill switch и как он работает
Kill switch — это не функция VPN-клиента, а набор правил firewall, которые физически не дают трафику покинуть машину в обход туннеля. Идея простая: разрешить исходящий и входящий трафик только через VPN-интерфейс (и отдельно — к самому VPN-серверу для установки соединения), а весь остальной трафик — заблокировать по умолчанию.
Если VPN-клиент просто «переподключается» без такого firewall-барьера, между разрывом и восстановлением туннеля проходит окно в несколько секунд, а иногда и минут — и всё это время приложения могут стучаться в сеть напрямую. Для обычного веб-сёрфинга это неприятно, но не критично. Для доступа к сервисам, где важно не светить исходный IP, или для передачи чувствительных данных — это дыра, которую нужно закрывать на уровне ОС, а не полагаться на переподключение клиента.
Три подхода к реализации, которые разберём дальше:
- iptables — классика для Linux, работает везде, где есть netfilter.
- nftables — современная замена iptables, более читаемый синтаксис, меньше правил.
- Windows Firewall (WFP) — правила через PowerShell или
netsh advfirewall. - pf (Packet Filter) — стандартный firewall macOS и BSD-систем.
Общий принцип везде одинаковый: политика по умолчанию — DROP, разрешения — точечные исключения.
Linux: iptables — блокировка трафика мимо VPN
Базовая схема для WireGuard (интерфейс wg0) или OpenVPN (интерфейс tun0). Подставьте свои значения интерфейса, IP и порта VPN-сервера.
#!/bin/bash
VPN_IF="wg0"
VPN_SERVER_IP="203.0.113.10"
VPN_SERVER_PORT="51820"
LAN_IF="eth0" # физический интерфейс, через который идёт handshake
# Сброс текущих правил
iptables -F
iptables -X
# Политика по умолчанию — блокировать всё
iptables -P OUTPUT DROP
iptables -P INPUT DROP
iptables -P FORWARD DROP
# Loopback всегда разрешён
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
# Уже установленные соединения
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Разрешить handshake с VPN-сервером напрямую через физический интерфейс
iptables -A OUTPUT -o $LAN_IF -p udp -d $VPN_SERVER_IP --dport $VPN_SERVER_PORT -j ACCEPT
iptables -A INPUT -i $LAN_IF -p udp -s $VPN_SERVER_IP --sport $VPN_SERVER_PORT -j ACCEPT
# Весь остальной трафик — только через VPN-интерфейс
iptables -A OUTPUT -o $VPN_IF -j ACCEPT
iptables -A INPUT -i $VPN_IF -j ACCEPT
# DHCP, если IP получаете динамически
iptables -A OUTPUT -p udp --dport 67:68 -j ACCEPT
iptables -A INPUT -p udp --sport 67:68 -j ACCEPT
Проверьте правила и, если всё работает, сохраните их так, чтобы они переживали перезагрузку:
apt install iptables-persistent
netfilter-persistent save
Для WireGuard есть более элегантный вариант — прописать те же правила прямо в PostUp/PostDown конфига wg-quick, тогда kill switch включается и выключается вместе с самим туннелем:
[Interface]
PrivateKey = ...
Address = 10.0.0.2/24
PostUp = iptables -I OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
PostDown = iptables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
Такой вариант проще привязать к жизненному циклу конкретного соединения, но статические правила из первого блока надёжнее — они работают даже если сам процесс wg-quick упал и не успел выполнить PostDown. Подробно установка и базовая настройка WireGuard разобрана в статье про установку WireGuard на VPS.
Арендуйте сервер под свои задачи!
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверLinux: nftables — современный аналог iptables
На новых дистрибутивах (Debian 12+, Ubuntu 22.04+) nftables — стандарт по умолчанию, iptables там работает через nft-совместимость. Тот же kill switch компактнее:
table inet killswitch {
chain output {
type filter hook output priority 0; policy drop;
oif lo accept
ct state established,related accept
# Handshake с VPN-сервером
ip daddr 203.0.113.10 udp dport 51820 accept
# Весь трафик через VPN-интерфейс
oifname "wg0" accept
# DHCP
udp dport 67-68 accept
}
chain input {
type filter hook input priority 0; policy drop;
iif lo accept
ct state established,related accept
ip saddr 203.0.113.10 udp sport 51820 accept
iifname "wg0" accept
udp sport 67-68 accept
}
}
Сохраните это в /etc/nftables.conf, примените и включите автозапуск:
nft -f /etc/nftables.conf
systemctl enable --now nftables
Важный нюанс: если на сервере уже есть другие таблицы nftables (например, от Docker или fail2ban), убедитесь, что приоритеты хуков не конфликтуют — таблица с policy drop и низким приоритетом может неожиданно перекрыть правила других сервисов. Проверяйте nft list ruleset после каждого изменения.
Windows: правила Windows Firewall для kill switch
У штатного Windows Firewall нет отдельной кнопки «kill switch», но можно собрать тот же эффект из правил через PowerShell. Логика: блокируем весь исходящий трафик по умолчанию, затем точечно разрешаем через VPN-адаптер и к серверу для handshake.
# Имя VPN-адаптера уточните через Get-NetAdapter
$vpnAdapter = "WireGuard Tunnel"
$vpnServerIP = "203.0.113.10"
$vpnPort = 51820
# Базовый блок всего исходящего трафика
New-NetFirewallRule -DisplayName "KillSwitch-Block-Outbound" `
-Direction Outbound -Action Block -Enabled True -Profile Any -Protocol Any
# Разрешить handshake к VPN-серверу
New-NetFirewallRule -DisplayName "KillSwitch-Allow-Handshake" `
-Direction Outbound -Action Allow -RemoteAddress $vpnServerIP `
-RemotePort $vpnPort -Protocol UDP
# Разрешить весь трафик через VPN-адаптер
New-NetFirewallRule -DisplayName "KillSwitch-Allow-VPN-Interface" `
-Direction Outbound -Action Allow -InterfaceAlias $vpnAdapter
# Локальная сеть (при необходимости — принтеры, NAS)
New-NetFirewallRule -DisplayName "KillSwitch-Allow-LAN" `
-Direction Outbound -Action Allow -RemoteAddress 192.168.0.0/16
Здесь есть честная оговорка: у Windows Firewall (WFP) правила Block не всегда автоматически «побеждают» Allow — это зависит от типа правила и профиля. На практике конкретно этот набор (Block-Any + точечные Allow) работает предсказуемо, но после применения обязательно проверьте это тестом ниже, а не полагайтесь на теорию.
Более простой и надёжный вариант для Windows — использовать встроенный kill switch клиента. Актуальные клиенты WireGuard для Windows и OpenVPN Connect уже реализуют блокировку трафика через тот же WFP при отсутствии активного туннеля — включается галочкой в настройках клиента, без ручного написания правил. Ручные правила firewall имеет смысл добавлять, если вы используете клиент без этой функции или хотите второй, независимый уровень защиты. О самих портах и протоколах VPN подробнее — в статье про порты для VPN-протоколов в Windows Firewall.
macOS: pf (Packet Filter) для аварийной блокировки
В macOS штатный firewall (в «Настройках») работает на уровне приложений и для kill switch не подходит — нужен pf, тот же движок, что в FreeBSD. Создайте файл конфигурации, например /etc/pf.anchors/killswitch:
vpn_if = "utun3"
vpn_server = "203.0.113.10"
vpn_port = "51820"
set skip on lo0
block drop all
pass out quick on $vpn_if all
pass in quick on $vpn_if all
pass out quick proto udp to $vpn_server port $vpn_port
pass in quick proto udp from $vpn_server port $vpn_port
Интерфейс VPN уточните командой ifconfig | grep utun — WireGuard и большинство клиентов на macOS создают интерфейсы utunN, конкретный номер зависит от порядка подключения и может меняться между сессиями, поэтому имеет смысл сначала поднять туннель и только потом смотреть актуальное имя.
Подключите анкор в основной /etc/pf.conf и загрузите правила:
echo 'anchor "killswitch"' | sudo tee -a /etc/pf.conf
echo 'load anchor "killswitch" from "/etc/pf.anchors/killswitch"' | sudo tee -a /etc/pf.conf
sudo pfctl -f /etc/pf.conf
sudo pfctl -e
Два ограничения, о которых стоит знать заранее. Во-первых, macOS сама управляет pf для системных нужд (Application Firewall, VPN-профили) и может частично перезаписывать правила при пробуждении из сна — для надёжности стоит добавить launchd-джобу, которая перезагружает анкор после wake. Во-вторых, если у вас VPN-клиент с собственным GUI (например, из App Store), он иногда создаёт свои анкоры pf и может конфликтовать с ручными правилами — проверяйте sudo pfctl -sr после установки соединения, чтобы увидеть итоговый набор активных правил.
Проверка kill switch: как убедиться, что он работает
Правила, которые вы не протестировали, — это иллюзия защиты. Проверка должна имитировать именно аварийный обрыв, а не штатное отключение VPN-клиентом (при штатном отключении многие клиенты сами снимают firewall-правила).
- Подключите VPN и убедитесь, что трафик идёт через туннель — сравните IP до и после:
curl -s https://ifconfig.me
- Оборвите туннель «грубо», в обход клиента — например, выключите сетевой интерфейс напрямую или заблокируйте порт VPN-сервера на файрволе роутера:
sudo ip link set wg0 down # Linux
- Сразу же повторите запрос к
ifconfig.me— если правила настроены верно, запрос должен зависнуть и оборваться по таймауту, а не вернуть ваш реальный IP. - Проверьте отдельно утечку DNS — сервисы вида
dnsleaktest.comпоказывают, какие DNS-резолверы реально видят ваши запросы; при правильном kill switch DNS-запросы тоже блокируются вместе с остальным трафиком. - Верните интерфейс в исходное состояние и убедитесь, что после восстановления VPN доступ снова появляется.
Если на шаге 3 запрос всё же прошёл — значит, где-то в правилах есть слишком широкое разрешение (частая причина — правило ESTABLISHED,RELATED, которое пропускает уже открытые соединения даже после обрыва туннеля, пока они не завершатся по таймауту). Проблемы именно с самим соединением, когда трафик не идёт вообще, разбираются отдельно в статье про отсутствие интернета через WireGuard.
Арендуйте сервер под свои задачи!
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Kill switch блокирует доступ к принтеру и другим устройствам в локальной сети — это нормально?
Да, если вы разрешаете только VPN-интерфейс и loopback. Добавьте отдельное правило ACCEPT для вашей локальной подсети (например, 192.168.1.0/24) — примеры такого правила есть в блоках для Linux и Windows выше.
Правила iptables/nftables переживут перезагрузку сервера?
Нет, если их не сохранить явно. На Debian/Ubuntu используйте netfilter-persistent save для iptables или включите systemctl enable nftables с правилами в /etc/nftables.conf — тогда они применяются при каждом старте системы.
Чем ручные правила firewall лучше встроенного kill switch VPN-клиента?
Встроенный kill switch удобнее и обычно работает через тот же механизм ОС (WFP на Windows, pf на macOS), но зависит от того, успел ли процесс клиента корректно обработать сбой. Ручные системные правила не зависят от состояния клиентского процесса — они действуют даже если сам VPN-клиент завис или был убит аварийно.
Можно ли настроить kill switch на роутере, а не на каждом устройстве?
Да, если роутер сам выступает VPN-клиентом (OpenWrt, MikroTik, Keenetic) — тогда правила firewall прописываются один раз на роутере и действуют для всех устройств в сети без отдельной настройки на каждом.
Kill switch замедляет соединение?
Сам факт наличия правил firewall почти не влияет на скорость — современные netfilter, WFP и pf обрабатывают пакеты с минимальными накладными расходами. Заметное замедление, если оно есть, обычно связано с самим VPN-протоколом или сервером, а не с firewall-правилами поверх него.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →