Openwrt обход блокировки tor
Если вы собираете пакеты для себя вручную, либо хотите встроить этот пакет прямо в прошивку то на этапе конфигурации прошивки OpenWRT нужно выбрать:
для сборки в виде пакета, или
для того чтобы встроить пакет прямо в прошивку. Затем собираете прошивку способом аналогичным описанному в моей предыдущей статье .
Несколько подводных камней, которые могут возникнуть после инсталляции пакета.
1. Обязательно настройте и синхронизируйте время чеpез ntp. Tor использует системное время для каких то своих действий. Неправильная дата может привести к проблемам при старте tor или к его не корректной работе.
2. При установке tor должен создать пользователя tor и группу tor. При создании группы инсталлятор у меня допустил ошибку и в файле /etc/group не поставил перенос строки для группы tor. Скорее всего это у меня единичный баг, однако будьте внимательны.
3. Проверьте все права на файлы необходимые tor они должны иметь маску 755 и принадлежать tor:tor
Настройка TOR.
Открываем конфигурационный файл /etc/tor/torrc и правим:
Где 192.168.120.1 – ip адрес вашего роутера для локальной сети, а 9100 – порт на котором будет socks сервер для сети tor.
2. Опциями SocksPolicy можно явно указать какие ip адреса будут иметь (или не иметь) доступ к socks серверу. В файле конфигурации эти опции закомментированы – рекомендую их раскомментировать и настроить под себя.
3. Если по каким то причинам tor не стартует воспользуетсь опцией Log для выяснения проблемы.
Собственно больше никаких настроек не нужно, и можно запускать tor.
Запуск Tor
Запускаем тор следующей командой:
Если tor уже запущен либо при старте возникают ошибки вида:
[warn] Could not bind to 127.0.0.1:9050: Address already in use. Is Tor already running?
необходимо остановить tor:
И запустить его заново как написано выше.
Если лог включен, то признаком успешного запуска и подключения к сети tor будет строка:
Feb 21 19:12:17.034 [notice] Tor has successfully opened a circuit. Looks like client functionality is working.
Feb 21 19:12:17.035 [notice] Bootstrapped 100%: Done.
Далее достаточно прописать адрес и порт указанный опцией SocksListenAddress как socks сервер в браузере или любой другой программе на вашем ПК.
Однако есть ряд программ которые не умеют работать с socks протоколом. Эту проблему можно решить средствами самого tor + iptables. Для этого необходимо включить в tor режим прозрачного проксирования. В таком случае на подключенных к роутеру машинах вообще никаких настроек делать не нужно. Весь трафик будет сразу проходить через tor.
Использование прозрачного прокси в Tor
Для этого в конфигурационном файле /etc/tor/torrc правим:
AutomapHostsOnResolve 1
TransPort 9040
DNSPort 53
Тем самым прозрачный прокси будет слушать порт 9040.
killall -9 tor
/etc/init.d/tor start
Далее необходимо весь трафик завернуть на этот порт. Для этого необходимо использовать iptables с опцией REDIRECT –to-port. Для использования этой опции необходимо дополнительно собрать и установить пакет iptables-mod-nat-extra. В противном случае вы получите ошибку вида:
iptables v1.4.6: unknown option `--to-ports'
Установить пакет можно тривиально выполнив
opkg install kmod-ipt-nat-extra
А можно собрать в своем репозитории или включить этот пакет сразу в прошивку. В конфигураторе OpenWrt этот пакет находится в
-> Network
-> iptables
iptables-mod-nat-extra
После установки пакета необходимо “завернуть” трафик на прозрачный прокси сервер:
iptables -t nat -A PREROUTING -p tcp -d ! 192.168.120.1 --dport 80 -j REDIRECT --to-ports 9040
Что означает – перебрасывать весь трафик идущий на 80-й порт (и не адресованый для 192.168.120.1) на порт 9040, на котором как раз и находится прозрачный прокси.
Тоже делаем и для dns запросов:
iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 53
Остальной udp трафик прийдется либо пропускать без анонимизации, либо резать.
Редактируем конфиги:
/etc/config/firewall
config zone
option name 'tor'
option network 'tor'
option input 'REJECT'
option forward 'REJECT'
option output 'ACCEPT'
config forwarding
option src 'tor'
option dest 'wan'
config rule
option name 'Allow DNS Queries'
option src 'tor'
option dest_port '53'
option proto 'tcpudp'
option target 'ACCEPT'
config rule
option name 'Allow DHCP request'
option src 'tor'
option src_port '67-68'
option dest_port '67-68'
option proto 'udp'
option target 'ACCEPT'
/etc/config/network
config interface 'tor'
option ifname 'wlan0-1'
option proto 'static'
option ipaddr '192.168.2.1'
option netmask '255.255.255.0'
/etc/config/wireless
config wifi-iface
option device 'radio0'
option network 'tor'
option mode 'ap'
option macaddr '00:01:4a:9f:6f:3c'
option encryption 'psk2'
option key '123456'
option ssid 'Tor_trans'
/etc/tor/torrc
VirtualAddrNetworkIPv4 10.192.0.0/10
AutomapHostsOnResolve 1
TransPort 9040
TransListenAddress 192.168.2.1
DNSPort 53
DNSListenAddress 192.168.2.1
iptables -F
iptables -t nat -F
iptables -t nat -A PREROUTING -i $_int_if -p udp --dport 53 -j REDIRECT --to-ports 53
iptables -t nat -A PREROUTING -i $_int_if -p tcp --syn -j REDIRECT --to-ports $_trans_port
I use a transparent proxy setup because I want to use a simple setup, especially for the user. A new client gets an IP-Address through DHCP, and can use the net. No need for any additional setup.
So that's why I'm doing it, but I guess there are lots of other situations where a transparent tor proxy can be usefull.
info about Tor: http://www.torproject.org/
info about the transparent proxy feature of Tor: https://trac.torproject.org/projects/tor/wiki/TheOnionRouter/TransparentProxy I set up an "Anonymizing Middlebox"
Setup:
I used a wgt634u with a recent backfire-svn checkout (r24007) it's a broadcom chip and I run a linux-2.6 kernel. I guess the stable backfire-release and any other architekture should work too but your router should have at least 32MB RAM (my tor-daemon needs about 13MB RAM) and enough Flash (8MB are enough).
I use only the wifi ("ath0") interface with own firewall-zone "tor" and restricted the access to the dhcp-server and tor-proxy only. But it will work with "br-lan" as well.
So everything is working so far.
The next thing I want to achieve is running a open captive portal an this device so that I can give the users some information. About Tor, Openwrt and about why I'm running this hotspot.
I took a look at nodogsquash but its firewall-rules doesn't seem to work with the redirections for the transparent proxy.
So any feedback on the HOWTO, or ideas about setting up a captive portal in this case, are appreciated!
Нужно простое и прозрачное для пользователей решение, которое, будучи единожды настроенным, позволит просто пользоваться интернетом, не задумываясь, что же сегодня заблокировали по заявкам очередных копирастов-плагиаторов.
Сама собой напрашивается мысль о том, чтобы обходить блокировку уже на домашнем маршрутизаторе.
Собственно, поднять на маршрутизаторе и гонять весь траффик через VPN несложно, а у некоторых VPN-провайдеров есть даже пошаговые инструкции по настройке OpenWrt на работу с ними.
Но скорости VPN сервисов все же отстают от скоростей доступа в интернет, да и VPN-сервис либо стоит денег, либо имеет массу ограничений, либо необходимость регулярного получения новых логинов. С точки зрения оптимизации затрат, как финансовых, так и временных, предпочтительней выглядит Tor, но его скорость еще хуже, а гонять через Tor торренты и вовсе идея не лучшая.
Выход — перенаправлять в VPN/Tor только траффик блокируемых ресурсов, пропуская остальной обычным путем.
Внимание: данная схема не обеспечивает анонимности просмотра заблокированных сайтов: любая внешняя ссылка раскрывает ваш настоящий IP.
Конкретная реализация на OpenWrt приведена в конце статьи. Если не интересуют подробности и альтернативные варианты решения, то можно листать сразу до нее.
Туннелирование и перенаправление траффика в туннель
Настройка VPN или Tor'а сложностей представлять не должна. Tor должен быть настроен, как прозрачный proxy (либо настроить связку из tor и tun2socks). Т.к. конечной целью явлется обход блокировок ркн, то в конфиге Tor'а целесообразно запретить использование выходных узлов на территории РФ ( ).
В Tor’а траффик перенаправляется правилом с REDIRECT ’ом на порт прозрачного прокси в цепочке PREROUTING таблицы nat netfilter’а.
Для перенаправления в VPN (или Tor + tun2socks) траффик маркируется в таблице mangle , метка затем используется для выбора таблицы маршрутизации, перенаправляющей траффик на соответствующий интерфейс.
В обоих случаях для классификации траффика используется ipset с хостами, подлежащими (раз)блокировке.
Формирование ipset c (раз)блокируемыми хостами
К сожалению, вариант «загнать все IP из реестра» в ipset не работает как хотелось бы: во-первых в списках присутствуют не все IP адреса блокируемых хостов, во-вторых в попытке уйти от блокировки IP адрес у ресурса может измениться (и провайдер об этом уже знает, а мы – еще нет), ну и в третьих – false positives для находящихся на том же shared hosting’е сайтов.
Городить огород с dpi того или иного вида не очень хочется: как-никак работать это должно на довольно слабом железе. Выход достаточно прост и в какой-то степени элегантен: dnsmasq (DNS сервер, который на маршрутизаторе скорее всего уже установлен) умеет при разрешении имен добавлять ip-адреса в соответствующий ipset (одноименная опция в конфиге). Как раз то, что нужно: вносим в конфиг все домены, которые необходимо разблокировать, и дальше по необходимости dnsmasq сам добавляет в ipset именно тот ip адрес, по которому будет идти обращение к заблокированному ресурсу.
У меня были сомнения, что dnsmasq запустится и будет нормально работать с конфигом в полдесятка тысяч строк (примерно столько записей в реестре после усушки и утряски), однако они к счастью оказались безосновательны.
Ложка дегтя в том, что при обновлении списка dnsmasq придется перезапускать, т.к. по SIGHUP он конфиг не перегружает.
Составление списка доменов
Должно происходить автоматически, насколько это возможно.
Теперь еще об одной ложке дегтя: некоторое провайдеры замечены за тем, что помимо включенных в список ркн сайтов самодеятельно блокируют и официально в списках не значащиеся. При этом блокируют тихой сапой и заглушки не выводят. Так что совсем без ручного привода не обойтись.
Дополнительные замечания
Реализация на OpenWrt (15.05)
Сам маршрутизатор должен быть не самый плохой, особенно при использовании Tor’а. MIPS 400MHz@32MB RAM это тот минимум, который стоит рассматривать.
При наличии USB-порта недостаток встроенного флеша можно компенсировать USB-флешкой(вообще мне представляется достаточно здравой идея не использовать встроенный флеш для регулярно перезаписываемых данных).
Штатно в прошивках OpenWrt содержится урезанный dnsmasq, не умеющий ipset. Необходимо заменить его на dnsmasq-full.
Из пакетов, по умолчанию не присутствующих, так же потребуются ipset, tor и tor-geoip.
Так же необходим либо пакет luasocket, либо (в режиме строгой экономии флеша) отдельно ltn12.luaв папке /usr/lib/lua. Для преобразования кириллических доменов из utf8 в punycode нужны idn.lua в /usr/lib/lua и пакет luabitop (либо отключить опции в конфиге скрипта).
Как человек постоянно работающий в интернете, я привык к полному и беспрепятственному доступу ко всем его ресурсам независимо от содержания данных ресурсов, а в силу того, что обеспечиваю работу части ресурсов (работаю в хостинг-провайдере), мне просто необходим такой доступ.
Обойти блокировки не так сложно, есть множество способов. Наиболее распространенный и стабильный из них — VPN. Но у VPN большой недостаток — это потеря скорости, завышается пинг и т.д. Исходя из этого, у меня возникла идея, использовать VPN только для обхода блокировок, а на остальные ресурсы ходить через провайдера.
Делать я это все буду на роутере TP-Link WR841N, чтобы обеспечить беспрепятственный доступ в интернет для всех сетевых устройств, а не только для рабочего компьютера.
Для начала нам потребуется поднять OpenVPN сервер или воспользоваться услугами VPN провайдера. Если же вы решите поднять собственный сервер, я бы рекомендовал использовать OpenVPN Access Server, т.к. с помощью него можно просто и быстро его развернуть, а также имеет веб-интерфейс. Достаточно просто установить пакет и задать пароль на учетную запись openvpn.
Итак, допустим у нас есть роутер с установленной прошивкой OpenWRT и OpenVPN. Правим файл-конфигурации подключения OpenVPN, у меня он находится в /etc/openvpn/my.cnf. Добавляем в него следующие параметры:
Создаем файл /etc/openvpn/login.conf в следующем формате:
Соответственно yourlogin и yourpassword нужно заменить на ваши авторизационные данные, если кто не понял.
Создаем скрипт /etc/openvpn/unban.sh, который будет выгружать список заблокированных IP и прописывать маршруты:
Опишу некоторые нюансы:
заменив IP Google и Yandex DNS на IP своих DNS серверов.
2. В переменной MIN_ROUTES задано минимальное количество существующих маршрутов при котором возможно дальнейшее выполнение скрипта. Обычно, до запуска данного скрипта, у меня не больше 15 маршрутов в таблице, если у вас больше маршрутов, следует изменить значение переменной MIN_ROUTES до минимального, но количество должно быть не менее существующих. Проверить это можно выполнив команду route | wc -l.
3. Т.к. роутер у меня очень слабенький, он не может осилить все 30000 с лишним маршрутов, бывает сбрасывает их, а также, чтобы прописать все 30к маршрутов уходило порядка 5 минут, а то и больше. Поэтому мне пришлось придумать как сократить список маршрутов. Решением стало добавление маршрутов подсетями по /24, это позволило сократить список до 8000 с лишним. Если ваш роутер позволяет прописывать большое количество маршрутов, то замените переменную LIST на:
4. Подсеть в которой находился мой VPN сервер была в списке блокировок, из-за этого у меня сбрасывался маршрут на сам VPN сервер, пришлось добавить в скрипт строки:
Если у вас такой проблемы нет, то это можно убрать из скрипта.
Далее включаем планировщик задач cron и активируем автозапуск:
Выполняем команду crontab -e и добавляем в планировщик задание:
Скрипт будет запускаться раз в 5 минут и проверять нужно ли прописывать маршруты. Частоту запуска можете изменить по своему усмотрению.
Возможно многие захотят спросить, зачем использовать cron, если можно просто добавить в конфиг подключения OpenVPN что-то вроде «up unban.sh» и скрипт будет выполняться сразу после подключения. Отвечу: при перезапуске VPN соединения маршруты сбрасываются, а скрипт повторно не выполняется.
P.S. На всякий случай: весь материал в данной статье приведен в ознакомительных целях и не является призывом к действию.
OpenWrt ставится на очень много моделей soho роутеров, конфигурируется и расширяется как душа пожелает. Сейчас многие прошивки роутеров — это надстройки над OpenWrt.
Wireguard используется из-за его быстрой и простой настройки, а так же из-за высокой скорости передачи через туннель.
Автоматически развертываем с помощью Ansible
Playbook и темплейты лежат на github. Используется модуль, в нём не нужен python на роутере и есть поддержка uci. Я постарался сделать так, что бы ваша конфигурация OpenWrt осталась не тронутой, но всё равно будьте бдительны.
Устанавливаем модуль gekmihesg/ansible-openwrt:
Копируем плейбук и темлпейты:
Добавляйте ваш роутер в hosts:
Подставляете свои переменные в hirkn.yml:
Обязательно нужно задать:
wg_server_address — ip/url wireguard сервера
wg_private_key, wg_public_key — приватный ключ клиента и публичный сервера
Остальное можно не менять или менять, в зависимости от того как настроен WireGuard сервер
После выполнения плейбука, роутер сразу начнёт выполнять обход блокировок через ваш wireguard сервер.
Конфигурация firewall
Конфигурация фаервола находится в /etc/config/firewall
Добавляем зону для wireguard. В openwrt зоны — это кастомные цепочки в iptables. Таким образом создаётся зона с одним\несколькими интерфейсами и уже на неё вешаются правила. Зона для wg выглядит например вот так:
Мы разрешаем только выход трафика из интерфейса и включаем маскарадинг.
Теперь нужно разрешить переадресацию с lan зоны на wg зону:
Ну и последнее — это формирование списков в iptables с помощью ipset:
loadfile — файл из которого берем список
name — имя для нашего списка
storage, match — здесь указываем как хранить и какой тип данных. Будем хранить тип "подсеть"
UPD: Если хотите использовать список отдельных IP адресов, то вам необходимо увеличить размер списка ipset. В config ipset добавьте
Иначе вы будете получать ошибку
UPD: Добавим два правила маркировки пакетов
Эти правила подразумевают под собой, что все пакеты идущие в подсети из списков vpn_subnets и vpn_ipsum необходимо помечать маркером 0x1.
После этого рестартуем сеть:
и запускаем скрипт:
После отработки скрипта у вас должно всё заработать. Проверьте маршрут на клиенте роутера:
Почему не BGP?
Под openwrt есть две утилиты реализующих BGP — quagga и bird. Quagg'у мне не удалось заставить забирать данные с antifilter. Bird подружился с сервисом с полпинка, но как заставить добавлять полученным подсетям интерфейс по умолчанию я, к сожалению, не понял. (Буду рад узнать как это можно реализовать).
В комментариях к подобным статьям я видел, что роутеры у людей "призадумывались" на некоторое время, когда те загоняют списки в таблицу маршрутизации. С реализацией через ipset мой Xiaomi mi 3G задумывается на 2 секунды (Asus rt-n16 на 5 секунд), когда скармливаешь ему список из 15ти тысяч подсетей. При дальнейшей работе нагрузки на процессор не замечал.
Все материалы не являются призывом к действию и представлены для ознакомления с функционалом ОС Linux.
Нужно простое и прозрачное для пользователей решение, которое, будучи единожды настроенным, позволит просто пользоваться интернетом, не задумываясь, что же сегодня заблокировали по заявкам очередных копирастов-плагиаторов.
Сама собой напрашивается мысль о том, чтобы обходить блокировку уже на домашнем маршрутизаторе.
Собственно, поднять на маршрутизаторе и гонять весь траффик через VPN несложно, а у некоторых VPN-провайдеров есть даже пошаговые инструкции по настройке OpenWrt на работу с ними.
Но скорости VPN сервисов все же отстают от скоростей доступа в интернет, да и VPN-сервис либо стоит денег, либо имеет массу ограничений, либо необходимость регулярного получения новых логинов. С точки зрения оптимизации затрат, как финансовых, так и временных, предпочтительней выглядит Tor, но его скорость еще хуже, а гонять через Tor торренты и вовсе идея не лучшая.
Выход — перенаправлять в VPN/Tor только траффик блокируемых ресурсов, пропуская остальной обычным путем.
Внимание: данная схема не обеспечивает анонимности просмотра заблокированных сайтов: любая внешняя ссылка раскрывает ваш настоящий IP.
Конкретная реализация на OpenWrt приведена в конце статьи. Если не интересуют подробности и альтернативные варианты решения, то можно листать сразу до нее.
Туннелирование и перенаправление траффика в туннель
Настройка VPN или Tor'а сложностей представлять не должна. Tor должен быть настроен, как прозрачный proxy (либо настроить связку из tor и tun2socks). Т.к. конечной целью явлется обход блокировок ркн, то в конфиге Tor'а целесообразно запретить использование выходных узлов на территории РФ ( ).
В Tor’а траффик перенаправляется правилом с REDIRECT ’ом на порт прозрачного прокси в цепочке PREROUTING таблицы nat netfilter’а.
Для перенаправления в VPN (или Tor + tun2socks) траффик маркируется в таблице mangle , метка затем используется для выбора таблицы маршрутизации, перенаправляющей траффик на соответствующий интерфейс.
В обоих случаях для классификации траффика используется ipset с хостами, подлежащими (раз)блокировке.
Формирование ipset c (раз)блокируемыми хостами
К сожалению, вариант «загнать все IP из реестра» в ipset не работает как хотелось бы: во-первых в списках присутствуют не все IP адреса блокируемых хостов, во-вторых в попытке уйти от блокировки IP адрес у ресурса может измениться (и провайдер об этом уже знает, а мы – еще нет), ну и в третьих – false positives для находящихся на том же shared hosting’е сайтов.
Городить огород с dpi того или иного вида не очень хочется: как-никак работать это должно на довольно слабом железе. Выход достаточно прост и в какой-то степени элегантен: dnsmasq (DNS сервер, который на маршрутизаторе скорее всего уже установлен) умеет при разрешении имен добавлять ip-адреса в соответствующий ipset (одноименная опция в конфиге). Как раз то, что нужно: вносим в конфиг все домены, которые необходимо разблокировать, и дальше по необходимости dnsmasq сам добавляет в ipset именно тот ip адрес, по которому будет идти обращение к заблокированному ресурсу.
У меня были сомнения, что dnsmasq запустится и будет нормально работать с конфигом в полдесятка тысяч строк (примерно столько записей в реестре после усушки и утряски), однако они к счастью оказались безосновательны.
Ложка дегтя в том, что при обновлении списка dnsmasq придется перезапускать, т.к. по SIGHUP он конфиг не перегружает.
Составление списка доменов
Должно происходить автоматически, насколько это возможно.
Теперь еще об одной ложке дегтя: некоторое провайдеры замечены за тем, что помимо включенных в список ркн сайтов самодеятельно блокируют и официально в списках не значащиеся. При этом блокируют тихой сапой и заглушки не выводят. Так что совсем без ручного привода не обойтись.
Дополнительные замечания
Реализация на OpenWrt (15.05)
Сам маршрутизатор должен быть не самый плохой, особенно при использовании Tor’а. MIPS 400MHz@32MB RAM это тот минимум, который стоит рассматривать.
При наличии USB-порта недостаток встроенного флеша можно компенсировать USB-флешкой (вообще мне представляется достаточно здравой идея не использовать встроенный флеш для регулярно перезаписываемых данных).
Штатно в прошивках OpenWrt содержится урезанный dnsmasq, не умеющий ipset. Необходимо заменить его на dnsmasq-full.
Из пакетов, по умолчанию не присутствующих, так же потребуются ipset, tor и tor-geoip.
Так же необходим либо пакет luasocket, либо (в режиме строгой экономии флеша) отдельно ltn12.lua в папке /usr/lib/lua. Для преобразования кириллических доменов из utf8 в punycode нужны idn.lua в /usr/lib/lua и пакет luabitop (либо отключить опции в конфиге скрипта).
На данный момент случайно заблокированных сайтов уже стало сильно меньше, чем пару лет назад, но мне так понравилось не думать об этих блокировках вообще, что я и дальше буду их обходить. Пожалуй, всегда. Не питаю никакого оптимизма по поводу людей, которые управляют этим рубильником, и не хочу зависеть от их спонтанных капризов.
Так как большая часть моего трафика всё-таки ходит к незаблокированной части интернета, то логично пускать через VPN лишь тот трафик, который в этом нуждается. Ну нет ведь смысла гонять через VPN просмотр видео на YouTube или какую-нибудь игру? В итоге получится просто более медленный доступ, а профита никакого.
Стоит отметить, что если вам нужен обход блокировок только на одном устройстве, там вам намного проще будет настроить VPN именно на нём. У многих провайдеров VPN есть программы-клиенты, которые в несколько кликов по красивым кнопкам настроят вам всё, что нужно — просто погуглите, сравните цены и условия. Ещё можете посмотреть в сторону таких бесплатных проектов, как АнтиЗапрет.
Опишу свой процесс настройки роутера на OpenWRT с точечным обходом блокировок. Мне уже приходилось делать это пару раз (то переезд со сменой провайдера, то смена роутера), и вот на третий раз я решил наконец задокументировать этот процесс, чтобы в следующие разы было легче. Может и ещё кому пригодится.
Загрузка списков
Всё, что можно сделать через стандартные возможности OpenWrt, сделано через них. Всё остальное (кроме hotplug) я поместил в небольшой скрипт:
Списки запрещенных подсетей и адресов получаем файлами. Для них создаём директорию в /tmp. В /tmp — потому что это RAM, такая особенность OpenWrt, довольно удобная. На ROM роутера что-то писать лишний раз не стоит.
Выкачиваем списки с antifilter.download curl'ом, флаг z означает, что curl будет скачивать файл, только если удаленный файл отличается от локального или если его нет, как например в случае при загрузке роутера.
subnet.lst — список заблокированных подсетей, изменяется не часто.
ipsum.lst — список заблокированных адресов, который суммаризирован по маске. Вместо 150 тысяч записей получаем 15 тысяч — удобно.
После того как файлы у нас — рестартуем firewall, это нужно для того что бы ipset отработал и добавил списки в iptables, ipset у нас будет сконфигурен в /etc/config/firewall.
Скрипт этот мы добавляем в /etc/init.d/ назовём hirkn. Сделаем его исполняемым
Теперь у нас не просто скрипт, а целая служба. Для того, что бы он запускался при загрузке, делаем симлинк в /etc/rc.d. Нам нужно, что бы он запускался после всех остальных служб, поэтому делаем приставку S99
Списки нужно обновлять время от времени, добавляем запись в cron:
Мне кажется вполне достаточным обновлять их раз в сутки. Имейте в виду, что при добавлении списков в ipset, отваливается сеть, в моём случае это 2 секунды.
UPD: Если не хотите разрывов, то sigo73 и Grayver подсказали в комментариях как это осуществить.
Так же включите крон, по дефолту он отключен:
Шаг 4. Дальнейшая настройка
Теперь осталось настроить роутер так, чтобы он правильно маршрутизировал пакеты через VPN-туннель.
Создадим таблицу маршрутизации для VPN, добавив в файл /etc/iproute2/rt_tables строчку следующего вида:
Добавим дефолтный маршрут для VPN через туннельный интерфейс:
Чтобы сделать это изменение постоянным, чтобы оно переживало перезагрузки роутера, создадим файл /etc/hotplug.d/iface/30-rknroute с вот таким содержимым:
В файл /etc/config/network , который мы уже редактировали в процессе настройки WireGuard, добавим правило, которое будет перенаправлять маркированные пакеты в таблицу маршрутизации VPN:
Теперь приступим к настройке файрволла. Это самая важная часть логики, которая просматривает списки заблокированных адресов, и маркирует пакеты. В файл /etc/config/firewall допишем несколько абзацев:
Первый из них настраивает зону для VPN — из неё разрешён лишь выход пакетов и включён маскарадинг.
Второй абзац разрешает переход из зоны lan , где по умолчанию находятся все устройства, подключенные к роутеру, в зону для VPN.
Третий и четвертый абзацы заставляют файрволл загрузить файлы со списками заблокированных адресов и распихать по хеш-таблицам в памяти. Как известно, поиск по хеш-таблице происходит за константное время, так что роутер сможет эффективно определять направляется ли пакет к заблокированному адресу или к обычному.
Пятый и шестой абзацы отвечают за маркировку пакетов: "если пакет направляется на заблокированный адрес, то добавим ему пометку 0x1 ".
И запустим наш скрипт:
После этого трафик к заблокированным сайтам должен побежать через VPN. Если нет, то попробуйте перезагрузить роутер.
Настройка WireGuard на сервере
Я проделываю всё на Ubuntu 18.04, но в официальной документации есть инструкции по установке для всех известных и не очень ОС.
Бонусом настроим DNSCrypt
Зачем? Ваш провайдер может заботливо подменять ip-адрес заблокированного ресурса, таким образом перенаправляя вас на свой ip с заглушкой, ну и наш обход по ip в данном случае не поможет. Для подмены не всегда даже нужно использовать dns сервер провайдера, ваши запросы могут перехватываться и ответы подменяться. Ну и к слову, это может делать не только провайдер.
Настраиваем конфиг /etc/config/dnscrypt-proxy примерно так:
Таким образом у нас есть сервис dnscrypt на порту 5353 доступный на localhost.
Настраиваем dnsmasq на работу с dnscrypt. В /etc/config/dhcp комментируем строчку:
для того что бы не были задействованы dns серверы провайдера.
Запись list server 'domain/ip_dns' указывает какой dns сервер использовать для резолва указанного домена. Таким образом мы не задействуем dnscrypt для синхронизации ntp — для работы службе dnscrypt важно иметь актуальное время.
При загрузке роутера, скрипт hirkn запускается быстрее чем стартует dnscrypt, таким образом домен antifilter.download не резолвится и списки не скачиваются. Можно сделать задержку или ещё что придумать, но пока что не вижу смысла.
UPD: необходимо добавить строку
В итоге мы получаем такую вставку в конфиг:
Отключаем использование провайдерских DNS для интерфейса wan
В /etc/config/network добавляем строку
к интерфейсу wan.
Получаем такую конфигурацию
Добавляем в автозагрузку и стартуем dnscrypt:
Илюстрация работы без DNSCrypt и c DNSCrypt
Шаг 2. Настройка VPN WireGuard
Для того, чтобы обходить блокировки по IP-адресам, придётся настроить VPN — другого способа нет. VPN "спрячёт" от провайдера ваши IP-пакеты так, что он не будет знать куда именно они направляются и что в себе содержат. В качестве протокола предлагаю использовать WireGuard — легковесный VPN-протокол, который к тому же довольно легко настраивать.
Всё описанное дальше вдохновлено и по сути является пересказом вот этой замечательной статьи на Хабре с некоторыми (минимальными) дополнениями от меня.
VPN — это клиент-серверный протокол. Наш роутер будет клиентом, но также нам обязательно нужен сервер. Можно либо поднять свой VPN-сервер самостоятельно (смотрите инструкцию в статье по ссылке выше, это не сложно), либо оформить подписку на какой-нибудь готовый VPN-сервис. Я пробовал оба варианта, но поддерживать свой VPN-сервер оказалось достаточно трудозатратно, и это тоже, как ни странно, стоит денег. Сложнее всего найти хостинг для своего VPN с незаруиненной репутацией. Проблема, с которой я столкнулся, заключалась в том, что все дешевые хостинги уже имеют плохую репутацию (спасибо вам, господа спамеры), и некоторые ресурсы, типа Пикабу (который тоже, как выяснилось, немножко заблокирован), сразу же заранее отвечают ошибкой 403. Намного проще купить готовый VPN, и пусть лучше кто-то другой за меня беспокоится о том, чтобы мне были доступны все нужные мне сайты.
В последнее время появляется очень много VPN-сервисов, которые работают по протоколу WireGuard — это нынче горячая тема. Недавно поддержка WireGuard была добавлена в основной состав ядра Linux. Погуглите, выбор сервисов действительно есть. Сейчас я пользуюсь RedShieldVPN, и меня пока что всё устраивает.
Бонус для читателей: при регистрации по этой ссылке вам подарят месяц бесплатного VPN.
Дальше буду описывать процесс для RedShieldVPN, но, думаю, для других подобных сервисов процесс должен быть похожим.
Переходим в раздел WireGuard, авторизуемся, выбираем страну и скачиваем конфиг. Я обычно выбираю какую-нибудь европейскую страну, чтобы пинг был приемлемым. В этот раз возьму Финляндию.
Вот примерно такой файл конфигурации скачался (ключи я заменил):
Переключимся на роутер и установим там нужную зависимость:
Дальше нужно настроить сеть. Это происходит в файле /etc/config/network . Открываем его при помощи vi (если не умеете пользоваться этим редактором, то лучше предварительно почитайте что-нибудь для подготовки психики) и дописываем в конец две секции вот такого содержания:
Приватный и публичный ключи замените соответствующими значениями из конфига. Поле list addresses заполняется IPv4-адресом из строчки Address в конфиге, а IPv6 адрес мы просто игнорируем — позже станет понятно почему. Поле Endpoint из конфига WireGuard распадается, соответственно, в поля endpoint_host и endpoint_port в конфиге OpenWRT. Остальные поля статичные.
Перезапустим сеть на роутере:
Если команда wg show выводит что-то подобное, то всё идёт хорошо.
Немного о WireGuard
В нашем случае сервер — это VPS вне РКН, клиент — OpenWrt роутер дома. Когда вы захотите зайти на pornolab telegram, ваш роутер направит трафик через сервер с WireGuard.
WireGuard поднимает site-to-site соединение, т.е. и у сервера и у клиента имеется серверная и клиентская часть конфигурации. Если не понятно — станет понятно когда увидите конфигурацию.
У сервера и у клиента есть свои собственные приватный и публичный ключи.
Конфигурация таблицы маршрутизации
Создаем таблицу маршрутизации для трафика через туннель, просто добавив строку:
в файл /etc/iproute2/rt_tables.
Создать дефолтный маршрут для таблицы "vpn" через wg интерфейс можно командой:
Но при рестарте сети маршрут пропадёт, поэтому создаём файл 30-rknroute в директории /etc/hotplug.d/iface/ с простым содержимым:
Это означает, что при включении\выключении интерфейсов будет добавляться наш маршрут. И соответственно, этот маршрут будет всегда прописан.
Роутер и прошивка
OpenWRT — это опенсорсный проект, который разрабатывает прошивки для роутеров на основе Linux. В той или иной мере, пожалуй, поддерживаются все существующие девайсы. Внутри есть даже свой собственный пакетный менеджер. Так как роутер с OpenWRT — это почти настоящая линукс-машина, то открывается огромное поле для различных извращений — файловые шары, торрент-клиенты, блокировка рекламы на уровне роутера, VPN — да что угодно.
Мой нынешний роутер — это Xiaomi Mi WiFi Router 3G. Выбрал его, потому что в нём достаточно мощи, чтобы на нём хорошо работала OpenWRT. Да и вообще, Mir3G — это, похоже, один из самых популярных девайсов в тусовке людей, которые занимаются дрессировкой роутеров, так что в сети по нему уже есть много мануалов и обсуждений на форумах. Если захотите купить такой же, то будьте аккуратны с конкретной моделью — их две под одним названием, а хорошая только та, у которой есть порт USB3. Такой роутер должно быть несложно купить на Авито или других досках объявлений.
У меня на данный момент установлена почти последняя версия прошивки:
Прошивка OpenWRT и базовая настройка роутера выходит за рамки этой статьи. Поищите мануалы для вашего роутера. Далее предполагается, что у вас уже есть роутер с OpenWRT, подключенный к интернету, и к нему настроен доступ по SSH.
Установка
Установите software-properties-common — пакет предоставляет возможность добавления и удаления PPA
Генерируем ключи для сервера. Ключи сохраним в директории WireGuard для удобства
Соответственно в файле privatekey-server будет приватный ключ, а в publickey-server — публичный.
Так же сгенерируем сразу ключ для клиента:
Блокировки
Грубо говоря, существует два типа блокировок:
Нам нужно победить оба. Разберёмся с каждым из них по порядку.
Логика работы роутера
Загружаем списки, помещаем их в iptables, все адреса из этих списков iptables помечает маркером 0x1. Далее все пакеты помеченные 0x1 идут в отдельную таблицу маршрутизации, все пакеты попавшие в эту таблицу маршрутизации идут через wg интерфейс.
Шаг 1. Шифрованный DNS
DNS (Domain Name System) — это распределенная система (нет, это не сеть магазинов), состоящая из множества серверов по всему миру, которая позволяет вашему компьютеру преобразовать человекочитаемое имя сайта в машиночитаемый IP-адрес, например, из github.com получить 140.82.121.3 . Этот процесс называется "разрешением" или "резолвингом" доменного имени.
Блокировка по доменным именам зачастую реализуется провайдером следующим образом: ваш роутер по умолчанию использует DNS-сервер, который контролируется провайдером и для заблокированных доменных имён возвращает специальный адрес сайта-заглушки. Именно это происходит, когда вы видите в браузере "доступ к ресурсу ограничен в соответствии со 149-ФЗ".
Кажется, что решение очевидно — просто не пользоваться DNS-сервером провайдера, а использовать, например, Google DNS, IP-адреса которого уже стоит знать наизусть как считалку — 8.8.8.8, 8.8.4.4 . Раньше это действительно работало, но сегодня провайдеры уже не дадут вам так просто себя обмануть.
Поскольку DNS — это очень старый протокол, в котором никак не было предусмотрено шифрование от слова "вообще", у провайдеров есть возможность перехватывать ваши запросы и подменять ответы, вставляя свой сайт-заглушку, даже если запрос шёл, например, к Google DNS. Именно этим они и занимаются. По сути, провайдер проводит против вас атаку DNS hijacking.
Вот как это работает, если всё хорошо. В таком сценарии можно даже не заметить этого "человека посередине" в лице вашего провайдера:
А вот так это работает, когда всё плохо. Провайдер наверняка даже не отправляет запрос к DNS-серверу, которому он предназначался, а просто сразу же возвращает ответ, подставляя адрес своей заглушки:
Но по-настоящему эффективное решение есть. Если провайдер не сможет увидеть, к какому домену происходит обращение, то не сможет и подменить ответ. А ещё лучше, если он вообще не будет знать, что происходит резолвинг имени. Этого можно достичь шифрованием.
Обновим список пакетов. Эту команду нужно выполнять после каждой перезагрузки роутера перед установкой пакетов:
Чтобы плагин для LuCI заработал, нужно сделать выполнить вот такую команду:
Готово! Теперь на компьютере, подключенном к роутеру, можно проверить как это работает:
Обратите внимание, что адреса возвращаются разные: до настройки DoH — неправильный, это результат подмены адресов провайдером, а после — правильный. Можно считать это маленькой победой!
Сам по себе обход блокировок по DNS вряд ли даст ожидаемый эффект, потому что, как правило, в довесок к доменному имени, ресурс блокируется еще и по IP-адресам — видимо, для надежности. Это следующий тип блокировок, которые нужно победить.
Стоит упомянуть про побочные эффекты от такой настройки — могут стать недоступными различные внутренние ресурсы провайдера. Например, когда у меня кончается интернет и я забываю его оплатить, провайдер просто не может меня переадресовать на страницу, куда он обычно направляет своих забывчивых абонентов. Для меня выглядит это всё так, будто интернет просто пропал, без каких-либо объяснений. Я даже первый раз из-за этого чуть не поругался с поддержкой, а оказалось, что это я сам дурак. Что ж, просто приходится платить заранее.
Если нравится статья, то подпишитесь на уведомления о новых постах в блоге, чтобы ничего не пропустить! А ещё читайте другие мои посты!
Установка пакетов
Насчет занимаемого места на флеше, на всё понадобится примерно 0.9МБ. Если у вас совсем плохо с местом, замените curl wget'ом и можете не ставить dnscrypt-proxy.
Ставим пакеты. В OpenWrt это просто сделать через менеджер пакетов opkg:
Конфигурация сети
Нам необходимо сконфигурировать WireGuard и правило для пакетов с меткой 0x1.
Конфигурация WireGuard располагается в /etc/config/network
private_key — это privatekey-client, который мы генерировали при настройке сервера
list addresses — адрес wg интерфейса
listen_port — порт на котором WireGuard принимает соединения. Но соединение будет происходить через порт на сервере, поэтому здесь мы не будем открывать для него порт на firewall
proto — указываем протокол, что бы openwrt понимало что это конфигурация WireGuard
public_key — ключ publickey-server
allowed_ips — подсети, в которые может ходить трафик через тунель, в нашем случае никаких ограничей не требуется, поэтому 0.0.0.0/0
route_allowed_ips — флаг, который делает роут через wg интерфейс для перечисленных сетей из параметра allowed_ips. В нашем случае это не нужно, эту работу выполняет iptables
endpoint_host — ip/url нашего wg сервера
persistent_keepalive — интервал времени, через который отправляются пакеты для поддержки соединения
endpoint_port — порт wireguard на сервере
Ещё в конфигурацию network добавим правило, которое будет отправлять весь трафик, помеченный 0x1, в таблицу маршрутизации "vpn":
Настройка роутера
Я использую OpenWrt версии 18.06.1 на Xiaomi mi 3G и Asus RT-N16.
Шаг 3. Скрипт для сбора списков заблокированных адресов
Это возможно благодаря крутейшему сервису antifilter.download, который обрабатывает выгрузки Роскомнадзора и отдает их в виде списков IP-адресов в машиночитаемых форматах. Мы настроим периодическую выгрузку списков заблокированных адресов с antifilter.download, чтобы всегда иметь актуальную информацию о блокировках. По моему опыту обновлять этот список раз в сутки (например, ночью) вполне достаточно.
Кроме того, нам нужно настроить файрволл роутера, чтобы он помечал пакеты, которые направляются к заблокированным адресам, специальным маркером. Такие маркированные пакеты должны маршрутизироваться роутером через VPN.
Начнём со скрипта, который реализует эту логику по обновлению списков заблокированных адресов.
Создадим файл /etc/init.d/hirkn со скриптом следующего содержания:
Этот скрипт скачивает два списка заблокированных адресов — один в виде сетей (иногда РКН блокирует адреса целыми подсетями), другой — обобщенный список отдельных заблокированных адресов. За счёт обобщения в небольшие подсети он содержит не миллионы строк, а всего лишь что-то около 15 тысяч. Нам нужны оба списка, они не пересекаются между собой. Файлы сохраняются в каталог /tmp , который в OpenWRT хранится в оперативной памяти — это должно работать быстро. В конце скрипт перезапускает файлволл. Настройка файлволла будет происходит позже.
Добавим этому скрипту права на выполнение:
Добавим скрипт в "автозапуск", чтобы он выполнялся при включении роутера после всех остальных скриптов:
Через cron запланируем выполнение этого скрипта раз в сутки:
В открывшемся редакторе нужно добавить на новой строке:
На crontab.guru можно посмотреть объяснение этой строчки.
Включим cron , потому что по умолчанию в OpenWRT он выключен:
Убедимся, что скрипт работает.
Если файлы со списками заблокированных адресов появились, то всё ок:
Шаг 5. Отключаем IPv6
Этот шаг мой самый нелюбимый, потому что я за всё новое и против всего старого. По моему глубокому убеждению IPv4 уже давно должен умереть и быть вытеснен шестой версией протокола. К сожалению, дела у IPv6 пока идут не так гладко, как хотелось бы (сейчас он занимает всего около 30% процентов трафика).
Проблема в том, что antifilter.download выдаёт только заблокированные IPv4 адреса. Это значит, что наш обход блокировок не будет работать по IPv6. Если разрешить вашему роутеру работать по IPv6, то многие ваши устройства предпочтут открывать сайты по IPv6 либо напарываясь на страницы с блокировками от провайдеров, либо просто получая ошибки подключения по таймауту.
Отключаем IPv6 (команды взяты отсюда):
После этого может потребоваться ещё одна перезагрузка роутера, чтобы он перестал раздавать вновь подключенным устройствам IPv6-адреса.
Вот как-то так можно при помощи несложных (ладно, сложных) манипуляций настроить свой роутер на точечный обход блокировок. Все незаблокированные сайты работают как обычно, а заблокированные — через VPN. С такой конфигурацией можно полностью забыть про мелкие пакости от Роскомнадзора и начать, наконец, жить :)
Конфигурация
Конфиг хранится в /etc/wireguard/wg0.conf. Серверная часть выглядит так:
Address — адрес для интерфейса wg (адрес внутри туннеля)
PrivateKey — Приватный ключ (privatekey-server)
ListenPort — Порт на котором служба ожидает подключения
Ну и делаем маскарадинг, потому что мы будем использовать этот сервер для выхода в интернет
Обратите внимание, что имя интерфейса в вашем случае может отличаться:
PublicKey — публичный ключ нашего роутера (publickey-client)
AllowedIPs — подсети, которые будут доступны через этот туннель. Серверу требуется доступ только до адреса клиента.
Обе части хранятся в одном конфиге.
Включаем автозапуск при перезагрузке:
Делаем сервер маршрутизатором:
Настроим фаервол. Предположим, что у нас на сервере только WireGuard и ssh:
Сохраним конфигурацию iptables:
Поднимаем wg интерфейс первый раз вручную:
WireGuard сервер готов.
UPD 27.06.19 Если ваш провайдер до сих пор использует PPoE, то нужно добавить правило. Спасибо denix123
Читайте также: