Sunday, December 11, 2016

OpenWRT + OpenVPN: точечный обход блокировок / Хабрахабр

Линуксоид
9,6
рейтинг
вчера в 22:02

Администрирование → OpenWRT + OpenVPN: точечный обход блокировок из песочницы

Как человек постоянно работающий в интернете, я привык к полному и беспрепятственному доступу ко всем его ресурсам независимо от содержания данных ресурсов, а в силу того, что обеспечиваю работу части ресурсов (работаю в хостинг-провайдере), мне просто необходим такой доступ.

Обойти блокировки не так сложно, есть множество способов. Наиболее распространенный и стабильный из них — 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 и прописывать маршруты:

unban.sh
#!/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. На всякий случай: весь материал в данной статье приведен в ознакомительных целях и не является призывом к действию.
Vitaliy @vitalegkhua
карма
1,0
рейтинг 9,6
Линуксоид
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Администрирование

Комментарии (15)

  • 0
    • 0
      Можно и так, но я все же предпочел использовать собственный VPN сервер.
  • 0
    Ох… От такого мучения таблице маршрутизации не поплохело?

    Опишу свой способ
    Выгрузка 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  

    • 0
      На 30к поплохело. 8к по подсетям /24 нормально держит и прописывает достаточно быстро, около минуты.
      Обход с помощью ipset/iptables конечно получше, но у моего роутера очень мало памяти и установить их нет возможности, к сожалению.
      • 0
        Странно, мой предыдущий достаточно дохлый tp-link нормально держал эти 30к без извратов с /24.

        Ну и да, такой обход получается не совсем уж и точечным :)
        • 0
          Бывает держит, но при малейшем чихе все сбрасывает. На самом деле, /24 это мизер в масштабах интернета, поэтому я не постеснялся применить такой способ.
          • 0
            Ну в том-то и дело, что 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к записей в таблице маршрутизации действительно могут выжрать всю доступную память, ведь там у каждой записи как минимум хранится интерфейс.
            • 0
              Я ж не спорю, но:

              Filesystem Size Used Available Use% Mounted on
              rootfs 640.0K 560.0K 80.0K 88% /

              Как-то так.
              • 0
                А причём тут флеш? Таблица хранится в оперативной памяти, а не в постоянной же.
                • 0
                  Это о невозможности установить ipset.
                  • 0
                    Да ладно, выкинуть opkg (ну и ещё что-нибудь ненужное) и поставить ipset, оный 120 килобайт занимает.
                    • 0
                      opkg выполняет установку openvpn в tmpfs при каждом запуске. Все не нужное уже удалил.
                      • 0
                        Тогда почему нельзя установить ipset в tmpfs?
  • 0
    OpenVPN@MIPS? Pervert!
  • 0
    Если роутер способен потянуть Tor, то вот мой вариант.

    Плюсы:
    • нет нужды поднимать свой сервер

    Минусы:
    • на некоторых рерсурсах могут возникнуть проблемы, IP-адреса Tor кое-где не любят
    • выходные ноды не всегда белые и пушистые, поэтому на ресурсы, не поддерживающие https, через Tor ходить не рекомендуется

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.



Original Page: https://habrahabr.ru/post/317354/



Sent from my iPad

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.