@cherkunoff

Как настроить маршрутизацию клиентов из LAN через VPN, а самого устройства через провайдера?

Добрый день!

В моей домашней сети есть Raspberry Pi, которую я хочу использовать в том числе как dns-резалку рекламы и как vpn-шлюз.

Для этих целей я установил AdGuard home и настроил на нём dns-over-tls, выпустив его в Интернет. Теперь реклама на мобильных телефонах режется не только при подключении к домашнему wifi, но и при использовании мобильной сети (в Андроиде есть штатные настройки для этого: Настройки -> Сеть и Интернет -> Персональный DNS сервер). Что бы всё работало, для определённого субдомена я настроил DNS запись типа A, указывающую на IP, получаемый от провайдера.

А вот с одновременным использованием Малинки как vpn-шлюза возникают проблемы. Для подключения к VPN я использую штатное приложение NordVPN под Linux и протокол Nordlynx (проприетарную реализацию Wireguard). Как только подключение поднимается, весь трафик уходит в туннель и я теряю доступ к dns-серверу AdGuard из Интернета. Сразу скажу, что настраивать DNS запись типа A на IP VPN провайдера не вариант - там все порты закрыты для входящих соединений.

Таким образом, мне нужно настроить следующую схему: трафик любого клиента из LAN (10.10.10.0/24), использующий Малинку как шлюз должен направляться через туннель с именем nordlynx, а трафик самой Малинки должен идти через провайдера.
Я понимаю, что мне нужен policy-роутинг (https://habr.com/ru/post/108690/), но как именно его настроить в такой конфигурации - пока догадаться не могу. В этой части и прошу помощи.

Моя текущая конфигурация.
Правило nat для интерфейа nordlynx:
-A POSTROUTING -o nordlynx -j MASQUERADE
Правила для цепочки FORWARD:
-A FORWARD -i eth0 -o nordlynx -j ACCEPT
-A FORWARD -i nordlynx -o eth0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

Так выглядят таблицы маршрутизации без подключённого VPN:
$ ip rule
0:      from all lookup local
220:    from all lookup 220
32766:  from all lookup main
32767:  from all lookup default

Вот так - с включённым:
$ ip rule
0:      from all lookup local
217:    from all lookup main suppress_prefixlength 0
218:    not from all fwmark 0xca6c lookup 51820
219:    from all to <IP VPN провайдера> lookup main
220:    from all lookup 220
32766:  from all lookup main
32767:  from all lookup default

Так выглядят маршруты без VPN подключения:
$ ip route
default via 10.10.10.1 dev eth0 onlink
10.10.10.0/24 dev eth0 proto kernel scope link src 10.10.10.100
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1

А так - с подключенным VPN:
$ ip route
default via 10.10.10.1 dev eth0 onlink
10.5.0.0/16 dev nordlynx proto kernel scope link src 10.5.0.2
10.10.10.0/24 dev eth0 proto kernel scope link src 10.10.10.100
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1


Заранее благодарю за советы!
  • Вопрос задан
  • 149 просмотров
Решения вопроса 1
@cherkunoff Автор вопроса
Мне удалось решить проблему 2 способами. Дублирую свой же комментарий, что бы пометить его ответом - может, кому-то поможет. Первый подсказали на форуме и он делает в точности то, что я описывал в начальном сообщении с вопросом: перепускает трафик клиентов из LAN через VPN туннель, а трафик самой Малинки - через провайдера. Для этого нужно после подключения VPN добавить таблицу маршрутизации с правилом по-умолчанию пускать трафик через роутер и 2 правила для интерфейса lo:

ip route add to default via 10.10.10.1 table 100
ip rule add iif lo to 10.10.10.0/24 lookup main prio 16000
ip rule add iif lo to default lookup 100 prio 16010


Как выяснилось, существенный минус этого решения - это увеличение пинга с 4 до 120 мс. и падение скорости более, чем в 10 раз до провайдера. Это очень печалит.

Второй вариант решения задачи я нашёл, когда начал гуглить ради интереса про
not from all fwmark 0xca6c lookup 51820


Вот здесь описано решение: https://unix.stackexchange.com/questions/607004/ca...
Нужно добавить один маршрут:

ip rule add from 10.10.10.100 lookup main

Тогда трафик, идущий с IP провайдера сможет достигнуть Малинки.

Добавлять правила после подключения нужно потому, что в противном случае хитрый NordVPN подсмотрит их порядок и добавит свои правила перед ними.
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
@res2001
Developer, ex-admin
Вам просто нужно на малинке добавить статический маршрут до вашего DNS провайдера, куда ходит AdGuard. Маршрут этот должен быть через DNS вашего оператора связи (или что там у вас сейчас в качестве шлюза по умолчанию без поднятого ВПН).
Никаких сложных телодвижений с настройкой фаервола не требуется.
Ответ написан
@alexvdem
Для этих целей я установил AdGuard home и настроил на нём dns-over-tls, выпустив его в Интернет.

Мартышкин труд. AdGuard имеет внешний DNS для такого случая. https://adguard.com/ru/blog/adguard-dns-announceme...
Свой собственный DOH иммет смысл настраивать, если он работает на внешнем VPS, на не на Pi. Да и то, надежность его будет ниже, чем решение от производителя.
Ответ написан
@AUser0
Чем больше знаю, тем лучше понимаю, как мало знаю.
Что-то не видно, каким образом весь трафик клиентов, использующих Малинку как шлюз, направляется в VPN.
Ещё более странным выглядит ip rule 217: from all lookup main suppress_prefixlength 0, которое просто повторяет стандартное правило 32766: from all lookup main.
Либо в случае VPN-соединения routes выглядят совсем по другому, либо что-то еще. Потому что вот с этой конфигурацией клиенты из Интернета должны спокойно получать доступ к DNS. Может что-то есть в iptables?
А что даёт ip route show table 220?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы