├── ALL_SHADOWSOCKS.md ├── README.md ├── SHADOWSOCKS_TCP.md ├── SHADOWSOCKS_TCP_UDP.md ├── VPN.md └── VPN_SHADOWSOCKS.md /ALL_SHADOWSOCKS.md: -------------------------------------------------------------------------------- 1 | # Предварительные условия 2 | Вы поняли и попробовали все, что описано в [Перенаправление TCP и UDP трафика на внешний Shadowsocks сервер](SHADOWSOCKS_TCP_UDP.md). Инструкция будет на основе этой статьи и очевидные вещи повторяться не будут. 3 | 4 | # Идея 5 | Перенаправлять весь трафик с одной из Policy Group Keenetic в SS + локальный трафик самого роутера. Так, чтобы не было утечек мимо SS. Таким образом можно перенаправить только TCP и UDP трафик, остальное будет обтрасываться. Это может не подойти в некоторых ситуациях, так что, конечно, не заменяет VPN. Зато работает максимально быстро и покрывает 99% потребностей обычных пользователей, которые не используют более специализированные протоколы. 6 | 7 | # Поехали 8 | Настраиваем Shadowsocks клиент в режиме ss-redir, TCP and UDP как описано в [Перенаправление TCP и UDP трафика на внешний Shadowsocks сервер](SHADOWSOCKS_TCP_UDP.md), можно опустить все что связано с dnsmasq, т.к. пока перенаправление в зависимости от доменного имени использовать не будем. А также можно опустить правила iptables, они будут другие. 9 | 10 | [Настраиваем роутинг для TPROXY UDP](https://github.com/Sharm/keenetic-domain-routing/blob/master/SHADOWSOCKS_TCP_UDP.md#%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0-%D1%80%D0%BE%D1%83%D1%82%D0%B8%D0%BD%D0%B3%D0%B0) 11 | 12 | ## Настройка переадресации iptables 13 | Создаем файл `/opt/root/iptables_nat.sh`. После создания конечно даем права на исполнение, про это не буду далее напоминать. 14 | ```bash 15 | #!/bin/sh 16 | 17 | [ -n "$(iptables-save | grep SS_TCP)" ] && exit 0 18 | 19 | # Create new chain 20 | iptables -t nat -N SS_TCP 21 | iptables -t nat -N SS_TCP_LOCAL 22 | 23 | # Anything else should be redirected to shadowsocks's local port 24 | iptables -t nat -A SS_TCP -p tcp -m mark --mark 0xffffd01 -j REDIRECT --to-ports 1080 25 | 26 | # Ignore your shadowsocks server's addresses 27 | iptables -t nat -A SS_TCP_LOCAL -p tcp -d xx.xx.xx.xx --dport 443 -j RETURN 28 | 29 | iptables -t nat -A SS_TCP_LOCAL -o eth3 -p tcp -j REDIRECT --to-ports 1080 30 | 31 | # Apply the rules to transit packets 32 | iptables -t nat -A PREROUTING -p tcp -j SS_TCP 33 | iptables -t nat -A OUTPUT -p tcp -j SS_TCP_LOCAL 34 | ``` 35 | В отличие от прошлых правил, появилась цепочка SS_TCP_LOCAL из OUTPUT. Теперь мы гоним в SS не только транзитный трафик, но и со всех процессов самого роутера. Под эти правила будет попадать в том числе трафик из самого ss-redir, поэтому важно игнорировать SS сервер. Замените `xx.xx.xx.xx` на адрес вашего сервера. Также обратите внимение на `-o eth3`, это интерфейс провайдера, возможно вам следует заменить на другое имя. Важно, чтобы правило не применялось для пакетов, идущих между локальными сегментами сети. 36 | 37 | Создаем файл `/opt/root/iptables_mangle.sh` 38 | ```bash 39 | #!/bin/sh 40 | 41 | [ -n "$(iptables-save | grep SS_UDP)" ] && exit 0 42 | 43 | [ -z "$(lsmod | grep xt_TPROXY)" ] && \ 44 | insmod /lib/modules/$(uname -r)/xt_TPROXY.ko 45 | 46 | iptables -t mangle -N SS_UDP_LOCAL 47 | iptables -t mangle -N SS_UDP_TRANSIT 48 | 49 | iptables -t mangle -A SS_UDP_TRANSIT -d 10.0.0.0/8 -j RETURN 50 | iptables -t mangle -A SS_UDP_TRANSIT -d 127.0.0.0/8 -j RETURN 51 | iptables -t mangle -A SS_UDP_TRANSIT -d 169.254.0.0/16 -j RETURN 52 | iptables -t mangle -A SS_UDP_TRANSIT -d 192.168.0.0/16 -j RETURN 53 | iptables -t mangle -A SS_UDP_TRANSIT -d 224.0.0.0/4 -j RETURN 54 | iptables -t mangle -A SS_UDP_TRANSIT -d 240.0.0.0/4 -j RETURN 55 | 56 | iptables -t mangle -A SS_UDP_TRANSIT -p udp -m mark --mark 0xffffd01 -j TPROXY --on-port 1080 --tproxy-mark 1 57 | iptables -t mangle -A SS_UDP_TRANSIT -i lo -p udp -m mark --mark 1 -j TPROXY --on-port 1080 --tproxy-mark 1 58 | 59 | iptables -t mangle -A SS_UDP_LOCAL -p udp -d xx.xx.xx.xx --dport 443 -j RETURN 60 | 61 | # Important to select provider interface (eth3). Otherwise VPN shouldn't work. 62 | iptables -t mangle -A SS_UDP_LOCAL -o eth3 -p udp -j MARK --set-mark 1 63 | 64 | iptables -t mangle -A PREROUTING -j SS_UDP_TRANSIT 65 | iptables -t mangle -A OUTPUT -j SS_UDP_LOCAL 66 | ``` 67 | Тоже самое, в отличие от прошлый правил, гоним **весь** локальный UDP через SS, а не только DNS. `-o eth3` - важно, чтобы не испортить VPN трафик между другими интерфейсами, а также локальный. В SS_UDP_TRANSIT вынуждены локальный трафик игнорировать явно, потмоу что в PREROUTING еще нет информации о выходном интерфейсе, это станет понятно только после роутинга. 68 | 69 | Добавляем оба скрипта в автозагрузку `/opt/etc/ndm/netfilter.d/`, как было описано ранее. 70 | 71 | ## Настройка переадресации iptables - защита от утечек 72 | Мы разобрались с UDP и TCP трафиком, но что с остальными? Нужно явно фильтровать его. 73 | 74 | Создаем файл `/opt/root/iptables_filter.sh` 75 | ```bash 76 | #!/bin/sh 77 | 78 | [ -n "$(iptables-save | grep SS_FLT)" ] && exit 0 79 | 80 | iptables -t filter -N SS_FLT 81 | 82 | # Other VPN connections and lan should work 83 | iptables -t filter -A OUTPUT -o eth3 -j SS_FLT 84 | iptables -t filter -I FORWARD -o eth3 -m mark --mark 0xffffd01 -j SS_FLT 85 | 86 | iptables -t filter -A SS_FLT -p udp -d xx.xx.xx.xx --dport 443 -j RETURN 87 | iptables -t filter -A SS_FLT -p tcp -d xx.xx.xx.xx --dport 443 -j RETURN 88 | iptables -t filter -A SS_FLT -m mark --mark 1 -j RETURN 89 | iptables -t filter -A SS_FLT -p tcp -m tcp --dport 1080 -j RETURN # accept local generated packets to outside, ex wget ya.ru 90 | iptables -t filter -A SS_FLT -p all -j REJECT 91 | ``` 92 | Явно разрешаем только соединения на SS сервер и помеченные пакеты. Помеченные - это UDP трафик, идущий через TPROXY, у них будет оригинальный destination и по IP такие пакеты поймать невозможно. Все остальное REJECT. Обратите внимание на `iptables -t filter -I FORWARD` -I добавит правило в начало цепочки. Обычно на Keenetic FORWARD цепочка имеет policy DROP и содержит правила на ACCEPT, после срабатывания которых дальше уже проверка не пойдет. Поэтому надо нашу цепочку поставить **до** стандартных правил. 93 | 94 | Теперь этот скрипт можно запустить вручную и проверить работу. Если что-то не так - можно перезагрузить роутер. **В автозагрузку добавлять только после того как все протестировано!** Для добавления в автозагрузку создадим файл `/opt/etc/init.d/S55_iptables_filter.sh` (S в начале имени файла - важно, означает, что скрипт нужно будет запустить с параметром start) с содержимым: 95 | ```bash 96 | #!/bin/sh 97 | [ "$1" != "start" ] && exit 0 98 | 99 | /opt/root/iptables_filter.sh 100 | 101 | logger "startup iptables_filter.sh configured" 102 | ``` 103 | Кроме того, полезно создать файл `/opt/etc/ndm/netfilter.d/iptables_filter_reload.sh` с содержимым ниже. Он будет дергаться в момент перезагрузки роутером таблицы filter. Хотя в моем случае я с таким поведением роутера ни разу не встретился. 104 | ```bash 105 | #!/bin/sh 106 | 107 | [ "$type" == "ip6tables" ] && exit 0 # check the protocol type in backward-compatible way 108 | [ "$table" == "filter" ] || exit 0 # check the table name 109 | 110 | logger "iptables $table reloaded: load /opt/root/iptables_filter.sh" 111 | 112 | /opt/root/iptables_filter.sh 113 | ``` 114 | 115 | ## Проверка 116 | Как минимум теперь нужно проверить, что `ping` до интернет узлов не работат. Как с локальных устройств, так и с самого роутера. 117 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Выборочный роутинг на основе доменного имени с использованием Keenetic, dnsmasq, shadowsocks, любой vpn (рекомендую wireguard). 2 | 3 | # Введение 4 | Репозиторий будет пополняться разными способами перераспределить трафик из локальной сети на разных провайдеров, VPN, Shadowproxy в зависимости от домена, к которому обращается пользователь. Задача сделать такую систему, которую можно было бы держать включенной всегда, сохраняя максимально возможную скорость соединений и при этом максимально быстро и легко настроить и поддерживать. 5 | 6 | # Проблематика 7 | Обычно перенаправления соединений, VPN и пакетов TCP/UDP происходит на сетевом или транспортном уровне OSI, тогда как имя домена может быть обнаружено только на прикладном. Ключ к решению проблемы - свой DNS сервер на основе dnsmasq. Его приятной особенностью является то, что он может автоматически заполнять ipset списки ip адресами, которые зарезолвил. Этим мы и будем пользоваться. 8 | 9 | # Инструменты 10 | - Shadowsocks. Очень быстрый прокси с шифрованием и обфускацией трафика. Шифрование далеко не самое стойкое. Обфускация хорошая, тем не менее, уже появляются сообщения, что в редких случаях можно задетектить SS, особенно в UDP режиме. 11 | - v2ray. Прокси для более надежной обфускации и маскировки трафика под HTTP/TLS. Пока самый стойкий к обнаружению метод. 12 | - Wireguard. Современный VPN. Самый быстрый среди всех известных VPN и самый безопасный, работает на уровне Linux Kernel. Лучшее решение для VPN на сегодня. Не обфусцирует трафик, соответственно обнаруживается элементарно. 13 | 14 | # Оборудование 15 | Keenetic Giga (KN-1011), KeeneticOS 3.9.5 16 | 17 | *Последнее тестирование было на KeeneticOS 4.1.7 - полет нормальный.* 18 | 19 | # Способы реализации 20 | 1. Перенаправление только TCP пакетов с использованием Shadowsocks. Достаточно простой в настройке способ. Дает самую высокую скорость. Подойдет, если достаточно перенаправлять только TCP (если система в основном для перенаправления HTTP, т.е. для работы с сайтами, то вполне подойдет) и если не боитесь утечек в основной канал UDP (в том числе DNS) и других протоколов. Кстати, почти все браузеры уже делают DNS запросы на HTTPS сайты по TCP. Для игр, видео, видеосвязи, аудио может не подойти по вышеописанным причинам. [Перенаправление TCP трафика на внешний Shadowsocks сервер](SHADOWSOCKS_TCP.md) 21 | 2. Перенаправление TCP и UDP пакетов с использованием Shadowsocks. Сложный для настройки способ. Развитие предыдущего пункта. Поможет перенаправить как DNS запросы, так и другие UDP пакеты. Тем не менее, риск утечек в основной канал других протоколов остается, например ICMP. [Перенаправление TCP и UDP трафика на внешний Shadowsocks сервер](SHADOWSOCKS_TCP_UDP.md) 22 | 3. Перенаправление на VPN. Самый простой в настройке способ. И почти самый быстрый, если использовать Wireguard, то чуть проигрывает Shadowsocks, на 10-20%. Если не знаете что выбрать - выбирайте этот способ. Из минусов можно отметить только отсутствие обфускации, т.е. ваш тунель будет виден. [Перенаправление всего трафика на VPN](VPN.md) 23 | 4. Перенаправление на VPN поверх Shadowsocks. Все преимущества предыдущего варианта, но с обфускацией от shadowsocks. К сожалению, скорость падает в 5-6 раз относительно чистого Wireguard VPN или чистого Shadowsocks. Поэтому вариант компромиссный. [VPN over Shadowsocks](VPN_SHADOWSOCKS.md) 24 | 5. Специфическая конфигурация для гарантированного отсутствия утечек через основное соединение. Используется Shadowsocks, в который заворачивается весь TCP/UDP трафик. [Перенаправление всего трафика на SS без утечек](ALL_SHADOWSOCKS.md) 25 | 6. TODO. Перенаправление на VPN поверх Shadowsocks поверх v2ray. Все преимущества предыдущего варианта, но с дополнительной маскировкой под TLS от v2ray. Соответственно, еще медленее, но с практически с гарантией анонимности. 26 | -------------------------------------------------------------------------------- /SHADOWSOCKS_TCP.md: -------------------------------------------------------------------------------- 1 | # Предварительные условия 2 | У вас есть роутер Keenetic и поднят внешний сервер shadowsocks https://shadowsocks.org/. Про shadowsocks лучше почитать отдельно. В двух словах, это супер легкий прокси с обфускацией трафика. Серверная часть принимает обфусцированный трафик от клиентской части и перенаправляет его уже на целевые адреса. Клиентская часть принимает трафик, обфусцирует и отдает серверу. Принимает трафик клиентская часть несколькими способами: может притвориться SOCKS5 прокси, может быть прозрачным прокси и может принимать тунельный трафик от VPN. 3 | 4 | # Можно все сделать средствами Keenetic? 5 | В последних версиях KeeneticOS появился SOCKS5 прокси, который можно использовать для выхода в интернет. Казалось бы - идеальный вариант, Keenetic сам заворачивает все в SOCKS5 на клиент Shadowsocks и все настраивается из интерфейса. Вариант выглядел изначально странным, ведь "выход в интернет" в терминах Keenetic, это IP уровень (L3 OSI), а SOCKS5 - сеансовый (L5 OSI), таким образом уже становится очевидно, что ВЕСЬ трафик таким образом завернуть нельзя. OCKS5 клиент в Keenetic построен на базе проекта badvpn https://github.com/ambrop72/badvpn/tree/master/tun2socks, который не развивается с 2015 года. Возможно поэтому к качеству его работы есть вопросы, а главное, он не заворачивает даже UDP трафик, не говоря уже о других протоколах. То есть только TCP. А значит DNS запросы будут ходить мимо него, что вообще в целом означает, что такое подключение не может использоваться для полноценного выхода в интернет. Кроме того, в версии Keenetic OS 3.9.5 есть баг, которыйне прописывает дефолтный маршрут для "выхода в интернет". Исправлен уже в разработческих alpha версиях. Тем не менее, если вам нужен только TCP и все и не пугают возможные проблемы - можно попробовать его использовать, но подробно я это описывать не буду. 6 | 7 | # Поехали 8 | 1. Установить Entware, лучше во внутреннюю память роутера, но можно и на флешку. Все пакеты в памяти займут не больше 16Мб, такой объем есть на всех роутерах Keenetic. 9 | [Инструкция](https://help.keenetic.com/hc/ru/articles/360021888880-%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0-OPKG-Entware-%D0%BD%D0%B0-%D0%B2%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%BD%D1%83%D1%8E-%D0%BF%D0%B0%D0%BC%D1%8F%D1%82%D1%8C-%D1%80%D0%BE%D1%83%D1%82%D0%B5%D1%80%D0%B0) 10 | 11 | ***Update 2024:*** *Спустя год работы роутера в режиме жесткого отключения электропитания пару раз в месяц, внутренняя память роутера умерла. Так что не могу более советовать установку на внутреннюю память. Лучше на внешнюю флешку и не забывать делать бекапы всего диска с Entware. Интересно, что действительно, как и обещали разработчики Keenetic, умер только примонтированный раздел, ОС роутера продолжает работать штатно, что радует.* 12 | 13 | **ВАЖНО!** При маунте storage с папкой Install начинается процесс установки. Он может занять время, надо смотреть логи в "Диагностика" в интерфейсе. После установки будет доступен SSH с параметрами из логов. 14 | 15 | Получили доступ к SSH с Entware, заходим туда. 16 | 17 | 3. 18 | ```bash 19 | opkg update 20 | opkg install mc dnsmasq-full ipset iptables shadowsocks-libev-ss-redir shadowsocks-libev-config bind-dig 21 | ``` 22 | 23 | С первого раза может не установится из-за ограниченной памяти и скачивания всего сразу, можно выполнить второй раз. 24 | 25 | ## Настройка shadowsocks клиента. 26 | 27 | Запускать будем в режиме прозрачного прокси (ss-redir) и перенаправлять трафик на уровне iptables. 28 | Создать файл `/opt/etc/shadowsocks.json` с содержимым: 29 | ```json 30 | { 31 | "server":"99.99.99.99", 32 | "mode":"tcp_only", 33 | "server_port":443, 34 | "local_address":"0.0.0.0", 35 | "local_port":1080, 36 | "password":"0u8sdufh73", 37 | "timeout":300, 38 | "method":"chacha20-ietf-poly1305" 39 | } 40 | ``` 41 | Ну конечно меняем содержимое под настройки нашего внешнего сервера. Алгоритм `chacha20-ietf-poly1305` лучше не менять, из рекомендованных к использованию он самый быстрый. 42 | 43 | Редактируем `/opt/etc/init.d/S22shadowsocks`, нужно убедиться, что запуск и аргументы корректны, должно быть 44 | ```bash 45 | PROCS=ss-redir 46 | ARGS="-c /opt/etc/shadowsocks.json" 47 | ``` 48 | 49 | Теперь управление сервисом можно осуществлять через `/etc/init.d/S22shadowsocks start|stop|restart` 50 | 51 | **Полезное для диагностики:** 52 | - Запуск shadowsocks в консоли для просмотра вывода: `ss-redir -v -c /opt/etc/shadowsocks.json` 53 | - Проверка открытых портов `netstat -lnp` 54 | - Можно поменять на ss-local и проверить связку клиент-сервер SS, подключившись в SS клиенту на роутере (192.168.0.1:1080) как к SOCKS5 прокси. Можно для этого использовать средства браузера, расширений, таких как FoxyProxy или вообще скачать десктопный клиент Shadowsocks. 55 | 56 | ## Настройка переадресации iptables 57 | Самая важная часть. Базовые принципы работы iptables [Описаны тут](https://interface31.ru/tech_it/2020/02/osnovy-iptables-dlya-nachinayushhih-chast-1.html). Хотя есть один нюанс, не описанный в этой статье. После цепочки OUTPUT (локальный трафик) будет произведен re-routing, если были изменения в метках MARK пакета. Помимо этого основные знания, которые нам понадобятся: 58 | - В цепочку PREROUTING попадают только транзитные пакеты 59 | - В цепочку OUTPUT попадают только локально инициированные пакеты 60 | - В таблице nat можно изменить адрес назначения 61 | - В таблице mangle можно "помечать" (MARK) пакеты для дальнейшего роутинга как нам нужно через ip rule и ip route 62 | 63 | Создаем файл `/opt/root/iptables_nat.sh`. После создания конечно даем права на исполнение, про это не буду далее напоминать. 64 | ```bash 65 | #!/bin/sh 66 | 67 | [ -n "$(iptables-save | grep SS_TCP)" ] && exit 0 68 | 69 | # Disable ndnproxy this way, coz dns-override sometimes switches back after reboot. 70 | iptables -F _NDM_HOTSPOT_DNSREDIR -t nat 71 | 72 | ipset list unblock > /dev/null 2>&1 && ipset flush unblock # flush if set exists 73 | ipset create unblock hash:net -exist 74 | 75 | # Create new chain 76 | iptables -t nat -N SS_TCP 77 | 78 | # Anything else should be redirected to shadowsocks's local port 79 | iptables -t nat -A SS_TCP -p tcp -m mark --mark 0xffffd01 -m set --match-set unblock dst -j REDIRECT --to-ports 1080 80 | 81 | # Apply the rules to transit packets 82 | iptables -t nat -A PREROUTING -p tcp -j SS_TCP 83 | ``` 84 | 85 | Давайте разберемся. Скрипт будет запускаться многократно из-за нюансов работы Keenetic, он очень часто сбрасывает iptables таблицы к исходному состоянию по своим внутренним причинам. Поэтому проверяем, существует ли наша цепочка в правилах. Меняем таблицу nat. Отключаем цепочку, которая перенаправляет DNS запросы на внутренний DNS сервер Keenetic. В теории должно быть достаточно команд 86 | ``` 87 | opkg dns-override 88 | system configuration save 89 | system reboot 90 | ``` 91 | но у меня такая конфигурация срабатывала через раз после перезагрузки роутера. А после обновления прошивки вообще перестала работать. Поэтому был найден дополнительный способ отключения. Тем не менее, сделать эти команды все-же в любом случае надо, иначе dnsmasq не сможет поднятся на стандартном 53 порту. Далее сначала очищаем, потом создаем ipset, в который в последствии будет писать dnsmasq. Очистка периодически нужна, потому что после длительного использования некоторые IP адреса могут начать использоваться другими сайтами, которые мы не хотим вести в SS. Создаем цепочку SS_TCP, в которую уходят tcp пакеты на этапе PREROUTING. **Важно!** в PREROUTING попадают только транзитные пакеты. Сгенерированные на роутере пакеты попадут в OUTPUT. Перенаправление происходит по нескольким условиям 92 | 1. `-m mark --mark 0xffffd01` 93 | Это метка, которая ставится роутером в зависимости от нахождения хоста-инициатора пакета в политике доступа в интернет ("приоритеты подключений" в интерфейсе Keenetic). Таким образом, мы можем управлять для каких клиентов включить такое перенаправление. Чтобы узнать метку, сделайте `iptables-save | grep MARK` и посмотрите каким IP адресам какие метки присваиваются, по ним можно будет понять у какой группы какая метка. 94 | 2. `-m set --match-set unblock dst` 95 | IP адрес назначения соответствует списку IP адресов "unblock". Этот ipset будет постоянно обновляться нашим DNS сервером на лету. 96 | 97 | Теперь этот скрипт можно запустить вручную и проверить работу. Если что-то не так - можно перезагрузить роутер. **В автозагрузку добавлять только после того как все протестировано!** Для добавления в автозагрузку (формально это не совсем автозагрузка, скрипт вызывается роутером в момент очистки и перезагрузки определенной таблицы iptables, таблица nat и mangle перезагружается роутером многократно) создадим файл `/opt/etc/ndm/netfilter.d/iptables_nat_reload.sh` с содержимым: 98 | ```bash 99 | #!/bin/sh 100 | 101 | [ "$type" == "ip6tables" ] && exit 0 # check the protocol type in backward-compatible way 102 | [ "$table" == "nat" ] || exit 0 # check the table name 103 | 104 | logger "iptables $table reloaded: load /opt/root/iptables_nat.sh" 105 | 106 | /opt/root/iptables_nat.sh 107 | ``` 108 | 109 | **Полезное для диагностики:** 110 | - `iptables-save | grep SS_TCP` - покажет все добавленные вами правила 111 | 112 | ## Настройка DNS сервера dnsmasq 113 | DNS сервер выполняет 2 задачи: 114 | 1. На основе домена заполняет ipset IP адресами, по которым будет фильтроваться трафик в iptables 115 | 2. Вышестоящий upstream DNS сервер будет выбираться также в зависимости от домена. Таким образом, для перечисленных адресов будут использоваться одни DNS серверы, для всех остальных - стандартный. Это даст возможность не потерять резолв локальных сетевых адресов. 116 | 117 | Добавим в конец файла `/opt/etc/dnsmasq.conf` 118 | ``` 119 | conf-file=/opt/etc/unblock.dnsmasq 120 | ``` 121 | Все настройки будем проводить в файле `/opt/etc/unblock.dnsmasq`, нужно его создать, например, с таким содержимым: 122 | ``` 123 | # Заполнить, если были локальные доменные имена, добавленные через ip host в Keenetic 124 | address=/example.lan/192.168.1.18 125 | 126 | # Команда для заполнения ipset 127 | ipset=/site.com/unblock 128 | ipset=/sitecdn.com/unblock 129 | 130 | # Команда для указания конкретного DNS сервера для резолва домена, никакие другие использоваться не будут. 131 | server=/site.com/1.1.1.1 132 | server=/site.com/8.8.8.8 133 | server=/sitecdn.com/1.1.1.1 134 | server=/sitecdn.com/8.8.8.8 135 | ``` 136 | Если на резолв локальных адресов пофиг, то можно просто глобавльно оставить постоянные upsream dns сервера `server=1.1.1.1` и не писать их для каждого домена отдельно. 137 | 138 | Заполнить по аналогии все нужные домены. Учтите, что `ipset=/example.com/` также включает в себя все домены 2,3 и тд уровней, то есть `my.example.com` тоже будет включен. 139 | 140 | Теперь нужно подключить hosts (для корректного резолва localhost) и resolv.conf (для поддягивания правильных upstream dns серверов для всех доменов, которые не были перечислены выше). Если на резолв локальных адресов пофиг, то resolv.conf можно не добавлять. Выполним команды: 141 | ```bash 142 | ln -s /var/hosts /opt/etc/hosts 143 | ln -s /var/resolv.conf /opt/etc/resolv.conf 144 | /opt/etc/init.d/S56dnsmasq restart 145 | ``` 146 | 147 | Если рестарт dnsmasq не работает, скорее всего из-за того, что порт занят стандартным DNS сервером. В этом случае выполняем: 148 | ``` 149 | opkg dns-override 150 | system configuration save 151 | system reboot 152 | ``` 153 | 154 | **Полезное для диагностики:** 155 | - Не забываем про кеш DNS. Сброс кеша на Windows: `ipconfig /flushdns`. Сам dnsmasq тоже кеширует результаты, по умолчанию на величину TTL, что логично. Но можно переопределить опцией `min-cache-ttl` в конфиге. 156 | - `nslookup example.com 192.168.0.1` 157 | - `dig @localhost example.com` 158 | - Смотрим логи в Диагностика->Системный журнал 159 | - Проверяем работу, чтобы убедиться что пакеты перенаправляются можно выключить временно shadowsocks: `/etc/init.d/S22shadowsocks stop` 160 | 161 | # Дополнительные материалы 162 | Многое описано на основе статей 163 | https://habr.com/ru/post/663862/ 164 | https://habr.com/ru/post/428992/ 165 | Но в них много ненужного и многое не работает. Тем не менее, спасибо авторам за идею, ключевая конечно это dnsmasq. 166 | -------------------------------------------------------------------------------- /SHADOWSOCKS_TCP_UDP.md: -------------------------------------------------------------------------------- 1 | # Предварительные условия 2 | Вы сделали все, что описано в [Перенаправление TCP трафика на внешний Shadowsocks сервер](SHADOWSOCKS_TCP.md) 3 | 4 | # Поехали 5 | Нельзя просто так взять и проксировать UDP, поэтому просто поддержки UDP у Shadowsocks недостаточно. Найти реальный адрес назначения в UDP возможности нет. Ну, почти нет. В линуксе для этого придумали специальный тип сокетов, Transparent Proxy, ключевые статьи для понимания: 6 | - https://lwn.net/Articles/252545/ 7 | - https://www.kernel.org/doc/Documentation/networking/tproxy.txt 8 | - https://powerdns.org/tproxydoc/tproxy.md.html 9 | 10 | Ключевой момент - мы не меняем на самом деле dst адрес у пакета, а заворачиваем его роутом на localhost. После этого iptables заворачивает все пакеты, идущие на localhost с меткой на порт Transparent Proxy. Выглядит, конечно, как костыль, но работает. 11 | 12 | ## Установка модуля iptables TPROXY 13 | Модуль нужен для перенаправления на специальные Transparent сокеты. Проверьте содержимое `/lib/modules/$(uname -r)/`, если там нет `xt_TPROXY.ko`, значит нужно доставить модули средствами Keenetic. Для этого нужно из интерфейса установить "Протокол IPv6" и "Модули ядра подсистемы Netfilter". Причем пакет "Модули ядра подсистемы Netfilter" появятся в интерфейсе только после установки "Протокол IPv6", т.е. перезагрузииться придется дважды. Если соберетесь использовать еще более широкие возможности iptables, можно установить еще "Пакет расширения Xtables-addons для Netfilter", появится только после установки первых двух. Но для TPROXY он не нужен. 14 | 15 | ## Настройка shadowsocks клиента на поддержку UDP 16 | 17 | Редактируем файл `/opt/etc/shadowsocks.json` месяем параметр `mode` 18 | ```json 19 | { 20 | "mode":"tcp_and_udp", 21 | } 22 | ``` 23 | И перезагружаем shadowsocks `/etc/init.d/S22shadowsocks restart` 24 | 25 | ## Настройка роутинга 26 | Создаем файл `/opt/etc/init.d/S55_ip_route_tproxy.sh` (`S` в начале имени файла - важно, означает, что скрипт нужно будет запустить с параметром start) 27 | ```bash 28 | #!/bin/sh 29 | [ "$1" != "start" ] && exit 0 30 | 31 | ip route add local default dev lo table 100 32 | ip rule add fwmark 1 lookup 100 33 | 34 | logger "ip route for TPROXY configured" 35 | ``` 36 | Разберемся что происходит. Выполняется всего 2 простые команды, первая заворачивает все, направленное на `0.0.0.0/0` на localhost и записывает это правило в таблицу 100. Вторая команда говорит о том, что если пакет помечен `fwmark 1`, то должна использоваться таблица маршрутизации 100. Далее средствами iptables мы будем помечать пакеты. 37 | 38 | **Полезное для диагностики:** 39 | - `ip rule` - выведет список всех правил. Правила упорядочены по приоритету. Убедитесь, что таблицы `main` и `default` имеют приоритет ниже, чет таблица 100, в противном случае, несмотря на маркерованный пакет, будет использована таблица `main`. 40 | - `ip route list table 100` - выведет правила пмаршрутизации конкретной таблицы. 41 | 42 | ## Настройка переадресации iptables 43 | Базовые принципы работы iptables [Описаны тут](https://interface31.ru/tech_it/2020/02/osnovy-iptables-dlya-nachinayushhih-chast-1.html). Хотя есть один нюанс, не описанный в этой статье. После цепочки OUTPUT (локальный трафик) будет произведен re-routing, если были изменения в метках MARK пакета. 44 | 45 | Создаем файл `/opt/root/iptables_mangle.sh` 46 | ```bash 47 | #!/bin/sh 48 | 49 | [ -n "$(iptables-save | grep SS_UDP)" ] && exit 0 50 | 51 | [ -z "$(lsmod | grep xt_TPROXY)" ] && \ 52 | insmod /lib/modules/$(uname -r)/xt_TPROXY.ko 53 | 54 | iptables -t mangle -N SS_UDP_LOCAL 55 | iptables -t mangle -N SS_UDP_TRANSIT 56 | 57 | iptables -t mangle -A SS_UDP_TRANSIT -p udp -m mark --mark 0xffffd01 -m set --match-set unblock dst -j TPROXY --on-port 1080 --tproxy-mark 1 58 | iptables -t mangle -A SS_UDP_TRANSIT -i lo -p udp -d 1.1.1.1 --dport 53 -j TPROXY --on-port 1080 --tproxy-mark 1 59 | iptables -t mangle -A SS_UDP_TRANSIT -i lo -p udp -d 8.8.8.8 --dport 53 -j TPROXY --on-port 1080 --tproxy-mark 1 60 | 61 | iptables -t mangle -A SS_UDP_LOCAL -p udp -d 1.1.1.1 --dport 53 -j MARK --set-mark 1 62 | iptables -t mangle -A SS_UDP_LOCAL -p udp -d 8.8.8.8 --dport 53 -j MARK --set-mark 1 63 | 64 | iptables -t mangle -A PREROUTING -j SS_UDP_TRANSIT 65 | iptables -t mangle -A OUTPUT -j SS_UDP_LOCAL 66 | ``` 67 | 68 | Давайте разберемся. Меняем таблицу mangle. Скрипт будет запускаться многократно из-за нюансов работы Keenetic, он очень часто сбрасывает iptables таблицы к исходному состоянию по своим внутренним причинам. Поэтому проверяем, существует ли наша цепочка в правилах. Включаем модуль `xt_TPROXY.ko`, если еще не включен. Далее создаем цепочки SS_UDP_LOCAL и SS_UDP_TRANSIT. **Важно!** в PREROUTING попадают только транзитные пакеты и затем в цепочку SS_UDP_TRANSIT. Сгенерированные на роутере пакеты попадут в OUTPUT и затем в SS_UDP_LOCAL. Транзитные UDP пакеты помечаем и перенаправляем на порт Shadowsocks. Пометка будет использоваться в роутинге на localhost. 69 | Перенаправление происходит по нескольким условиям 70 | 1. `-m mark --mark 0xffffd01` 71 | Это метка, которая ставится роутером в зависимости от нахождения хоста-инициатора пакета в политике доступа в интернет ("приоритеты подключений" в интерфейсе Keenetic). Таким образом, мы можем управлять для каких клиентов включить такое перенаправление. Чтобы узнать метку, сделайте `iptables-save | grep MARK` и посмотрите каким IP адресам какие метки присваиваются, по ним можно будет понять у какой группы какая метка. 72 | 2. `-m set --match-set unblock dst` 73 | IP адрес назначения соответствует списку IP адресов "unblock". Этот ipset будет постоянно обновляться нашим DNS сервером на лету. 74 | 75 | Перенаправления для 1.1.1.1 и 8.8.8.8 имеют следующий смысл. Мы хотим, чтобы DNS запросы на указанные в dnsmasq домены проходили через прокси. Для этого необходимо 2 вещи: 76 | 1. Перенаправить DNS запросы от dnsmasq в сторону upstream серверов на localhost. Так как dnsmasq генерит запросы локально, это цепочка OUTPUT и SS_UDP_LOCAL. Они помечаются, после чего произойдет re-routing таких пакетов. 77 | 2. После такого перенаправления пакеты попадут в PREROUTING как транзитные, но с локального хоста. Их мы отправляем в Shadowsocks. Таким образом, локально сгенерированные DNS запросы к 1.1.1.1 и 8.8.8.8 пойдут через прокси, а транзитные (если клиент делает запрос на 1.1.1.1) пойдут по основному соединению. 78 | 79 | Теперь этот скрипт можно запустить вручную и проверить работу. Если что-то не так - можно перезагрузить роутер. **В автозагрузку добавлять только после того как все протестировано!** Для добавления в автозагрузку (формально это не совсем автозагрузка, скрипт вызывается роутером в момент очистки и перезагрузки определенной таблицы iptables, таблица nat и mangle перезагружается роутером многократно) создадим файл `/opt/etc/ndm/netfilter.d/iptables_mangle_reload.sh` с содержимым: 80 | ```bash 81 | #!/bin/sh 82 | 83 | [ "$type" == "ip6tables" ] && exit 0 # check the protocol type in backward-compatible way 84 | [ "$table" == "mangle" ] || exit 0 # check the table name 85 | 86 | logger "iptables $table reloaded: load /opt/root/iptables_mangle.sh" 87 | 88 | /opt/root/iptables_mangle.sh 89 | ``` 90 | 91 | **Полезное для диагностики:** 92 | - `iptables-save | grep SS_UDP` - покажет все добавленные вами правила 93 | - `nslookup example.com 192.168.0.1` 94 | - `dig @localhost example.com` 95 | - `tcpdump -i lo -p udp` 96 | -------------------------------------------------------------------------------- /VPN.md: -------------------------------------------------------------------------------- 1 | # Предварительные условия 2 | У вас есть роутер Keenetic, поднят внешний сервер VPN и стандартными средствами Keenetic к нему подключен тунель. Статья про перенаправление трафика в зависимости от домена, а не про настройку VPN. Тем не менее, рекомендую использовать Wireguard, как самый быстрый и безопасный. 3 | 4 | # Основная идея 5 | Максимально будем использовать встроенные средства Keenetic, а именно - политики доступа в интернет. Это позволит нам гибко контроллировать как способ выхода в интернет через VPN: например, для смены OpenVPN на Wireguard не придется лезть в консоль, все можно будет сделать из интерфейса, так и контроллировать какие именно устройства получат возможность использовать перенаправление в зависимости от доменного имени. В случае каких-то проблем, можно будет отключить не лазая в консоль. 6 | 7 | # Поехали 8 | 1. Установить Entware, лучше во внутреннюю память роутера, но можно и на флешку. Все пакеты в памяти займут не больше 16Мб, такой объем есть на всех роутерах Keenetic. 9 | [Инструкция](https://help.keenetic.com/hc/ru/articles/360021888880-%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0-OPKG-Entware-%D0%BD%D0%B0-%D0%B2%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%BD%D1%83%D1%8E-%D0%BF%D0%B0%D0%BC%D1%8F%D1%82%D1%8C-%D1%80%D0%BE%D1%83%D1%82%D0%B5%D1%80%D0%B0) 10 | 11 | **ВАЖНО!** При маунте storage с папкой Install начинается процесс установки. Он может занять время, надо смотреть логи в "Диагностика" в интерфейсе. После установки будет доступен SSH с параметрами из логов. 12 | 13 | Получили доступ к SSH с Entware, заходим туда. 14 | 15 | 2. 16 | ```bash 17 | opkg update 18 | opkg install mc dnsmasq-full ipset iptables 19 | ``` 20 | 21 | С первого раза может не установится из-за ограниченной памяти и скачивания всего сразу, можно выполнить второй раз. 22 | 23 | ## Настройка DNS сервера dnsmasq 24 | Настраиваем dnsmasq в точности как [описано тут:](SHADOWSOCKS_TCP.md#настройка-dns-сервера-dnsmasq) 25 | 26 | ## Подготовка политик доступа 27 | Будем максимально использовать возможность Keenetic, доступные из интерфейса. Переходим в "Приоритеты подключений" в интерфейсе. Нам нужно создать 2 новые политики доступа. Одна будет использоваться для реального выхода в интернет через VPN, вторая - для включения перенаправления в зависимости от домена. 28 | 1. Первую назовем "VPN". И настроим ее так, чтобы все устройства, подключенные к этой политике, всегда выходили в интернет только через VPN соединение. Для этого оставляем галочку только у VPN соединения. 29 | 2. Вторую назовем "Domain VPN". Настроим выход в интернет как по умолчанию, через основного провайдера. В дальнейшем все устройства, которые будут подключены к этой политике будут на самом деле использовать политику "VPN" для подключения к адресам, доменные имена которых указаны в настройках dnsmasq. При подключении ко всем остальным будет использоваться стандартная политика, настроенная в "Domain VPN" 30 | 31 | 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`. Запомним. 32 | 33 | ## Настройка iptables 34 | Базовые принципы работы iptables [Описаны тут](https://interface31.ru/tech_it/2020/02/osnovy-iptables-dlya-nachinayushhih-chast-1.html). Хотя есть один нюанс, не описанный в этой статье. После цепочки OUTPUT (локальный трафик) будет произведен re-routing, если были изменения в метках MARK пакета. 35 | 36 | Создаем файл `/opt/root/iptables_mangle_vpn.sh`. После создания конечно даем права на исполнение, про это не буду далее напоминать. 37 | ```bash 38 | [ -n "$(iptables-save | grep DOMAIN_VPN)" ] && exit 0 39 | 40 | iptables -t mangle -N DOMAIN_VPN 41 | 42 | iptables -t mangle -A DOMAIN_VPN -j MARK --set-mark 0xffffd00 43 | iptables -t mangle -A DOMAIN_VPN -j CONNMARK --save-mark --nfmask 0xffffffff --ctmask 0xffffffff 44 | 45 | iptables -t mangle -A PREROUTING -p all -m mark --mark 0xffffd02 -m set --match-set unblock dst -j DOMAIN_VPN 46 | iptables -t mangle -A OUTPUT -p udp -d 1.1.1.1 --dport 53 -j DOMAIN_VPN 47 | iptables -t mangle -A OUTPUT -p udp -d 8.8.8.8 --dport 53 -j DOMAIN_VPN 48 | ``` 49 | Давайте разберемся. Скрипт будет запускаться многократно из-за нюансов работы Keenetic, он очень часто сбрасывает iptables таблицы к исходному состоянию по своим внутренним причинам. Поэтому проверяем, существует ли наша цепочка в правилах. Меняем таблицу mangle. Наша задача - пометить пакеты, которые в группе "Domain VPN" и которые идут по указанному в настройках dnsmasq доменному имени, меткой от группы "VPN", чтобы роутинг таких пакетов пошел по пути "VPN". Итак, ловим пакеты, которые 50 | * `-p all` - любой протокол 51 | * `-m mark --mark 0xffffd02` - инициатор пакета находится в группе "Domain VPN" 52 | * `-m set --match-set unblock dst` - IP адрес назначения соответствует списку IP адресов "unblock". Этот ipset будет постоянно обновляться нашим DNS сервером на лету. 53 | * Дополнительно ловим DNS запросы из `OUTPUT`. Это локально сгенерированные DNS запросы от dnsmasq. Транзитные DNS запросы, например, если у клиента используется DNS сервер `8.8.8.8` - пойдут без VPN. 54 | 55 | Все пакеты, соответствующие этим условиям помечаем меткой от группы "VPN". Соответственно, на этапе роутинга эти пакеты пойдут по пути, определенному политикой "VPN", то есть через наше VPN подключение. 56 | 57 | Теперь этот скрипт можно запустить вручную и проверить работу. Если что-то не так - можно перезагрузить роутер. **В автозагрузку добавлять только после того как все протестировано!** Для добавления в автозагрузку (формально это не совсем автозагрузка, скрипт вызывается роутером в момент очистки и перезагрузки определенной таблицы iptables, таблица nat и mangle перезагружается роутером многократно) создадим файл `/opt/etc/ndm/netfilter.d/iptables_mangle_vpn_reload.sh` с содержимым: 58 | ```bash 59 | #!/bin/sh 60 | 61 | [ "$type" == "ip6tables" ] && exit 0 # check the protocol type in backward-compatible way 62 | [ "$table" == "mangle" ] || exit 0 # check the table name 63 | 64 | logger "iptables $table reloaded: load /opt/root/iptables_mangle_vpn.sh" 65 | 66 | /opt/root/iptables_mangle_vpn.sh 67 | ``` 68 | 69 | **Полезное для диагностики:** 70 | - `iptables-save | grep DOMAIN_VPN` - покажет все добавленные вами правила 71 | -------------------------------------------------------------------------------- /VPN_SHADOWSOCKS.md: -------------------------------------------------------------------------------- 1 | # Предварительные условия 2 | У вас есть роутер Keenetic, поднят внешний сервер VPN и стандартными средствами Keenetic к нему подключен тунель. Вероятно даже с использованием доменного перенаправления трафика, как описано тут: [Перенаправление всего трафика на VPN](VPN.md). А также поднят внешний сервер shadowsocks. 3 | 4 | # Основная идея 5 | Пустить трафик VPN через Shadowsocks для полной анонимизации трафика, потому что любые VPN туннели легко обнаруживаются. Для еще более сложно обнаружимой маскировки под SSL/TLS/Websocket можно использовать v2ray plugin, но это тема отдельной статьи. 6 | 7 | **ВАЖНО!** К сожалению, метод показал очень плохие результаты по скорости. Скорость падает в 5-6 раз относительно прямого соединения Wireguard или чистого Shadowsocks. Потому для меня он не подошел. Альтернатива `ss-tunnel` - полностью завернуть весь TCP и UDP трафик в Shadowsocks через ss-redir и iptables, включая любые туннели. Такое можно сделать, завернув весь локальный трафик роутера на SS, как описано тут [Перенаправление всего трафика на SS без утечек](ALL_SHADOWSOCKS.md). К сожалению, прироста в скорости он не дает никакого, так что нет смысла заморачиваться. 8 | 9 | # Поехали 10 | 1. Установить Entware, лучше во внутреннюю память роутера, но можно и на флешку. Все пакеты в памяти займут не больше 16Мб, такой объем есть на всех роутерах Keenetic. 11 | [Инструкция](https://help.keenetic.com/hc/ru/articles/360021888880-%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0-OPKG-Entware-%D0%BD%D0%B0-%D0%B2%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%BD%D1%83%D1%8E-%D0%BF%D0%B0%D0%BC%D1%8F%D1%82%D1%8C-%D1%80%D0%BE%D1%83%D1%82%D0%B5%D1%80%D0%B0) 12 | 13 | **ВАЖНО!** При маунте storage с папкой Install начинается процесс установки. Он может занять время, надо смотреть логи в "Диагностика" в интерфейсе. После установки будет доступен SSH с параметрами из логов. 14 | 15 | Получили доступ к SSH с Entware, заходим туда. 16 | 17 | 2. 18 | ```bash 19 | opkg update 20 | opkg install mc shadowsocks-libev-ss-tunnel shadowsocks-libev-config 21 | ``` 22 | 23 | С первого раза может не установится из-за ограниченной памяти и скачивания всего сразу, можно выполнить второй раз. 24 | 25 | ## Настройка shadowsocks клиента. 26 | 27 | Запускать будем в режиме туннеля (ss-tunnel). Для этого редактируем файл `/opt/etc/init.d/S22shadowsocks`, нужно убедиться, что запуск и аргументы корректны, должно быть 28 | ```bash 29 | PROCS=ss-tunnel 30 | ARGS="-s -p -l -L : -k -m chacha20-ietf-poly1305 -u" 31 | ``` 32 | Ну конечно меняем содержимое под настройки нашего внешнего сервера. Алгоритм `chacha20-ietf-poly1305` лучше не менять, из рекомендованных к использованию он самый быстрый. Главное отличие от стандартного запуска, аргумент `-L :` - это тот адрес сервера VPN, который вы вводите в VPN клиенте, подключаясь к нему напрямую. Теперь на этот адрес будет перенаправлять Shadowsocks. 33 | 34 | Теперь управление сервисом можно осуществлять через `/etc/init.d/S22shadowsocks start|stop|restart` 35 | 36 | После этого достаточно подключаться VPN клиентом не к серверу VPN напрямую, а на `127.0.0.1:` 37 | 38 | **Полезное для диагностики:** 39 | - Запуск shadowsocks в консоли для просмотра вывода: `ss-tunnel -v` 40 | - Проверка открытых портов `netstat -lnp` 41 | 42 | ## MTU 43 | Так как Shadowsocks увеличивает размер пакетов, нужно уменьшить MTU у интерфейсов VPN на клиенте и на сервере. Подробнее https://github.com/shadowsocks/shadowsocks-rust/issues/785 44 | --------------------------------------------------------------------------------