Май 262020
 

Введение

Для успешного решения проблемы необходимо сделать два шага:

  • решить проблему подмены DNS ответов,
  • туннелировать трафик блокируемых IP адресов за пределы зоны блокировок, желательно с использованием шифрования, чтобы исключить возможность фильтрации не только по IP заголовкам, но и области данных.

В свежей версии OpenWRT 19.07 есть несколько «штатных» инструментов для настройки этих возможностей через web интерфейс LuCI.

Проблема первая. Подмена DNS ответов.

Есть множество инструментов для решения этой проблемы:

  • туннелирование DNS запросов,
  • использование DNS-over-TLS или DNS-over-HTTPS.

Второй способ для роутера представляется более предпочтительным т.к. позволит не только обходить блокировки, но и настроить локальный DNS сервер. Этот способ потребует установки оснастки luci-app-unbound и ее зависимостей, собственно пакета unbound-daemon и unbound-control для сопряжения с локальным DHCP сервером odhcpd.

Большая часть настроек оставлена по умолчанию.

Собственно, настройка шифрования DNS запросов.

Используем DNS сервисы cloudflare-dns.com

Под капотом.

Процесс /usr/sbin/unbound -d запускается с конфигурацией -c /var/lib/unbound/unbound.conf. Файл конфигурации формируется динамически при запуске unbound. В нем есть параметр, который влияет на производительность: num-threads: 1. В конфигураторе web интерфейса этот параметр отсутствует, но он доступен через прямое редактирование файла конфигурации /etc/config/unbound - option num_threads '2'. Однако, его изменение не влияет на результирующий файл /var/lib/unbound/unbound.conf.
Как выяснилось проблема заключается в сборке самого unbound. Файл конфигурации создается из исходного запуском скрипта /usr/lib/unbound/unbound.sh в котором присутствуют строки, которые это проясняют:

if [ "$UB_N_THREADS" -gt 1 ] \
  && $PROG -V | grep -q "Linked libs:.*libevent" ; then
    # heavy variant using "threads" may need substantial resources
    echo "  num-threads: 2" >> $UB_CORE_CONF
else
    # light variant with one "process" is much more efficient with light traffic
    echo "  num-threads: 1" >> $UB_CORE_CONF
fi

Проблема вторая. Туннель с шифрованием.

Опять же существует множество решений этой проблемы, но у меня уже есть решение большей ее половины — собственный shadowsocks сервер вне зоны блокировок. Для его использования нужно установить пакеты luci-app-shadowsocks-libev и его зависимости: shadowsocks-libev-config, shadowsocks-libev-ss-local, shadowsocks-libev-ss-redir, shadowsocks-libev-ss-rules, shadowsocks-libev-ss-tunnel, ipset. Возможно что-то упущено или лишнее для решения этой проблемы, но в любом случае менеджер пакетов подскажет, что точно необходимо.

Для начала настраиваем доступ к удаленному серверу, в поле Server указываем IP адрес и параметры сервера:

Следующая вкладка.

Здесь нужно обратить внимание на поле Dst ip/net forward file, ниже будет объяснено более подробно, что с этим полем нужно сделать, а пока что нужно оставить его пустым и заполнить поле чуть выше Dst ip/net forward каким-нибудь IP адресом. Например, 195.201.201.32 — IP адрес известного ресурса 2ip.ru.

Надеюсь у читателя есть под рукой Linux консоль, которая может или точно понадобится для дпльнейшей настройки. В принципе это можно делать прямо на роутере, если установить нужные пакеты: bind-dig, bind-host, bind-libs, dropbear. Затем подключиться к консоли роутера по ssh и ввести команду:

root@router:/# dig +short 2ip.ru
195.201.201.32

или

root@router:/# host 2ip.ru
2ip.ru has address 195.201.201.32

Нажимая каждый раз значок + справа поля Dst ip/net forward можно ввести несколько адресов. Занятие это достаточно утомительное — нужно постоянно переключаться с консоли в окно ввода и обратно, и не всегда может оказаться успешным, т.к. нужный сайт может располагаются на нескольких IP адресах.

Переходим на первую вкладку.

И включаем редирект.

На вкладке Advanced Settings по умолчанию включен Verbose — логирование перенаправления. Это может оказаться полезным при отладке, но после его лучше отключить.

На данном этапе настройку можно закончить. Перенаправление в тоннель будет работать при заходе на введенные вручную IP адреса.

Расширенная настройка с использованием файла /etc/net_block

После успешной настройки тоннеля и редиректа можно посмотреть содержимое списков туннелируемых IP адресов командой:

root@router:/# ipset list |less
Name: ss_rules_src_bypass
Type: hash:net
Revision: 6
Header: family inet hashsize 64 maxelem 65536
Size in memory: 312
References: 2
Number of entries: 0
Members:

Name: ss_rules_src_forward
Type: hash:net
Revision: 6
Header: family inet hashsize 64 maxelem 65536
Size in memory: 312
References: 2
Number of entries: 0
Members:

Name: ss_rules_src_checkdst
Type: hash:net
Revision: 6
Header: family inet hashsize 64 maxelem 65536
Size in memory: 312
References: 2
Number of entries: 0
Members:

Name: ss_rules_dst_bypass
Type: hash:net
Revision: 6
Header: family inet hashsize 64 maxelem 65536
Size in memory: 312
References: 2
Number of entries: 0
Members:

Name: ss_rules_dst_bypass_
Type: hash:net
Revision: 6
Header: family inet hashsize 64 maxelem 65536
Size in memory: 1152
References: 3
Number of entries: 20
Members:
192.175.48.0/24
192.52.193.0/24
224.0.0.0/4
172.16.0.0/12
192.88.99.0/24
198.18.0.0/15
...

Name: ss_rules_dst_forward
Type: hash:net
Revision: 6
Header: family inet hashsize 8192 maxelem 65536
Size in memory: 535056
References: 2
Number of entries: 25542
Members:
149.202.195.0/24
45.79.98.0/24
185.117.74.0/24
34.195.168.0/24
52.205.80.0/24
173.208.141.0/24
34.253.159.0/24
138.197.60.0/24
185.127.24.0/24
208.100.28.0/24
91.211.99.0/24

Перенаправляемые в тоннель IP адреса будут находиться в списке ss_rules_dst_forward. Списки создаются при запуске процесса /etc/init.d/shadowsocks-libev скриптом /usr/bin/ss-rules:

create ss_rules${o_af}_dst_forward hash:net family inet$o_af hashsize 64

Как видно, список может состоять из отдельных адресов и подсетей hash:net. По умолчанию список может содержать 65536 элементов.
Посмотрим список заблокированных IP адресов. Например, его можно получить следующей командой в Linux консоли:

curl https://reestr.rublacklist.net/api/v2/ips/csv |grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' > ip_block

После выполнения команды файл ip_block будет содержать заблокированные IPv4 адреса. Увы, напрямую этот файл использовать не получится, т.к. он содержит очень большое количество адресов, намного превосходящее заданное по умолчанию 65536 строк и еще потому, что исходный список будет очень долго загружаться конфигуратором, даже если изменить заданные по умолчанию ipset параметры.

Идея состоит в том, чтобы преобразовать исходный файл ip_block в файл net_block, который содержит вместо отдельных IP адресов список подсетей. Сделать это можно скриптом на python3 ip2net.py, например, таким:

#!/usr/bin/python3
with open('ip_block', 'r') as myfile:
 for line in myfile:
  lin = line.split('.')
  print(lin[0]+'.'+lin[1]+'.'+lin[2]+'.0/24')

После выполнения команды получим список подсетей, который вполне поместится в ss_rules_dst_forward:

python3 ip2net.py |sort |uniq >net_block

Полученный файл net_block можно дополнить какими-то своими адресами, записав их в другой файл, например, block и добавить к файлу подсетей командой:

cat block >> net_block

Если своих адресов не много, их можно вносить напрямую, добавляя строки Dst ip/net forward в web интерфейсе на вкладке Redir Rules.

Теперь остается лишь загрузить полученный файл net_block на роутер, исправить вкладку Redir Rules так, как это было показано ранее на скриншоте, сохранить конфигурацию и перезапустить скрипт вручную /etc/init.d/shadowsocks-libev restart или через web интерфейс. Кнопка Save & Apply почему-то не всегда помогает при обновлении списка.

Sorry, the comment form is closed at this time.