Заобиђите ИЛВ блокирање помоћу ДНСТап и БГП-а

Заобиђите ИЛВ блокирање помоћу ДНСТап и БГП-а

Тема је прилично излизана, знам. На пример, постоји одличан чланак, али се ту разматра само ИП део листе блокова. Такође ћемо додати домене.

Због чињенице да судови и РКН блокирају све лево и десно, а провајдери се труде да не потпадну под казне које издаје Ревизорро, повезани губици од блокирања су прилично велики. А међу „легитимно“ блокираним сајтовима има много корисних (здраво, рутрацкер)

Живим ван надлежности РКН, али моји родитељи, рођаци и пријатељи остају у мојој домовини. Стога је одлучено да се смисли једноставан начин за људе који су далеко од ИТ-а да заобиђу блокирање, по могућности без њиховог учешћа.

У овој напомени нећу описивати основне мрежне ствари корак по корак, већ ћу описати опште принципе како се ова шема може имплементирати. Дакле, знање о томе како мрежа уопште функционише и посебно у Линук-у је неопходно.

Врсте брава

Прво, да освежимо памћење о томе шта је блокирано.

Постоји неколико типова брава у преузетом КСМЛ-у са РКН-а:

  • IP
  • Домаин
  • УРЛ адреса

Ради једноставности, смањићемо их на два: ИП и домен, а од блокирања по УРЛ-у једноставно ћемо извући домен (или боље речено, ово је већ урађено за нас).

Добри људи из Роскомсвобода спровео диван АПИ за, кроз које можемо добити оно што нам је потребно:

Приступ блокираним сајтовима

Да бисмо то урадили, потребан нам је мали страни ВПС, пожељно са неограниченим саобраћајем - има их пуно за 3-5 долара. Морате га купити у блиском иностранству како пинг не би био превисок, али опет имајте на уму да се интернет и географија не поклапају увек. А пошто не постоји СЛА за 5 долара, боље је узети 2+ комада од различитих провајдера ради толеранције грешака.

Затим морамо да поставимо шифровани тунел од клијентског рутера до ВПС-а. Користим Вирегуард као најбржи и најлакши за конфигурисање јер... Моји клијентски рутери су такође засновани на Линуку (АПУ2 или нешто на ОпенВРТ). У случају неких Микротик/Цисцо-а, можете користити протоколе доступне на њима као што су ОпенВПН и ГРЕ-овер-ИПСЕЦ.

Идентификација и преусмеравање саобраћаја од интереса

Можете, наравно, спречити да сав интернет саобраћај иде у иностранство. Али, највероватније, брзина рада са локалним садржајем ће у великој мери патити од овога. Плус, захтеви за пропусни опсег на ВПС-у ће бити много већи.

Због тога ћемо морати некако да изолујемо саобраћај до блокираних сајтова и селективно га усмеримо у тунел. Чак и ако нешто од „додатног“ саобраћаја стигне тамо, то је и даље много боље него возити све кроз тунел.

Да бисмо управљали саобраћајем, користићемо БГП протокол и оглашавати руте до потребних мрежа од нашег ВПС-а до клијената. Узмимо БИРД као БГП демона, јер је један од најфункционалнијих и најпогоднијих.

IP

Све је јасно са ИП блокирањем: једноставно објављујемо све блокиране ИП адресе са ВПС-а. Проблем је што постоји око 600 хиљада подмрежа на листи коју пружа АПИ, а велика већина њих су /32 хоста. Овај број рута може збунити слабе клијентске рутере.

Због тога је приликом обраде листе одлучено да се сумира на /24 мрежу ако у њој има 2 или више хостова. Тако је број рута смањен на ~100 хиљада. Сценарио за ово ће уследити.

domeni

То је компликованије и постоји неколико начина. На пример, можете да инсталирате транспарентни Скуид на сваки клијентски рутер и тамо пресрете ХТТП и шпијунирате ТЛС руковање да бисте добили тражени УРЛ у првом случају и домен од СНИ у другом.

Али због новонасталих ТЛС1.3+еСНИ, ХТТПС анализа сваким даном постаје све мање реална. А инфраструктура на страни клијента постаје компликованија - мораћете да користите барем ОпенВРТ.

Стога сам одлучио да кренем путем пресретања одговора на ДНС упите. И овде нам почињу да лебде све врсте ДНС-овер-ТЛС/ХТТПС-а, али можемо (за сада) да контролишемо овај део на клијенту – или га онемогућимо или користимо сопствени сервер за ДоТ/ДоХ.

Како отети ДНС?

Овде такође може постојати неколико приступа.

  • Пресретање ДНС саобраћаја преко ПЦАП-а или НФЛОГ-а
    Обе ове методе пресретања су имплементиране у услужни програм сидмат. Али већ дуго није подржан и функционалност је веома примитивна, тако да још увек треба да напишете везу за њега.
  • Анализа дневника ДНС сервера
    Нажалост, рекурзори које познајем не знају како да евидентирају одговоре, већ само захтеве. У принципу, ово је логично, јер, за разлику од захтева, одговори имају сложену структуру и тешко их је написати у текстуалном облику.
  • ДНСТап
    Срећом, многи од њих већ подржавају ДНСТап за ове сврхе.

Шта је ДНСТап?

Заобиђите ИЛВ блокирање помоћу ДНСТап и БГП-а

Ово је клијент-сервер протокол заснован на баферима протокола и токовима оквира за пренос структурираних ДНС упита и одговора са ДНС сервера на колектор. У суштини, ДНС сервер преноси метаподатке захтева и одговора (тип поруке, ИП клијент/сервер, итд.) плус пуне ДНС поруке у (бинарном) облику у којем ради са њима преко мреже.

Важно је разумети да у ДНСТап парадигми, ДНС сервер делује као клијент, а колектор делује као сервер. То јест, ДНС сервер се повезује са колектором, а не обрнуто.

Данас је ДНСТап подржан на свим популарним ДНС серверима. Али, на пример, БИНД у многим дистрибуцијама (као што је Убунту ЛТС) се често компајлира из неког разлога без његове подршке. Дакле, немојмо се замарати обнављањем, већ узмимо лакши и бржи рекурсор - Унбоунд.

Како ухватити ДНСТап?

Ту је неки количество Постоје ЦЛИ услужни програми за рад са током ДНСТап догађаја, али они нису погодни за решавање нашег проблема. Зато сам одлучио да измислим свој бицикл, који ће учинити све што је потребно: днстап-бгп

Алгоритам рада:

  • Када се покрене, учитава листу домена из текстуалне датотеке, инвертује их (хабр.цом -> цом.хабр), искључује испрекидане линије, дупликате и поддомене (тј. ако листа садржи хабр.цом и ввв.хабр.цом, биће учитана само прва) и прави стабло префикса за брзу претрагу кроз ову листу
  • Делујући као ДНСТап сервер, чека везу са ДНС сервера. У принципу, подржава и УНИКС и ТЦП утичнице, али ДНС сервери које познајем подржавају само УНИКС утичнице
  • Долазни ДНСТап пакети се прво десериализују у Протобуф структуру, а затим се сама бинарна ДНС порука, која се налази у једном од Протобуф поља, анализира на ниво ДНС РР записа
  • Проверава се да ли је тражени хост (или његов надређени домен) на учитаној листи, ако није, одговор се игнорише
  • Из одговора се бирају само А/АААА/ЦНАМЕ РР-ови и из њих се издвајају одговарајуће ИПв4/ИПв6 адресе
  • ИП адресе се кеширају помоћу конфигурабилног ТТЛ-а и оглашавају свим конфигурисаним БГП колегама
  • Када добијете одговор који указује на већ кеширану ИП адресу, њен ТТЛ се ажурира
  • Након што ТТЛ истекне, унос се уклања из кеша и из БГП најава

Додатна функционалност:

  • Поновно читање листе домена од стране СИГХУП-а
  • Синхронизујте кеш са другим инстанцама днстап-бгп преко ХТТП/ЈСОН-а
  • Дуплирање кеша на диску (у БолтДБ бази података) да бисте вратили његов садржај након поновног покретања
  • Подршка за прелазак на други мрежни простор имена (зашто је то потребно биће описано у наставку)
  • ИПв6 подршка

Ограничења:

  • ИДН домени још увек нису подржани
  • Неколико БГП подешавања

Сакупио сам РПМ и ДЕБ пакети за једноставну инсталацију. Требало би да ради на свим релативно новијим ОС-овима са системд-ом, јер... немају зависности.

Схема

Дакле, почнимо да састављамо све компоненте заједно. Као резултат, требало би да добијемо нешто попут ове мрежне топологије:
Заобиђите ИЛВ блокирање помоћу ДНСТап и БГП-а

Логика рада, мислим, јасна је из дијаграма:

  • Клијент има наш сервер конфигурисан као ДНС, а ДНС захтеви такође морају да прођу кроз ВПН. Ово је неопходно да провајдер не може да користи ДНС пресретање за блокирање.
  • Када клијент отвори веб локацију, он шаље ДНС захтев попут „који ИП има ккк.орг?“
  • невезан решава ккк.орг (или га узима из кеша) и шаље одговор клијенту „ккк.орг има такав и такав ИП“, истовремено га дуплирајући преко ДНСТап
  • днстап-бгп оглашава ове адресе у БИРД преко БГП-а ако је домен на листи блокираних
  • БИРД оглашава руту до ових ИП адреса са next-hop self клијентски рутер
  • Наредни пакети од клијента до ових ИП адреса пролазе кроз тунел

На серверу користим посебну табелу унутар БИРД-а за руте до блокираних сајтова и ни на који начин се не укршта са ОС-ом.

У овој шеми постоји недостатак: први СИН пакет од клијента ће највероватније имати времена да прође преко домаћег провајдера јер Рута се не објављује одмах. И овде постоје могуће опције у зависности од тога како провајдер врши блокирање. Ако само обустави саобраћај, онда нема проблема. А ако га преусмери на неки ДПИ, онда су (теоретски) могући специјални ефекти.

Чуда су такође могућа са клијентима који не поштују ДНС ТТЛ, што може довести до тога да клијент користи неке застареле записе из свог поквареног кеша уместо да тражи Унбоунд.

У пракси, ни први ни други ми нису правили проблеме, али ваша километража може варирати.

Подешавање сервера

Ради лакшег покретања, написао сам улога за Ансибле. Може да конфигурише и сервере и клијенте засноване на Линуку (дизајниран за дистрибуције засноване на деб-у). Сва подешавања су прилично очигледна и постављена су инвентар.имл. Ова улога је исечена из моје велике свеске, тако да може садржати грешке - повуци захтеве Добродошли :)

Хајде да прођемо кроз главне компоненте.

БГП

Када покренете два БГП демона на истом хосту, појављује се фундаментални проблем: БИРД не жели да подигне БГП пееринг са локалним хостом (или са било којим локалним интерфејсом). Од речи апсолутно. Гуглање и читање маилинг-листа није помогло, тврде да је то по дизајну. Можда постоји неки начин, али га нисам нашао.

Можете испробати други БГП демон, али мени се свиђа БИРД и користим га свуда, не желим да креирам више ентитета.

Због тога сам сакрио днстап-бгп унутар мрежног именског простора, који је повезан са кореном преко ветх интерфејса: то је као цев чији крајеви вире у различитим именским просторима. На сваком од ових крајева прилажемо приватне п2п ИП адресе које не иду даље од хоста, тако да могу бити било шта. Ово је исти механизам који се користи за интерни приступ процесима свима миљеник Доцкер и други контејнери.

Због тога је и написано скрипта а већ описана функционалност превлачења за косу у други именски простор је додата у днстап-бгп. Због тога се мора покренути као роот или дати бинарном систему ЦАП_СИС_АДМИН преко команде сетцап.

Пример скрипте за креирање простора имена

#!/bin/bash

NS="dtap"

IP="/sbin/ip"
IPNS="$IP netns exec $NS $IP"

IF_R="veth-$NS-r"
IF_NS="veth-$NS-ns"

IP_R="192.168.149.1"
IP_NS="192.168.149.2"

/bin/systemctl stop dnstap-bgp || true

$IP netns del $NS > /dev/null 2>&1
$IP netns add $NS

$IP link add $IF_R type veth peer name $IF_NS
$IP link set $IF_NS netns $NS

$IP addr add $IP_R remote $IP_NS dev $IF_R
$IP link set $IF_R up

$IPNS addr add $IP_NS remote $IP_R dev $IF_NS
$IPNS link set $IF_NS up

/bin/systemctl start dnstap-bgp

днстап-бгп.цонф

namespace = "dtap"
domains = "/var/cache/rkn_domains.txt"
ttl = "168h"

[dnstap]
listen = "/tmp/dnstap.sock"
perm = "0666"

[bgp]
as = 65000
routerid = "192.168.149.2"

peers = [
    "192.168.149.1",
]

бирд.цонф

router id 192.168.1.1;

table rkn;

# Clients
protocol bgp bgp_client1 {
    table rkn;
    local as 65000;
    neighbor 192.168.1.2 as 65000;
    direct;
    bfd on;
    next hop self;
    graceful restart;
    graceful restart time 60;
    export all;
    import none;
}

# DNSTap-BGP
protocol bgp bgp_dnstap {
    table rkn;
    local as 65000;
    neighbor 192.168.149.2 as 65000;
    direct;
    passive on;
    rr client;
    import all;
    export none;
}

# Static routes list
protocol static static_rkn {
    table rkn;
    include "rkn_routes.list";
    import all;
    export none;
}

ркн_роутес.лист

route 3.226.79.85/32 via "ens3";
route 18.236.189.0/24 via "ens3";
route 3.224.21.0/24 via "ens3";
...

ДНС

Подразумевано, у Убунту-у, Унбоунд бинарни фајл је стегнут са АппАрмор профилом, који му забрањује повезивање са било којим ДНСТап утичницама. Можете или да избришете овај профил или да га онемогућите:

# cd /etc/apparmor.d/disable && ln -s ../usr.sbin.unbound .
# apparmor_parser -R /etc/apparmor.d/usr.sbin.unbound

Ово би вероватно требало додати у свеску. Било би идеално, наравно, исправити профил и издати потребна права, али сам био превише лењ.

унбоунд.цонф

server:
    chroot: ""
    port: 53
    interface: 0.0.0.0
    root-hints: "/var/lib/unbound/named.root"
    auto-trust-anchor-file: "/var/lib/unbound/root.key"
    access-control: 192.168.0.0/16 allow

remote-control:
    control-enable: yes
    control-use-cert: no

dnstap:
    dnstap-enable: yes
    dnstap-socket-path: "/tmp/dnstap.sock"
    dnstap-send-identity: no
    dnstap-send-version: no

    dnstap-log-client-response-messages: yes

Преузимање и обрада листа

Скрипта за преузимање и обраду листе ИП адреса
Преузима листу, сумира у префикс пфк. У донт_адд и донт_суммаризе можете рећи које ИП адресе и мреже треба прескочити или не сумирати. Ово ми је требало јер... моја ВПС подмрежа је била на листи блокираних :)

Смешно је то што АПИ РосКомСвобода блокира захтеве са подразумеваним Питхон корисничким агентом. Изгледа да су добили сценарио мали. Стога га мењамо у Огнелис.

За сада ради само са ИПв4 јер... ИПв6 удео је мали, али ће се лако поправити. Осим ако не морате да користите и бирд6.

ркн.пи

#!/usr/bin/python3

import json, urllib.request, ipaddress as ipa

url = 'https://api.reserve-rbl.ru/api/v2/ips/json'
pfx = '24'

dont_summarize = {
    # ipa.IPv4Network('1.1.1.0/24'),
}

dont_add = {
    # ipa.IPv4Address('1.1.1.1'),
}

req = urllib.request.Request(
    url,
    data=None, 
    headers={
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 Safari/537.36'
    }
)

f = urllib.request.urlopen(req)
ips = json.loads(f.read().decode('utf-8'))

prefix32 = ipa.IPv4Address('255.255.255.255')

r = {}
for i in ips:
    ip = ipa.ip_network(i)
    if not isinstance(ip, ipa.IPv4Network):
        continue

    addr = ip.network_address

    if addr in dont_add:
        continue

    m = ip.netmask
    if m != prefix32:
        r[m] = [addr, 1]
        continue

    sn = ipa.IPv4Network(str(addr) + '/' + pfx, strict=False)

    if sn in dont_summarize:
        tgt = addr
    else:
        tgt = sn

    if not sn in r:
        r[tgt] = [addr, 1]
    else:
        r[tgt][1] += 1

o = []
for n, v in r.items():
    if v[1] == 1:
        o.append(str(v[0]) + '/32')
    else:
        o.append(n)

for k in o:
    print(k)

Скрипта за ажурирање
Провлачим га једном дневно кроз круну, можда је вредно трчати једном на 4 сата јер... Ово је, по мом мишљењу, период обнове који РКН захтева од провајдера. Осим тога, имају још неке супер-хитне блокаде које могу стићи брже.

ради следеће:

  • Покреће прву скрипту и ажурира листу рута (rkn_routes.list) за БИРД
  • Релоад БИРД
  • Ажурира и чисти листу домена за днстап-бгп
  • Поново учитај днстап-бгп

ркн_упдате.сх

#!/bin/bash

ROUTES="/etc/bird/rkn_routes.list"
DOMAINS="/var/cache/rkn_domains.txt"

# Get & summarize routes
/opt/rkn.py | sed 's/(.*)/route 1 via "ens3";/' > $ROUTES.new

if [ $? -ne 0 ]; then
    rm -f $ROUTES.new
    echo "Unable to download RKN routes"
    exit 1
fi

if [ -e $ROUTES ]; then
    mv $ROUTES $ROUTES.old
fi

mv $ROUTES.new $ROUTES

/bin/systemctl try-reload-or-restart bird

# Get domains
curl -s https://api.reserve-rbl.ru/api/v2/domains/json -o - | jq -r '.[]' | sed 's/^*.//' | sort | uniq > $DOMAINS.new

if [ $? -ne 0 ]; then
    rm -f $DOMAINS.new
    echo "Unable to download RKN domains"
    exit 1
fi

if [ -e $DOMAINS ]; then
    mv $DOMAINS $DOMAINS.old
fi

mv $DOMAINS.new $DOMAINS

/bin/systemctl try-reload-or-restart dnstap-bgp

Написане су без много размишљања, па ако видите нешто што се може побољшати, наставите.

Подешавање клијента

Овде ћу дати примере за Линук рутере, али у случају Микротик/Цисцо би требало да буде још једноставније.

Прво, подесите БИРД:

бирд.цонф

router id 192.168.1.2;
table rkn;

protocol device {
    scan time 10;
};

# Servers
protocol bgp bgp_server1 {
    table rkn;
    local as 65000;
    neighbor 192.168.1.1 as 65000;
    direct;
    bfd on;
    next hop self;
    graceful restart;
    graceful restart time 60;
    rr client;
    export none;
    import all;
}

protocol kernel {
    table rkn;
    kernel table 222;
    scan time 10;
    export all;
    import none;
}

На овај начин ћемо синхронизовати руте примљене од БГП-а са табелом рутирања језгра број 222.

Након овога, довољно је замолити кернел да погледа ову табелу пре него што погледа подразумевану:

# ip rule add from all pref 256 lookup 222
# ip rule
0:  from all lookup local
256:    from all lookup 222
32766:  from all lookup main
32767:  from all lookup default

То је то, остаје само да конфигуришете ДХЦП на рутеру да дистрибуира ИП адресу тунела сервера као ДНС и шема је спремна.

Ограничења

Са актуелним алгоритмом за генерисање и обраду листе домена, он између осталог укључује youtube.com и његове ЦДН-ове.

А то доводи до чињенице да ће сви видео снимци бити послати преко ВПН-а, што може зачепити цео канал. Можда би било вредно саставити листу популарних домена изузетака које је РКН још увек преслаб да би их блокирао. И прескочите их приликом рашчлањивања.

Закључак

Описани метод вам омогућава да заобиђете скоро свако блокирање које провајдери тренутно примењују.

У основи, днстап-бгп може се користити у било које друге сврхе где је потребан одређени ниво управљања саобраћајем на основу имена домена. Само треба да узмете у обзир да данас хиљаду сајтова може да виси на истој ИП адреси (иза неког Цлоудфлареа, на пример), тако да овај метод има прилично ниску тачност.

Али за потребе заобилажења блокирања, ово је сасвим довољно.

Додаци, измене, захтеви за повлачење су добродошли!

Извор: ввв.хабр.цом

Додај коментар