Обойти блокировки не так сложно, есть множество способов. Наиболее распространенный и стабильный из них — VPN. Но у VPN большой недостаток — это потеря скорости, завышается пинг и т.д. Исходя из этого, у меня возникла идея, использовать VPN только для обхода блокировок, а на остальные ресурсы ходить через провайдера.
Делать я это все буду на роутере TP-Link WR841N, чтобы обеспечить беспрепятственный доступ в интернет для всех сетевых устройств, а не только для рабочего компьютера.
Для начала нам потребуется поднять OpenVPN сервер или воспользоваться услугами VPN провайдера. Если же вы решите поднять собственный сервер, я бы рекомендовал использовать OpenVPN Access Server, т.к. с помощью него можно просто и быстро его развернуть, а также имеет веб-интерфейс. Достаточно просто установить пакет и задать пароль на учетную запись openvpn.
Я не буду описывать как прошить роутер под OpenWRT, уже есть такая статья. Я скажу даже больше, есть даже решение проблемы с отсутствием OpenVPN в прошивке OpenWRT под TP-Link WR841N — вот эта статья. Единственное, из этой статьи мне пришлось немного подправить init-скрипт, т.к. возникла проблема с автозапуском, а также я добавил условие при котором скрипт не будет скачивать дистрибутив OpenVPN при каждом запуске, а только при первом.
#!/bin/sh /etc/rc.common
START=99
start() {
local TMPPATH=/tmp/openvpn
if [ ! -f "${TMPPATH}/usr/sbin/openvpn" ]; then
sleep 60;
[ ! -d ${TMPPATH} ] && mkdir ${TMPPATH}
cd ${TMPPATH}
opkg update || exit 1
tar xzf $(opkg download libopenssl | grep Downloaded | cut -d\ -f4 | sed '$s/.$//')
tar xzf data.tar.gz
tar xzf $(opkg download openvpn-openssl | grep Downloaded | cut -d\ -f4 | sed '$s/.$//')
tar xzf data.tar.gz
rm -f pkg.tar.gz data.tar.gz control.tar.gz debian-binary getopenvpn.sh
for i in $(ls ${TMPPATH}/usr/lib)
do
[ ! -f /usr/lib/$i ] && ln -s /tmp/openvpn/usr/lib/$i /usr/lib/$i
done
fi
${TMPPATH}/usr/sbin/openvpn --writepid /tmp/ovpn_ciberterminal.pid --daemon --cd /etc/openvpn --config my.conf
}
stop() {
PIDOF=$(ps | egrep openvpn | egrep -v grep | awk '{print $1}')
kill ${PIDOF}
}
Итак, допустим у нас есть роутер с установленной прошивкой OpenWRT и OpenVPN. Правим файл-конфигурации подключения OpenVPN, у меня он находится в /etc/openvpn/my.cnf. Добавляем в него следующие параметры:
route-noexec #Этот параметр не дает перезаписать default route.
auth-user-pass login.conf #Для автоматической авторизации
keepalive 3 10 #Перезапуск соединения при разрыве
persist-tun #Не ложить tun/tap интерфейс про разрыве
persist-key #Не считывать ключи при разрыве
Создаем файл /etc/openvpn/login.conf в следующем формате:
yourlogin
yourpassword
Соответственно yourlogin и yourpassword нужно заменить на ваши авторизационные данные, если кто не понял.
Создаем скрипт /etc/openvpn/unban.sh, который будет выгружать список заблокированных IP и прописывать маршруты:
#!/bin/sh
TUN=`ifconfig | grep tun | awk '{print $1}'`
MIN_ROUTES="15"
if [ "$TUN" == "" ]; then
exit;
fi
CHECK_ROUTES=`route | wc -l`
if [ "$CHECK_ROUTES" -gt "$MIN_ROUTES" ]; then
exit;
fi
route add 8.8.8.8/32 dev $TUN;
route add 8.8.4.4/32 dev $TUN;
route add 77.88.8.8/32 dev $TUN;
wget "http://reestr.rublacklist.net/api/ips" -O /tmp/ip_list;
LIST=`cat /tmp/ip_list | sed 's/;/\n/g' | grep -v '"' | awk -F. '{print $1"."$2"."$3".0/24"}' | sort | uniq`
for IP in $LIST
do
echo "Adding $IP..."
route add -net $IP dev $TUN;
done
REMOTE_IP=`cat /etc/openvpn/my.conf | grep remote | tail -n1 | awk '{print $2}'`;
DEFAULT_GW=`route | grep default | awk '{print $2}'`
route add ${REMOTE_IP}/32 gw $DEFAULT_GW;
rm -rf /tmp/ip_list;
Опишу некоторые нюансы:
1. Мой провайдер, как оказалось, перехватывает DNS запросы и выдает мне ложный IP заблокированных сайтов, соответственно, чтобы этого избежать необходимо направить DNS запросы через VPN. Если Вы используете другие DNS серверы, стоит поправить строки:
route add 8.8.8.8/32 dev $TUN;
route add 8.8.4.4/32 dev $TUN;
route add 77.88.8.8/32 dev $TUN;
заменив IP Google и Yandex DNS на IP своих DNS серверов.
2. В переменной MIN_ROUTES задано минимальное количество существующих маршрутов при котором возможно дальнейшее выполнение скрипта. Обычно, до запуска данного скрипта, у меня не больше 15 маршрутов в таблице, если у вас больше маршрутов, следует изменить значение переменной MIN_ROUTES до минимального, но количество должно быть не менее существующих. Проверить это можно выполнив команду route | wc -l.
3. Т.к. роутер у меня очень слабенький, он не может осилить все 30000 с лишним маршрутов, бывает сбрасывает их, а также, чтобы прописать все 30к маршрутов уходило порядка 5 минут, а то и больше. Поэтому мне пришлось придумать как сократить список маршрутов. Решением стало добавление маршрутов подсетями по /24, это позволило сократить список до 8000 с лишним. Если ваш роутер позволяет прописывать большое количество маршрутов, то замените переменную LIST на:
LIST=`cat /tmp/ip_list | sed 's/;/\n/g' | grep -v '"' | sort | uniq`
4. Подсеть в которой находился мой VPN сервер была в списке блокировок, из-за этого у меня сбрасывался маршрут на сам VPN сервер, пришлось добавить в скрипт строки:
REMOTE_IP=`cat /etc/openvpn/my.conf | grep remote | tail -n1 | awk '{print $2}'`;
DEFAULT_GW=`route | grep default | awk '{print $2}'`
route add ${REMOTE_IP}/32 gw $DEFAULT_GW;
Если у вас такой проблемы нет, то это можно убрать из скрипта.
Далее включаем планировщик задач cron и активируем автозапуск:
/etc/init.d/cron start
/etc/init.d/cron enable
Выполняем команду crontab -e и добавляем в планировщик задание:
*/5 * * * * /bin/sh /etc/openvpn/unban.sh
Скрипт будет запускаться раз в 5 минут и проверять нужно ли прописывать маршруты. Частоту запуска можете изменить по своему усмотрению.
Возможно многие захотят спросить, зачем использовать cron, если можно просто добавить в конфиг подключения OpenVPN что-то вроде «up unban.sh» и скрипт будет выполняться сразу после подключения. Отвечу: при перезапуске VPN соединения маршруты сбрасываются, а скрипт повторно не выполняется.
P.S. На всякий случай: весь материал в данной статье приведен в ознакомительных целях и не является призывом к действию.
Комментарии (25)
Prototik
11.12.2016 23:33+2Ох… От такого мучения таблице маршрутизации не поплохело?
Опишу свой способВыгрузка ip адресов с rublacklist, должен выполняться по крону каждые n-минут/часов/дней:
#!/bin/sh TARGET_SET=vpn-whitelist TARGET_TMP=vpn-whitelist-tmp ipset destroy -q ${TARGET_TMP} || true ipset create -q ${TARGET_SET} hash:ip || true ipset create ${TARGET_TMP} hash:ip wget -O - https://reestr.rublacklist.net/api/ips | awk '{gsub(/"/,"",$1); gsub(";"," ",$1); print $1}' | xargs -n1 ipset add ${TARGET_TMP} ipset swap ${TARGET_TMP} ${TARGET_SET} ipset destroy ${TARGET_TMP}
Добавляем алиас для таблицы маршрутизации:
echo 99 vpn >> /etc/iproute2/rt_tables
Говорим, что все пакеты с меткой 0x99 должны идти через эту таблицу:
ip rule add fwmark 0x99/0x99 lookup vpn
Помечаем адреса из ipset vpn-whitelist меткой 0x99:
iptables -t mangle -A PREROUTING -i br-lan -m set --match-set vpn-whitelist dst -j MARK --set-xmark 0x99/0x99
Превентивно помечаем чистый http (не https) как подлежащий маршрутизации через vpn (опциональный шаг):
iptables -t mangle -A PREROUTING -i br-lan -m tcp -p tcp --dport 80 -j MARK --set-xmark 0x99/0x99
vitalegkhua
11.12.2016 23:39На 30к поплохело. 8к по подсетям /24 нормально держит и прописывает достаточно быстро, около минуты.
Обход с помощью ipset/iptables конечно получше, но у моего роутера очень мало памяти и установить их нет возможности, к сожалению.Prototik
11.12.2016 23:40Странно, мой предыдущий достаточно дохлый tp-link нормально держал эти 30к без извратов с /24.
Ну и да, такой обход получается не совсем уж и точечным :)vitalegkhua
11.12.2016 23:44Бывает держит, но при малейшем чихе все сбрасывает. На самом деле, /24 это мизер в масштабах интернета, поэтому я не постеснялся применить такой способ.
Prototik
11.12.2016 23:52Ну в том-то и дело, что ipset хранит всё это дело гораздо оптимальнее:
Name: vpn-whitelist Type: hash:ip Revision: 4 Header: family inet hashsize 8192 maxelem 65536 Size in memory: 364368
Т.е. 364368/1024 = 355 килобайт памяти на хранение всего списка. Даже самые дохлые роутеры сейчас снабжаются 4 метрами оперативы, а чаще 16. А вот 30к записей в таблице маршрутизации действительно могут выжрать всю доступную память, ведь там у каждой записи как минимум хранится интерфейс.vitalegkhua
12.12.2016 00:00Я ж не спорю, но:
Filesystem Size Used Available Use% Mounted on
rootfs 640.0K 560.0K 80.0K 88% /
Как-то так.Prototik
12.12.2016 00:02А причём тут флеш? Таблица хранится в оперативной памяти, а не в постоянной же.
vitalegkhua
12.12.2016 00:04Это о невозможности установить ipset.
Prototik
12.12.2016 00:08Да ладно, выкинуть opkg (ну и ещё что-нибудь ненужное) и поставить ipset, оный 120 килобайт занимает.
vitalegkhua
12.12.2016 00:13opkg выполняет установку openvpn в tmpfs при каждом запуске. Все не нужное уже удалил.
Prototik
12.12.2016 00:22Тогда почему нельзя установить ipset в tmpfs?
vitalegkhua
12.12.2016 22:52Будет время, поэкспериментирую. Предварительно посмотрел, как-то громоздко и сложновато все выходит, т.к. нужно устанавливать дополнительные модули ядра и библиотеки.
Crandel
12.12.2016 11:36Советую собрать свою openwrt, собирается гдето часа 3, но с теми пакетами, которые нужны, я впихнул и opkg и openvpn и еще место осталось, а выкинул немного лишнего, ip6 и еще какие-то пакеты, даже веб интерфейс оставил
https://habrahabr.ru/post/264299/apatrushev
13.12.2016 14:483 часа? С помощью ImageBuilder собирается за минуты.
Инструкция на офсайте.
dartraiden
12.12.2016 02:06+3Если роутер способен потянуть Tor, то вот мой вариант.
Плюсы:
- нет нужды поднимать свой сервер
Минусы:
- на некоторых рерсурсах могут возникнуть проблемы, IP-адреса Tor кое-где не любят
- выходные ноды не всегда белые и пушистые, поэтому на ресурсы, не поддерживающие https, через Tor ходить не рекомендуется
Vindicar
12.12.2016 09:03+2Я использую способ попроще — Proxy Auto Config.
На OpenVPN сервере подняты bind, privoxy и lighttpd, смотрящие внутрь VPN.
Роутер на базе прошивки Vampik'а (OpenWRT не может толком работать с моим ISP, увы) настроен так, чтобы при установке VPN соединения переключаться на использование bind на сервере (и обратно на провайдерский если соединение падает). Также он роутит пакеты между VPN и внутренней сетью, с маскарадом. (Эту часть я настраивал по гуглу, так как в сетях разбираюсь слабо.)
Ежедневно по крону выкачивается список адресов с antizapret, формируется PAC-файл, и отдаётся клиентам через lighttpd.
К слову, в списке с antizapret сейчас очень мало IP-адресов — по большей части домены. Поэтому они сразу проверяются в PAC-скрипте.
Примерно так:function FindProxyForURL(url, host) { var domainblacklist = [ 'config.privoxy.org', 'тут те сайты, которые всегда должны проксироваться', $DOMAINLIST ]; var ipblacklist = [ $IPLIST ]; function endsWith(str, suffix) { return str.indexOf(suffix, str.length - suffix.length) !== -1; } var blocked = false; for (var i=0; !blocked && (i<domainblacklist.length); i++) blocked = blocked || ((host == domainblacklist[i]) || endsWith(host, '.'+domainblacklist[i])); if (blocked || (ipblacklist.indexOf(dnsResolve(host)) != -1)) return "PROXY privoxy.addr:port"; else return "DIRECT"; }
ValdikSS
12.12.2016 17:16+1К слову, в списке с antizapret сейчас очень мало IP-адресов — по большей части домены. Поэтому они сразу проверяются в PAC-скрипте.
Может, вам удобней будет http://antizapret.prostovpn.org/iplist.txt или http://antizapret.prostovpn.org/proxy-ip.pac?Prototik
13.12.2016 07:46А почему в iplist.txt есть 0.0.0.1 и 127.0.0.2, парочка 192.168.x.x? :D
ValdikSS
13.12.2016 11:510.0.0.1 и 127.0.0.2
Какой-то домен резолвится в такие адреса.
парочка 192.168.x.x
Чтобы эффективно обходить блокировки у провайдеров, которые подменяют записи DNS, а заглушка у них расположена на 192.168.x.x.
Vindicar
13.12.2016 11:38Да по мне так с доменами даже удобнее. Коллизий (ситуаций, когда сайт сидит на одном IP с блокированным) пока не наблюдал.
Просто когда писал крон-скрипт, выдергивал только IPшники — ничего другого не было. А потом большая часть IP была заменена на домены, как следствие список резко сократился и прокси перестал использоваться. Здорово я удивился тогда. =)
Но за ссылки спасибо!
ValdikSS
https://antizapret.prostovpn.org/antizapret.ovpn
vitalegkhua
Можно и так, но я все же предпочел использовать собственный VPN сервер.