Маршрутизация VPN-трафика: как направить только нужные сайты через туннель

Разбираем способы выборочной маршрутизации VPN-трафика: статические маршруты, ipset, политики на роутере. Практические примеры, ограничения и ответы на частые вопросы.

Зачем нужна выборочная маршрутизация VPN-трафика

Когда VPN-клиент включён на роутере, обычно весь трафик домашней сети уходит в туннель. Это удобно для защиты, но создаёт проблемы: замедляется доступ к локальным ресурсам, онлайн-банкинг может блокировать вход из-за смены геолокации, а стриминговые сервисы начинают показывать контент для другой страны. Выборочная маршрутизация позволяет отправлять через VPN только те сайты и сервисы, которые действительно нужны, оставляя остальной трафик на обычном канале.

Такой подход востребован, когда нужно обойти региональные ограничения для конкретного видеосервиса, но при этом сохранить быстрый доступ к местным сайтам. Например, пользователь хочет смотреть YouTube без замедлений, но не желает, чтобы все запросы к банку или госуслугам шли через зарубежный сервер. Маршрутизация по IP-адресам или по доменам даёт гибкость, но требует понимания сетевых механизмов.

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

Как работает таблица маршрутизации и почему важно указывать шлюз

Маршрутизация в IP-сетях основана на таблице маршрутов, которая хранится в операционной системе роутера или сервера. Каждая запись содержит адрес назначения, маску подсети, шлюз (next hop) и интерфейс. Когда пакет отправляется, система выбирает наиболее специфичный маршрут — тот, у которого маска длиннее. Если точного совпадения нет, используется маршрут по умолчанию (default gateway).

При настройке VPN-туннеля важно правильно указать шлюз. В примере с роутером TP-Link пользователь добавил статические маршруты, используя адрес VPN-сервера из конфигурации WireGuard. Однако ошибка заключалась в том, что шлюзом был указан адрес самого VPN-интерфейса, а не адрес удалённого шлюза. В WireGuard адрес интерфейса (например, 10.0.0.2/24) — это локальный адрес внутри туннеля, а шлюзом должен быть адрес другой стороны туннеля (обычно .1). Если указать неверный шлюз, пакеты не смогут корректно покинуть туннель, что приводит к ошибкам подключения.

Также важно помнить, что маршруты для VPN должны иметь более высокий приоритет (меньшую метрику), чем маршрут по умолчанию, иначе трафик не пойдёт через туннель. В большинстве случаев достаточно добавить маршрут с маской /32 для конкретного IP или /24 для подсети, указав шлюз туннеля.

Статические маршруты: простой способ, но с ограничениями

Самый очевидный способ направить трафик к определённым IP-адресам через VPN — добавить статические маршруты в таблицу маршрутизации роутера. Например, если нужно, чтобы все запросы к подсети 173.194.0.0/16 (диапазон Google) шли через туннель, добавляется запись: ip route add 173.194.0.0/16 via <VPN_GATEWAY>. Это работает, но есть нюансы.

Во-первых, IP-адреса крупных сервисов (Google, YouTube, Netflix) разбросаны по множеству подсетей, и их список постоянно меняется. Пользователь из обсуждения на Хабре пытался вручную перечислить все диапазоны YouTube, но столкнулся с тем, что часть адресов не была учтена, из-за чего видео зависало. Во-вторых, некоторые сервисы используют CDN-серверы, которые могут находиться в других странах, и их IP не входят в официальные диапазоны компании. В-третьих, статические маршруты не учитывают DNS-резолвинг: если домен резолвится в IP, которого нет в списке, трафик пойдёт напрямую.

Тем не менее, для небольших списков IP (например, для одного игрового сервера) статические маршруты — вполне рабочий вариант. Главное — правильно определить шлюз и маску, а также быть готовым периодически обновлять список.

Маршрутизация по геолокации с помощью ipset: автоматизация списков

Более продвинутый подход — использовать ipset для хранения списка подсетей целой страны. Это позволяет автоматически направлять через VPN весь трафик, идущий в определённую страну, или наоборот, исключать её. В статье на Хабре описан сценарий, где на сервере создаётся виртуальный интерфейс macvlan, поднимается WireGuard-туннель, а затем с помощью ipset и iptables настраивается маршрутизация на основе геолокации.

Идея проста: скачивается список IP-диапазонов страны (например, из ipdeny.com), загружается в ipset-таблицу типа hash:net, а затем в iptables добавляются правила, которые помечают пакеты, идущие в эти подсети, специальной меткой. Далее на основе метки выбирается таблица маршрутизации: либо обычный шлюз, либо VPN-туннель.

Этот метод удобен, когда нужно направить через VPN весь трафик, кроме, скажем, российских сайтов. Или наоборот — только российские сайты через VPN, если вы за границей. Однако он требует наличия Linux-сервера или роутера с OpenWRT, так как на стандартных прошивках TP-Link или D-Link таких возможностей нет.

Настройка ipset и iptables: пошаговый пример

Рассмотрим пример из статьи на Хабре. Предположим, у вас есть сервер с Ubuntu, который выступает шлюзом для домашней сети. Сначала создаётся macvlan-интерфейс mc0 с адресом 192.168.0.3, чтобы сервер мог принимать трафик от устройств, которые будут использовать его как шлюз. Затем поднимается WireGuard-туннель wg0 с адресом 192.168.2.6.

Далее создаётся ipset-таблица с российскими подсетями:

create-ipset.sh ru

Этот скрипт скачивает список с ipdeny.com и заполняет таблицу. После этого настраиваются правила iptables:

# Помечаем весь трафик с mc0 меткой 0x32 (обычный шлюз)
iptables -t mangle -A PREROUTING -i mc0 -j MARK --set-xmark 0x32/0xffffffff

# Помечаем трафик, идущий в подсети из списка ru, меткой 0x64 (VPN)
iptables -t mangle -A PREROUTING ! -d 192.168.0.0/16 -i mc0 -m set ! --match-set ru dst -j MARK --set-xmark 0x64/0xffffffff

Затем создаются две таблицы маршрутизации: одна с обычным шлюзом, другая с VPN. Правила ip rule направляют пакеты с меткой 0x64 в VPN-таблицу, а с меткой 0x32 — в основную. В итоге трафик к российским IP идёт напрямую, а весь остальной — через VPN.

Важно не забыть включить форвардинг (net.ipv4.ip_forward=1) и настроить NAT (MASQUERADE) для исходящих пакетов. Также нужно решить проблему с ARP-ответами, если используется macvlan — для этого выставляются параметры ядра arp_ignore=1 и arp_announce=2.

Проблемы с DNS и CDN: почему маршрутизация по IP не всегда спасает

Даже если вы правильно настроили маршруты, могут возникнуть проблемы, связанные с DNS и CDN. Например, сервис YouTube использует домены googlevideo.com, которые резолвятся в IP-адреса, принадлежащие Google. Однако часть видеоконтента может храниться на кеширующих серверах локальных провайдеров, которые не входят в официальные диапазоны Google. В таком случае трафик к этим серверам пойдёт напрямую, и вы получите ошибки подключения или низкую скорость.

Кроме того, некоторые сервисы определяют ваше местоположение не по IP, а по DNS-запросам. Если DNS-сервер остаётся локальным, сервис может считать, что вы находитесь в России, даже если трафик идёт через VPN. Поэтому важно использовать DNS-серверы, которые резолвят домены в IP-адреса, соответствующие стране VPN-сервера. Например, можно использовать DNS от Cloudflare (1.1.1.1) или Google (8.8.8.8), но они тоже могут возвращать разные результаты в зависимости от геолокации.

Ещё одна проблема — токены авторизации. Некоторые сервисы включают в токен ваш IP-адрес, и если он меняется в процессе сессии, возникают ошибки. Это особенно актуально для стриминговых платформ, которые активно борются с VPN.

Ограничения стандартных роутеров и когда нужен OpenWRT

Большинство домашних роутеров (TP-Link, ASUS, D-Link) имеют ограниченные возможности настройки маршрутизации. В веб-интерфейсе обычно доступны только статические маршруты, но не поддержка ipset или сложных правил iptables. Например, на TP-Link Archer AX5400 пользователь из обсуждения смог добавить маршруты только через редактирование конфигурационного файла, что неудобно и рискованно.

Если вам нужна гибкая маршрутизация по геолокации или по доменам, придётся использовать роутер с OpenWRT или аналогичной прошивкой. OpenWRT позволяет устанавливать пакеты ipset, dnsmasq с поддержкой ipset, а также настраивать политики маршрутизации через luci-app-policy-routing. Это открывает возможности для маршрутизации по доменным именам, когда трафик к определённым доменам направляется в VPN, даже если их IP меняются.

Альтернативный вариант — использовать второй роутер, который будет работать как VPN-шлюз для конкретных устройств. Например, один роутер раздаёт обычный Wi-Fi, а второй, подключённый к VPN, создаёт отдельную сеть. Устройства, которым нужен VPN, подключаются ко второй сети. Это просто и надёжно, но требует дополнительного оборудования.

Маршрутизация по доменам: как обойти проблему смены IP

Поскольку IP-адреса крупных сервисов часто меняются, более надёжным решением является маршрутизация по доменным именам. Суть в том, что DNS-резолвер (обычно dnsmasq) при запросе к определённому домену добавляет полученный IP-адрес в ipset-таблицу, а затем iptables направляет трафик к этим IP через VPN. Это позволяет автоматически отслеживать изменения IP.

Например, в OpenWRT можно настроить dnsmasq так:

ipset=/youtube.com/googlevideo.com/yt

Это означает, что все IP, полученные при резолвинге доменов youtube.com и googlevideo.com, будут добавляться в ipset-список yt. Затем правило iptables направляет трафик к этим IP в VPN-туннель.

Этот метод удобен, но имеет недостатки: если сервис использует множество доменов, список нужно постоянно пополнять. Кроме того, DNS-запросы могут быть перехвачены провайдером, поэтому стоит использовать шифрованный DNS (DoH/DoT).

Практические советы по настройке и диагностике

При настройке выборочной маршрутизации VPN-трафика полезно следовать нескольким рекомендациям.

Во-первых, всегда проверяйте, какие IP-адреса использует целевой сервис. Для этого можно запустить tcpdump на роутере или использовать утилиты типа netstat на клиенте. Например, чтобы узнать, к каким IP обращается YouTube, можно открыть консоль браузера и посмотреть сетевые запросы.

Во-вторых, не забывайте про MTU. VPN-туннели (особенно WireGuard) имеют меньший MTU (обычно 1420), чем стандартный Ethernet (1500). Если MTU настроен неправильно, могут возникать фрагментация и потери пакетов. Проверить оптимальный MTU можно командой ping с флагом -f -l.

В-третьих, используйте системный журнал для диагностики. Если трафик не идёт через VPN, проверьте, что маршруты активны (ip route), что ipset-таблицы заполнены (ipset list), и что правила iptables не блокируют пакеты.

Наконец, если вы используете роутер с ограниченной прошивкой, рассмотрите возможность установки OpenWRT или использования второго устройства в качестве VPN-шлюза. Это сэкономит время и нервы.

Типичные ошибки и как их избежать

Одна из самых частых ошибок — указание неправильного шлюза в статических маршрутах. Как уже упоминалось, для WireGuard шлюзом должен быть адрес удалённого пира, а не локальный адрес интерфейса. Также часто забывают про маску подсети: если указать /32 вместо /24, маршрут будет работать только для одного IP, а не для всей подсети.

Другая ошибка — несоответствие DNS и маршрутизации. Если DNS-сервер возвращает IP, который не входит в ваши маршруты, трафик пойдёт напрямую. Решение — использовать DNS, который резолвит домены в нужные IP, или настроить dnsmasq с ipset.

Также стоит помнить, что некоторые сервисы (например, YouTube) используют несколько доменов и IP-диапазонов, и их список постоянно меняется. Поэтому статические маршруты — это временное решение. Для долгосрочной работы лучше использовать автоматические списки (ipset по геолокации) или маршрутизацию по доменам.

Наконец, не забывайте про безопасность: если вы направляете только часть трафика через VPN, остальной трафик может быть виден провайдеру. Убедитесь, что это соответствует вашим требованиям.

Вопросы и ответы

Как правильно указать шлюз в статическом маршруте для WireGuard?

В WireGuard шлюзом должен быть IP-адрес удалённого пира (обычно .1 в подсети туннеля), а не локальный адрес интерфейса. Например, если ваш интерфейс wg0 имеет адрес 10.0.0.2/24, а сервер — 10.0.0.1, то шлюз будет 10.0.0.1. Указание локального адреса приводит к ошибкам маршрутизации.

Почему YouTube работает нестабильно при маршрутизации по IP?

YouTube использует множество IP-диапазонов, которые могут меняться. Если вы прописали только часть из них, часть трафика пойдёт напрямую, что вызовет ошибки и зависания. Также проблема может быть связана с CDN-серверами, которые не входят в официальные диапазоны Google. Рекомендуется использовать маршрутизацию по доменам через dnsmasq и ipset.

Можно ли настроить выборочную маршрутизацию на обычном роутере TP-Link?

На большинстве стандартных прошивок TP-Link доступны только статические маршруты, но нет поддержки ipset или сложных правил iptables. В некоторых моделях можно редактировать конфигурационные файлы, но это рискованно. Для гибкой маршрутизации лучше использовать OpenWRT или второй роутер с VPN.

Что такое ipset и как он помогает в маршрутизации VPN?

ipset — это утилита для создания списков IP-адресов и подсетей в ядре Linux. Она позволяет быстро проверять принадлежность IP к списку и использовать это в правилах iptables. Например, можно создать список подсетей страны и направлять трафик к ним через VPN или наоборот.

Как настроить маршрутизацию по доменным именам в OpenWRT?

В OpenWRT нужно настроить dnsmasq с опцией ipset. Например, добавьте в /etc/config/dhcp строку: list ipset '/youtube.com/googlevideo.com/yt'. Затем создайте ipset-таблицу yt и добавьте правило iptables, которое направляет трафик к IP из этой таблицы в VPN-туннель. Подробные инструкции можно найти в документации OpenWRT.

Почему сервис определяет меня как местного, даже если трафик идёт через VPN?

Сервис может определять геолокацию по DNS-запросам, которые идут через локальный DNS-сервер, или по IP-адресам CDN-серверов, которые не входят в VPN-маршруты. Также некоторые сервисы используют токены авторизации, включающие IP. Убедитесь, что DNS-запросы тоже идут через VPN, и что все IP-адреса сервиса охвачены маршрутами.