Skip to content

Latest commit

 

History

History
70 lines (50 loc) · 9.61 KB

VPN.md

File metadata and controls

70 lines (50 loc) · 9.61 KB

Предварительные условия

У вас есть роутер Keenetic, поднят внешний сервер VPN и стандартными средствами Keenetic к нему подключен тунель. Статья про перенаправление трафика в зависимости от домена, а не про настройку VPN. Тем не менее, рекомендую использовать Wireguard, как самый быстрый и безопасный.

Основная идея

Максимально будем использовать встроенные средства Keenetic, а именно - политики доступа в интернет. Это позволит нам гибко контроллировать как способ выхода в интернет через VPN: например, для смены OpenVPN на Wireguard не придется лезть в консоль, все можно будет сделать из интерфейса, так и контроллировать какие именно устройства получат возможность использовать перенаправление в зависимости от доменного имени. В случае каких-то проблем, можно будет отключить не лазая в консоль.

Поехали

  1. Установить Entware, лучше во внутреннюю память роутера, но можно и на флешку. Все пакеты в памяти займут не больше 16Мб, такой объем есть на всех роутерах Keenetic. Инструкция

    ВАЖНО! При маунте storage с папкой Install начинается процесс установки. Он может занять время, надо смотреть логи в "Диагностика" в интерфейсе. После установки будет доступен SSH с параметрами из логов.

    Получили доступ к SSH с Entware, заходим туда.

  2. opkg update
    opkg install mc dnsmasq-full ipset iptables

    С первого раза может не установится из-за ограниченной памяти и скачивания всего сразу, можно выполнить второй раз.

Настройка DNS сервера dnsmasq

Настраиваем dnsmasq в точности как описано тут:

Подготовка политик доступа

Будем максимально использовать возможность Keenetic, доступные из интерфейса. Переходим в "Приоритеты подключений" в интерфейсе. Нам нужно создать 2 новые политики доступа. Одна будет использоваться для реального выхода в интернет через VPN, вторая - для включения перенаправления в зависимости от домена.

  1. Первую назовем "VPN". И настроим ее так, чтобы все устройства, подключенные к этой политике, всегда выходили в интернет только через VPN соединение. Для этого оставляем галочку только у VPN соединения.
  2. Вторую назовем "Domain VPN". Настроим выход в интернет как по умолчанию, через основного провайдера. В дальнейшем все устройства, которые будут подключены к этой политике будут на самом деле использовать политику "VPN" для подключения к адресам, доменные имена которых указаны в настройках dnsmasq. При подключении ко всем остальным будет использоваться стандартная политика, настроенная в "Domain VPN"

Keenetic маркирует трафик в зависимости от того, в какой группе находится устройство. Нам нужно выяснить значения маркера для групп "VPN" и "Domain VPN". Сделать это можно, добавив какие-либо устройства в эти группы (нужно знать IP адреса устройст) и посмотреть командой iptables-save | grep MARK каким IP адресам какой -j MARK присваивается. Например, для политики "VPN" мы увидим -j MARK --set-xmark 0xffffd00/0xffffffff, а для "Domain VPN" -j MARK --set-xmark 0xffffd02/0xffffffff. Запомним.

Настройка iptables

Базовые принципы работы iptables Описаны тут. Хотя есть один нюанс, не описанный в этой статье. После цепочки OUTPUT (локальный трафик) будет произведен re-routing, если были изменения в метках MARK пакета.

Создаем файл /opt/root/iptables_mangle_vpn.sh. После создания конечно даем права на исполнение, про это не буду далее напоминать.

[ -n "$(iptables-save | grep DOMAIN_VPN)" ] && exit 0

iptables -t mangle -N DOMAIN_VPN

iptables -t mangle -A DOMAIN_VPN -j MARK --set-mark 0xffffd00
iptables -t mangle -A DOMAIN_VPN -j CONNMARK --save-mark --nfmask 0xffffffff --ctmask 0xffffffff

iptables -t mangle -A PREROUTING -p all -m mark --mark 0xffffd02 -m set --match-set unblock dst -j DOMAIN_VPN
iptables -t mangle -A OUTPUT -p udp -d 1.1.1.1 --dport 53 -j DOMAIN_VPN
iptables -t mangle -A OUTPUT -p udp -d 8.8.8.8 --dport 53 -j DOMAIN_VPN

Давайте разберемся. Скрипт будет запускаться многократно из-за нюансов работы Keenetic, он очень часто сбрасывает iptables таблицы к исходному состоянию по своим внутренним причинам. Поэтому проверяем, существует ли наша цепочка в правилах. Меняем таблицу mangle. Наша задача - пометить пакеты, которые в группе "Domain VPN" и которые идут по указанному в настройках dnsmasq доменному имени, меткой от группы "VPN", чтобы роутинг таких пакетов пошел по пути "VPN". Итак, ловим пакеты, которые

  • -p all - любой протокол
  • -m mark --mark 0xffffd02 - инициатор пакета находится в группе "Domain VPN"
  • -m set --match-set unblock dst - IP адрес назначения соответствует списку IP адресов "unblock". Этот ipset будет постоянно обновляться нашим DNS сервером на лету.
  • Дополнительно ловим DNS запросы из OUTPUT. Это локально сгенерированные DNS запросы от dnsmasq. Транзитные DNS запросы, например, если у клиента используется DNS сервер 8.8.8.8 - пойдут без VPN.

Все пакеты, соответствующие этим условиям помечаем меткой от группы "VPN". Соответственно, на этапе роутинга эти пакеты пойдут по пути, определенному политикой "VPN", то есть через наше VPN подключение.

Теперь этот скрипт можно запустить вручную и проверить работу. Если что-то не так - можно перезагрузить роутер. В автозагрузку добавлять только после того как все протестировано! Для добавления в автозагрузку (формально это не совсем автозагрузка, скрипт вызывается роутером в момент очистки и перезагрузки определенной таблицы iptables, таблица nat и mangle перезагружается роутером многократно) создадим файл /opt/etc/ndm/netfilter.d/iptables_mangle_vpn_reload.sh с содержимым:

#!/bin/sh

[ "$type" == "ip6tables" ] && exit 0   # check the protocol type in backward-compatible way
[ "$table" == "mangle" ] || exit 0   # check the table name

logger "iptables $table reloaded: load /opt/root/iptables_mangle_vpn.sh"

/opt/root/iptables_mangle_vpn.sh

Полезное для диагностики:

  • iptables-save | grep DOMAIN_VPN - покажет все добавленные вами правила