MAATRIX / Блог / Split tunneling на Windows: как пускать через VPN только часть трафика

Split tunneling на Windows: как пускать через VPN только часть трафика

MAATRIX

Полный туннель через VPN — это удобно, но не всегда нужно: он режет скорость до локальных сервисов, ломает доступ к принтеру в офисной сети и гоняет через удалённый сервер трафик, которому там нечего делать — YouTube, Steam, банк-клиент. Split tunneling решает это точечно: через VPN уходят только выбранные подсети или адреса, всё остальное идёт напрямую через обычный интернет-канал. Разберём, как настроить такую маршрутизацию на Windows — и через встроенный клиент, и через WireGuard.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Как Windows выбирает маршрут для пакета

Прежде чем городить конфиги, полезно понимать, что вообще происходит с трафиком. Windows держит таблицу маршрутов — список пар «подсеть → шлюз, через который до неё добираться» с метрикой (приоритетом). Когда система формирует пакет, она ищет в таблице самое точное совпадение по адресу назначения (longest prefix match) и отправляет пакет через соответствующий интерфейс.

Посмотреть текущую таблицу:

route print

или через PowerShell, в более читаемом виде:

Get-NetRoute -AddressFamily IPv4 | Sort-Object -Property InterfaceMetric | Format-Table DestinationPrefix, NextHop, InterfaceAlias, RouteMetric

Обычный «полный» VPN добавляет маршрут 0.0.0.0/0 через VPN-интерфейс (или два маршрута 0.0.0.0/1 и 128.0.0.0/1, чтобы формально не конфликтовать с локальным дефолтным маршрутом, но фактически всё равно забрать весь трафик). Split tunneling — это когда вместо 0.0.0.0/0 в таблицу попадают только конкретные подсети: 10.20.0.0/16, 203.0.113.0/24 и так далее. Всё, что не совпало ни с одним из этих префиксов, уходит по обычному дефолтному маршруту через провайдера.

route add: ручная маршрутизация поверх поднятого туннеля

Самый прямой способ — поднять VPN как обычно (он получит свой IP на интерфейсе, но не станет забирать весь трафик), а нужные подсети добавить руками через route add.

Синтаксис:

route add <подсеть> mask <маска> <шлюз> metric <метрика> if <номер_интерфейса>

Пример: пропустить через туннель только диапазон 10.20.0.0/16 (внутренняя сеть за VPN), где шлюз внутри туннеля — 10.20.0.1:

route add 10.20.0.0 mask 255.255.0.0 10.20.0.1 metric 5

Флаг -p делает маршрут постоянным — он переживёт перезагрузку и останется в таблице до следующего изменения конфигурации сети:

route add -p 10.20.0.0 mask 255.255.0.0 10.20.0.1 metric 5

Узнать номер интерфейса и его IP, если нужен явный if:

route print -4
netsh interface ipv4 show interfaces

Удалить маршрут, если ошиблись или он больше не нужен:

route delete 10.20.0.0 mask 255.255.0.0

Минус ручного route add — он работает только для встроенных клиентов, где VPN сам не пытается перезаписать таблицу маршрутов при каждом переподключении. WireGuard, например, живёт по своей логике (см. ниже), и добавленные вручную маршруты туда лучше не мешать.

Арендуйте сервер под свои задачи!

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Split tunneling для встроенного VPN-клиента Windows

Если вы поднимаете туннель через встроенный клиент Windows (IKEv2, L2TP/IPsec, SSTP, PPTP), по умолчанию Windows тоже пытается забрать весь трафик — это управляется галочкой «Использовать основной шлюз в удалённой сети» (Use default gateway on remote network).

Через графический интерфейс: Панель управления → Сеть и интернет → Подключения → выбрать VPN-подключение → Свойства → вкладка «Сеть» → выделить IPv4 → Свойства → Дополнительно → снять галочку «Использовать основной шлюз в удалённой сети».

После этого подключение перестаёт добавлять маршрут 0.0.0.0/0 и просто добавляет маршрут только до подсети сервера. Чтобы дотянуться до других подсетей за VPN, добавьте маршруты вручную (как в разделе выше) или через PowerShell:

Add-VpnConnectionRoute -ConnectionName "MyVPN" -DestinationPrefix 10.20.0.0/16 -PassThru

Посмотреть, какие маршруты уже привязаны к VPN-подключению:

Get-VpnConnectionRoute -ConnectionName "MyVPN"

Удалить лишний:

Remove-VpnConnectionRoute -ConnectionName "MyVPN" -DestinationPrefix 10.20.0.0/16

Важный нюанс: Add-VpnConnectionRoute привязывает маршрут к самому VPN-подключению — он будет добавляться автоматически при каждом коннекте и удаляться при разрыве. Это надёжнее, чем route add -p, который остаётся в системе независимо от состояния туннеля и может «зависнуть» мёртвым маршрутом, если интерфейс уже не поднят.

Split tunneling в WireGuard для Windows

WireGuard устроен иначе: маршрутизация в нём завязана на параметр AllowedIPs в секции [Peer] конфига. Это не просто список «разрешённых» адресов для приёма пакетов — на Windows и большинстве платформ клиент буквально прописывает эти подсети как маршруты через туннельный интерфейс при подключении.

Конфиг с полным туннелем (весь трафик через VPN):

[Interface]
PrivateKey = <ваш_приватный_ключ>
Address = 10.66.66.2/32
DNS = 10.66.66.1

[Peer]
PublicKey = <публичный_ключ_сервера>
Endpoint = 203.0.113.10:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

Тот же конфиг со split tunneling — в туннель уходят только две подсети, остальной трафик идёт напрямую:

[Interface]
PrivateKey = <ваш_приватный_ключ>
Address = 10.66.66.2/32
DNS = 10.66.66.1

[Peer]
PublicKey = <публичный_ключ_сервера>
Endpoint = 203.0.113.10:51820
AllowedIPs = 10.66.66.0/24, 198.51.100.0/24
PersistentKeepalive = 25

Здесь 10.66.66.0/24 — сама VPN-сеть (нужна почти всегда, иначе не будет связи с сервером и другими пирами), а 198.51.100.0/24 — например, подсеть офисных сервисов, к которой и был весь смысл подключения.

Можно перечислить сколько угодно диапазонов через запятую, включая отдельные IP как /32:

AllowedIPs = 10.66.66.0/24, 198.51.100.0/24, 203.0.113.55/32

Если сервер настраивался по инструкции «Как установить и настроить WireGuard на VPS», обратите внимание: там же нужно поправить AllowedIPs и в конфиге сервера (в секции клиентского peer), но это влияет только на то, какие исходные адреса сервер принимает от клиента, а не на маршрутизацию клиента — эти две настройки путают чаще всего.

Отдельно про DNS при split tunneling: если задать DNS = 10.66.66.1 в конфиге, WireGuard на Windows пропишет этот DNS-сервер глобально для всех запросов, даже для доменов, не связанных с VPN-подсетью. Если это не нужно (и приводит к утечкам или медленному резолву обычных сайтов), проще не указывать DNS в конфиге вовсе и резолвить внутренние адреса через hosts-файл или отдельный DNS-сервер, прописанный только на интерфейсе VPN через netsh interface ipv4 set dnsservers.

Практические сценарии и таблица настроек

Несколько типичных задач и что именно прописывать в AllowedIPs / маршрутах:

СценарийЧто добавить в туннельПример
Доступ к офисной сети через RDP/файлыПодсеть офиса192.168.10.0/24
Доступ только к одному серверу за VPNОдин IP203.0.113.55/32
Обход блокировок для нескольких сервисовIP-диапазоны этих сервисовнесколько /24 или /32 через запятую
Полный туннель (для сравнения)Весь трафик0.0.0.0/0
VPN-сеть + одна внешняя подсетьСеть VPN + нужная подсеть10.66.66.0/24, 198.51.100.0/24

Для сценария «обход блокировок для конкретных сервисов» на практике список IP-адресов сервиса может быть большим и меняться — тогда список AllowedIPs быстро становится неудобным для ручного сопровождения. Если задача именно в этом, честно: обычно проще держать отдельный маршрутизатор с проксированием по доменным именам (например, через DNS-based роутинг), а не пытаться поддерживать вручную список подсетей в WireGuard-конфиге. Split tunneling через route add/AllowedIPs хорошо работает, когда список подсетей стабилен и известен заранее — офисная сеть, подсеть дата-центра, конкретные серверы.

Диагностика: маршрут не тот, трафик всё равно через VPN

Если после настройки split tunneling трафик всё равно идёт через туннель (или наоборот — не идёт куда нужно), порядок проверки такой:

  1. Смотрим фактическую таблицу маршрутов: route print или Get-NetRoute. Ищем строку с нужной подсетью — если её нет, маршрут не применился (VPN не поднят, ошибка в AllowedIPs, забыли -p для постоянного маршрута).
  2. Проверяем метрики. Если один и тот же префикс есть в двух записях с разных интерфейсов (например, обе 0.0.0.0/0), выигрывает запись с меньшей метрикой — конфликт часто возникает, когда одновременно активны VPN и, например, второй туннель или Wi-Fi-соединение с похожим приоритетом. Разбор похожей ситуации есть в статье про конфликт двух VPN одновременно — логика с приоритетом маршрутов там та же, просто применительно к телефону.
  3. Трассируем конкретный адрес: tracert <IP> — по первому хопу видно, ушёл пакет через туннельный интерфейс или через обычный шлюз провайдера.
  4. Проверяем внешний IP до и после: если по логике split tunneling обычный сайт должен идти напрямую, а не через сервер, сверьте, что показывает проверка IP и страны после туннеля — если внешний адрес совпадает с адресом VPN-сервера для трафика, который должен был идти в обход, значит где-то остался маршрут 0.0.0.0/0 или слишком широкий AllowedIPs.
  5. Если совсем ничего не ходит через туннель даже для нужных подсетей — проверьте, не заблокирован ли форвардинг на сервере и не потерян ли handshake; частые причины разобраны в статье «WireGuard подключается, но нет интернета».

Отдельно стоит помнить про firewall: сам факт наличия маршрута не гарантирует, что пакет дойдёт — правило Windows Defender Firewall или стороннего файрвола может резать трафик на конкретный интерфейс независимо от таблицы маршрутов.

Арендуйте сервер под свои задачи!

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Split tunneling снижает безопасность VPN?

Да, в том смысле, что трафик, идущий в обход туннеля, не защищён и не скрыт — это осознанный компромисс ради скорости и совместимости с локальной сетью, а не баг настройки.

Можно совместить split tunneling с DNS через VPN?

Можно, но тогда DNS-запросы для доменов вне туннелируемых подсетей тоже пойдут через VPN-сервер, если вы не разделите DNS отдельно — см. раздел про DNS в WireGuard выше.

Почему route add -p не сохраняется после переустановки VPN-клиента?

Постоянные маршруты привязаны к номеру интерфейса или к его характеристикам в таблице маршрутов Windows; если интерфейс пересоздаётся (переустановка клиента, смена адаптера), маршрут может стать «висячим» и не примениться — тогда его нужно добавить заново.

AllowedIPs с несколькими подсетями работает одинаково на всех платформах WireGuard?

Логика одна и та же (это часть протокола/конфига), но то, как клиент применяет её к системной таблице маршрутов, зависит от реализации — на Windows это делает сервис WireGuardTunnel$, на Linux обычно wg-quick. Поведение по сути одинаковое, но диагностика отличается.

Что приоритетнее — маршрут из route add или из AllowedIPs?

Если оба применяются к одному интерфейсу и одному префиксу, действует обычная логика таблицы маршрутов Windows: точнее совпадение и меньшая метрика побеждают, а не то, каким инструментом маршрут был добавлен.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →