Главная » Хабрахабр » [recovery mode] Настройка BGP для обхода блокировок, или «Как я перестал бояться и полюбил РКН»

[recovery mode] Настройка BGP для обхода блокировок, или «Как я перестал бояться и полюбил РКН»

Скорее «смог сосуществовать с». Ну ладно, про «полюбил» — это преувеличение.

В результате граждане Российской Федерации и бизнес страдают, потеряв доступ к необходимым им совершенно легальным ресурсам. Как вы все знаете, с 16 апреля 2018 года Роскомнадзор крайне широкими мазками блокирует доступ к ресурсам в сети, добавляя в "Единый реестр доменных имен, указателей страниц сайтов в сети «Интернет» и сетевых адресов, позволяющих идентифицировать сайты в сети «Интернет», содержащие информацию, распространение которой в Российской Федерации запрещено" (по тексту — просто реестр) по /10 иногда.

Когда у них всё заработало, один из них порекомендовал описать методику в статье. После того, как в комментариях к одной из статей на Хабре я сказал, что готов помочь пострадавшим с настройкой схемы обхода, ко мне обратились несколько человек с просьбой о такой помощи. хабрапост. Поразмыслив, решил нарушить свое молчание на сайте и попробовать в кои-то веки написать что-то промежуточное между проектом и постом в Facebook, т.е. Результат — перед вами.

Disclaimer

А доступ к другим ресурсам, получаемый в результате действий из статьи, является досадным побочным эффектом и целью статьи ни в коем случае не является. Поскольку публиковать способы обхода блокировок доступа к информации, запрещенной на территории Российской Федерации, не очень законно, целью этой статьи будет рассказать о методе, позволяющем автоматизировать получение доступа к ресурсам, разрешенным на территории Российской Федерации, но из-за чьих-то действий недоступным напрямую через вашего провайдера.

Поэтому, безусловно, скрипты можно написать лучше, вопросы безопасности в VPS можно проработать глубже и т.д. Также, поскольку я по профессии, призванию и жизненному пути прежде всего сетевой архитектор, программирование и линуксы не являются моими сильными сторонами. Ваши предложения будут приняты с благодарностью, если они будут достаточно детальны — с удовольствием добавлю их в текст статьи.

TL;DR

Цель — убрать весь трафик, адресованный заблокированным ресурсам, в туннель. Автоматизируем доступ к ресурсам через существующий у вас туннель, используя копию реестра и протокол BGP. Минимум объяснений, в основном пошаговая инструкция.

Что вам для этого потребуется

Для того, чтобы воспользоваться этой методикой, вам нужно будет собрать вместе несколько элементов: К сожалению, этот пост не для каждого.

  1. У вас должен быть linux-сервер где-то за пределами поля блокировок. Или хотя бы желание такой сервер завести — благо это сейчас стоит от $9/год, а возможно и меньше. Метод также подходит, если у вас есть отдельный VPN-туннель, тогда сервер может располагаться и внутри поля блокировок.
  2. Ваш роутер должен быть достаточно умным, чтобы уметь
    • любой нравящийся вам VPN-клиент (я предпочитаю OpenVPN, но это может быть PPTP, L2TP, GRE+IPSec и любой другой вариант, создающий туннельный интерфейс);
    • протокол BGPv4. Что означает, что для SOHO это может быть Mikrotik или любой роутер с OpenWRT/LEDE/аналогичными кастомными прошивками, позволяющими установить Quagga или Bird. Использование PC-роутера также не возбраняется. В случае энтерпрайза смотрите поддержку BGP в документации к вашему бордер-роутеру.
  3. Вы должны иметь представление о использовании Linux и сетевых технологиях, в том числе о протоколе BGP. Или хотя бы хотеть получить такое представление. Поскольку объять необъятное в этот раз я не готов, некоторые непонятные для вас моменты вам придется изучить самостоятельно. Впрочем, на конкретные вопросы, конечно же, отвечу в комментариях и вряд ли окажусь единственным отвечающим, так что не стесняйтесь спрашивать.

Что используется в примере

  • Копия реестра — из https://github.com/zapret-info/z-i 
  • VPS — Ubuntu 16.04
  • Сервис маршрутизации — bird 1.6.3   
  • Маршрутизатор — Mikrotik hAP ac
  • Рабочие папки — поскольку работаем от рута, бОльшая часть всего будет размещаться в домашней папке рута. Соответственно:
    • /root/blacklist — рабочая папка со скриптом компиляции
    • /root/z-i — копия реестра с github
    • /etc/bird — стандартная папка настроек сервиса bird
  • Внешним IP-адресом VPS с сервером маршрутизации и точкой терминации туннеля принимаем 194.165.22.146, ASN 64998; внешним IP-адресом роутера — 81.177.103.94, ASN 64999
  • IP адреса внутри туннеля — 172.30.1.1 и 172.30.1.2 соответственно.

image

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

Кратко — логика решения

  1. Подготовительные действия
    1. Получаем VPS
    2. Поднимаем туннель от маршрутизатора к VPS
  2. Получаем и регулярно обновляем копию реестра
  3. Устанавливаем и настраиваем сервис маршрутизации
  4. Создаем на основании реестра список статических маршрутов для сервиса маршрутизации
  5. Подключаем роутер к сервису и настраиваем отправку всего трафика через туннель.

Собственно решение

Подготовительные действия

Пока я нашел и пользуюсь вариантом за $9/год, но даже если не особо заморачиваться — вариантов за 1E/месяц много на каждом углу. На просторах сети есть множество сервисов, предоставляющих VPS за крайне умеренные деньги. Вопрос выбора VPS лежит далеко за пределами этой статьи, поэтому если кому-то что-то непонятно в этом — спросите в комментариях.

В сети большое количество инструкций по этим действиям, здесь я их повторять не буду. Если вы будете использовать VPS не только для сервиса маршрутизации, но и для терминации на нем туннеля — вам нужно поднять этот туннель и, практически однозначно, настроить NAT для него. Этому требованию соответствует большинство используемых технологий VPN — например, OpenVPN в tun режиме прекрасно подходит. Основное требование к такому туннелю — он должен создавать на вашем роутере, поддерживающем туннель в сторону VPS, отдельный интерфейс.

Получение копии реестра

Раз уж РКН создает реестр запрещенных ресурсов, грешно было бы не воспользоваться этим реестром для решения нашей задачи. Как говорил Джабраил, "Тот, кто нам мешает, тот нам поможет". Копию реестра мы будем получать с github.

Заходим на ваш линукс-сервер, проваливаемся в контекст root'а (sudo su -) и устанавливаем git, если он еще не установлен.

apt install git

Переходим в домашнюю директорию и вытягиваем копию реестра.

cd ~ && git clone https://github.com/zapret-info/z-i

Для этого запускаем crontab -e и добавляем в него следующую строку: Настраиваем обновление по крону (у меня раз в 20 минут, но вы можете выбрать любой интересный вам интервал).

*/20 * * * * cd ~/z-i && git pull

Для этого создаем файл /root/z-i/.git/hooks/post-merge со следующим содержимым: Подключаем хук, который будет создавать файлы для сервиса маршрутизации после обновления реестра.

#!/usr/bin/env bash
changed_files="$(git diff-tree -r --name-only --no-commit-id ORIG_HEAD HEAD)"
check_run() { echo "$changed_files" | grep --quiet "$1" && eval "$2"
}
check_run dump.csv "/root/blacklist/makebgp"

и не забываем сделать его исполняемым

chmod +x /root/z-i/.git/hooks/post-merge

Скрипт makebgp, на который ссылается хук, мы создадим чуть позже.

Установка и настройка сервиса маршрутизации

К сожалению, выложенная в репозиториях Ubuntu на данный момент версия bird по свежести сопоставима с фекалиями археоптерикса, поэтому нам необходимо предварительно добавить в систему официальный PPA разработчиков ПО. Устанавливаем bird.

add-apt-repository ppa:cz.nic-labs/bird
apt update
apt install bird

После этого сразу отключаем bird для IPv6 — в этой инсталляции он для нас не потребуется.

systemctl stop bird6
systemctl disable bird6

Ниже приведен минималистичный файл конфигурации сервиса bird (/etc/bird/bird.conf), которого нам вполне хватит (и еще раз напоминаю, что никто не запрещает развивать и дотюнивать идею под ваши собственные потребности)

log syslog all;
router id 172.30.1.1; protocol kernel { scan time 60; import none;
# export all; # Actually insert routes into the kernel routing table
} protocol device { scan time 60;
} protocol direct { interface "venet*", "tun*"; # Restrict network interfaces it works with
} protocol static static_bgp { import all; include "pfxlist.txt"; #include "iplist.txt";
} protocol bgp OurRouter { description "Our Router"; neighbor 81.177.103.94 as 64999; import none; export where proto = "static_bgp"; local as 64998; passive off; multihop;
}

В нашем случае может быть вообще любым 32-битным числом в формате IPv4-адреса, но хорошим тоном является указывать там именно IPv4-адрес вашего устройства (в данном случае VPS). router id — идентификатор роутера, визуально выглядящий как IPv4-адрес, но им не являющийся.

В примере дана пара примеров имен, можно добавлять и другие. protocol direct определяет, какие интерфейсы будут работать с процессом маршрутизации. Можно и просто удалить строку, в этом случае сервер будет слушать все доступные интерфейсы с IPv4-адресом.

Откуда появляются эти списки — будет рассмотрено ниже. protocol static — наше волшебство, которое подгружает из файлов списки префиксов и ip-адресов (которые на самом деле, конечно, префиксы по /32) для последующего анонса. Для сравнения, в списке префиксов на момент написания статьи 78 строк, а в списке ip-адресов — 85898. Обратите внимание, что загрузка ip-адресов по умолчанию закомментирована, причина этого — большой объем выгрузки. Далеко не каждый из них легко переварит 85 тысяч записей в таблице маршрутизации. Настоятельно рекомендую запускаться и отлаживаться только на списке префиксов, а включать или не включать в дальнейшем подгрузку ip — решать после экспериментов со своим роутером.

ip-адрес — это адрес внешнего интерфейса роутера (либо адрес интерфейса туннеля со стороны роутера), 64998 и 64999 — номера автономных систем. protocol bgp, собственно, настраивает bgp-пиринг с вашим роутером. Описанная конфигурация использует eBGP пиринг, при котором номера автономных систем сервиса маршрутизации и роутера должны различаться. Их в данном случае можно назначить в виде любых 16-битных чисел, но хорошим тоном является использование номеров AS из приватного диапазона, определенного RFC6996 — 64512-65534 включительно (существует формат 32-битных ASN, но в нашем случае это точно излишество).

Как вы можете заметить, сервису нужно знать IP-адрес роутера, поэтому если у вас динамический или немаршрутизируемый private (RFC1918) или shared (RFC6598) адрес, варианта поднимать пиринг на внешнем интерфейсе у вас нет, но внутри туннеля сервис все равно будет работать.

Именно поэтому в примере показаны настройки для пиринга вне туннеля, как наиболее универсальные. Достаточно прозрачно также, что с одного сервиса вы можете обеспечивать маршрутами несколько разных роутеров — достаточно продублировать настройки для них копированием секции protocol bgp со сменой IP-адреса соседа. Убрать их в туннель несложно, поменяв соответственно IP-адреса в настройках.

Обработка реестра для сервиса маршрутизации

Для этого мы берем файл реестра и делаем из него нужные нам файлы следующим скриптом, размещаемым в /root/blacklist/makebgp Сейчас нам надо, собственно, создать списки префиксов и ip-адресов, которые на предыдущем этапе упомянуты в protocol static.

#!/bin/bash
cut -d";" -f1 /root/z-i/dump.csv| tr '|' '\n' | tr -d ' ' > /root/blacklist/tmpaddr.txt
cat /root/blacklist/tmpaddr.txt | grep / | sed 's_.*_route & reject;_' > /etc/bird/pfxlist.txt
cat /root/blacklist/tmpaddr.txt | sort | uniq | grep -Eo "([0-9][\.]){3}[0-9]{1,3}" | sed 's_.*_route &/32 reject;_' > /etc/bird/iplist.txt
/etc/init.d/bird reload
logger 'bgp list compiled'

Не забываем сделать его исполняемым

chmod +x /root/blacklist/makebgp

Теперь можно запустить его вручную и пронаблюдать появление файлов в /etc/bird.

Поэтому запускаем его и контролируем, что он запустился: Вероятнее всего, в этот момент bird у вас не работает, поскольку на предыдущем этапе вы ему предложили поискать файлы, которых еще не было.

systemctl start bird
birdc show route

Вывод второй команды должен показать около 80 записей (это на данный момент, а когда будете настраивать, всё будет зависеть от рьяности РКН в блокировках сетями) вида приблизительно такого:

54.160.0.0/12 unreachable [static_bgp 2018-04-19] * (200)

Команда

birdc show protocol

Пока вы не настроили роутер (см. покажет состояние протоколов внутри сервиса. Например, в моей системе вывод этой команды выглядит следующим образом: следующий пункт), протокол OurRouter будет в состоянии start (фазы Connect или Active), а после успешного подключения перейдет в состояние up (фаза Established).

BIRD 1.6.3 ready.
name proto table state since info
kernel1 Kernel master up 2018-04-19
device1 Device master up 2018-04-19
static_bgp Static master up 2018-04-19
direct1 Direct master up 2018-04-19
RXXXXXx1 BGP master up 13:10:22 Established
RXXXXXx2 BGP master up 2018-04-24 Established
RXXXXXx3 BGP master start 2018-04-22 Connect Socket: Connection timed out
RXXXXXx4 BGP master up 2018-04-24 Established
RXXXXXx5 BGP master start 2018-04-24 Passive

Gj

Подключение роутера

Тем более, что в этом разделе я не смогу дать пошаговую инструкцию — для каждого производителя она будет своя. Все уже, наверное, устали читать эту портянку, но мужайтесь — конец близок.

Основная логика — поднять BGP-пиринг и на все получаемые префиксы навесить nexthop, указывающий на наш туннель (если нужно выводить трафик через p2p интерфейс) или ip-адрес некстхопа, если трафик будет уходить в ethernet). Однако могу показать пару примеров.

Например, на Mikrotik в RouterOS это решается следующим образом

/routing bgp instance set default as=64999 ignore-as-path-len=yes router-id=172.30.1.2
/routing bgp peer add in-filter=dynamic-in name=VPS remote-address=194.165.22.146 remote-as=64998 ttl=default
/routing filter add action=accept chain=dynamic-in comment="Set nexthop" set-in-nexthop=172.30.1.1

а в Cisco IOS — вот так

router bgp 64999 neighbor 194.165.22.146 remote-as 64998 neighbor 194.165.22.146 route-map BGP_NEXT_HOP in
!
route-map BGP_NEXT_HOP permit 10 set ip next-hop 172.30.1.1

Но если выставите вручную — хуже от этого тоже не будет. В том случае, если один и тот же туннель используется и для BGP-пиринга, и для передачи полезного трафика, выставлять nexthop не обязательно, он выставится правильно средствами протокола.

На других платформах вам придется разбираться в конфигурировании самостоятельно, но если возникнут затруднения — пишите в комментариях, попробую помочь.

После того, как у вас поднялась BGP-сессия, прилетели и установились в таблицу маршруты на крупные сети, трафик на адреса из них пошел и счастье близко, вы можете вернуться к сервису bird и попробовать раскомментировать там запись, подключающую список ip-адресов, выполнить после этого

systemctl reload bird

Будьте готовы отключать и думать, что с этим делать 🙂 и посмотреть, как ваш роутер перенес эти 85 тысяч маршрутов.

Итого

Чисто теоретически после выполнения вышеописанных действий у вас появился сервис, который автоматически перенаправляет трафик к забаненным в РФ IP-адресам мимо системы фильтрации.

Например, достаточно легко сделать суммаризацию списка ip-адресов через решения на perl или python. Его, конечно, можно дорабатывать. Простой скрипт на perl, делающий это с помощью Net::CIDR::Lite, превращает 85 тысяч префиксов в 60 (не тысяч), но, естественно, перекрывает гораздо бОльший диапазон адресов, чем заблокировано.

Но вместе с реестром из github прилетает файл nxdomain.txt, который несколькими штрихами скрипта легко превращается в источник адресов для, например, плагина SwitchyOmega в Chrome. Поскольку сервис работает на третьем уровне модели ISO/OSI, он не спасет от блокировок по сайту/странице, если оно резолвится не в тот адрес, который записан в реестре.

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

При возникновении вопросов — задавайте, готов отвечать.


Оставить комментарий

Ваш email нигде не будет показан
Обязательные для заполнения поля помечены *

*

x

Ещё Hi-Tech Интересное!

Аркадий Волож отказался продавать свою долю в «Яндексе»

Пресс-служба «Яндекса» опубликовала заявление по поводу слухов на рынке о продаже Сбербанку контрольного пакета акций. В заявлении приводятся слова основателя и основного акционера компании Аркадия Воложа: — Когда-то все сотрудники Яндекса умещались в одной квартире, а сегодня в компании работают ...

Министерство внутренней безопасности США изъяло восстановленные батареи к ноутбукам Apple, назвав их поддельными

Обычно крупные корпорации, такие, как Apple, стремятся зарабатывать на ремонте и обслуживании собственных устройств, поэтому независимым сервисным центрам компании часто вставляют палки в колеса. О «праве на ремонт» на Хабре опубликовано много материалов. Все это получают сертифицированные центры, но не ...