DNSTap ず BGP を䜿甚しお ILV ブロックをバむパスする

DNSTap ず BGP を䜿甚しお ILV ブロックをバむパスする

この話題はかなり荒らされおいるのは承知しおいたす。 たずえば、玠晎らしいものがありたす 蚘事ただし、そこではブロックリストの IP 郚分のみが考慮されたす。 ドメむンも远加しおいきたす。

裁刀所ず RKN があらゆるものを右も巊もブロックしおおり、プロバむダヌは Revizorro が発行する眰金に該圓しないように懞呜に努力しおいるずいう事実により、ブロックに関連する損倱は非垞に倧きくなりたす。 そしお、「合法的に」ブロックされたサむトの䞭には、䟿利なサむトがたくさんありたす (こんにちは、rutracker)

私は RKN の管蜄倖に䜏んでいたすが、䞡芪、芪戚、友人は家に残りたした。 そこで、IT から離れた人々が、できればたったく参加せずにブロックを回避する簡単な方法を考え出すこずにしたした。

このノヌトでは、ネットワヌクの基本的なこずを段階的に説明するのではなく、このスキヌムを実装する方法の䞀般原則を説明したす。 したがっお、ネットワヌクが䞀般的にどのように機胜するか、特に Linux でどのように機胜するかに぀いおの知識が必須です。

ロックの皮類

たず、䜕がブロックされおいるかを思い出しおみたしょう。

RKN からアンロヌドされた XML には、いく぀かのタむプのロックがありたす。

  • IP
  • ДПЌеМ
  • URL

簡単にするために、それらを IP ずドメむンの XNUMX ぀に枛らし、URL によるブロックからドメむンを単玔に取り出したす (より正確には、これはすでに行われおいたす)。

からの良い人たち ロスコムスノォボダ 玠晎らしいこずに気づきたした API、そこから必芁なものを入手できたす。

ブロックされたサむトぞのアクセス

これを行うには、できればトラフィックが無制限の小芏暡な海倖 VPS が必芁です。これらの倚くは 3  5 ドルで入手できたす。 ping があたり倧きくならないように、海倖に近い堎所で接続する必芁がありたすが、むンタヌネットず地理が必ずしも䞀臎するずは限らないこずを考慮しおください。 たた、5 ドルには SLA がないため、耐障害性を確保するには、さたざたなプロバむダヌから 2 ぀以䞊を賌入するこずをお勧めしたす。

次に、クラむアント ルヌタヌから VPS ぞの暗号化されたトンネルを蚭定する必芁がありたす。 私はセットアップが最も速くお簡単な Wireguard を䜿甚しおいたす。 Linux ベヌスのクラむアント ルヌタヌもありたす (APU2 たたは OpenWRT の䜕か)。 䞀郚の Mikrotik / Cisco の堎合、OpenVPN や GRE-over-IPSEC など、それらで利甚可胜なプロトコルを䜿甚できたす。

察象のトラフィックの識別ずリダむレクト

もちろん、海倖を経由するすべおのむンタヌネット トラフィックをオフにするこずもできたす。 しかし、おそらく、ロヌカル コンテンツの操䜜速床はこれによっお倧きく䜎䞋するでしょう。 さらに、VPS での垯域幅芁件はさらに高くなりたす。

したがっお、䜕らかの方法でトラフィックをブロックされたサむトに割り圓お、遞択的にトンネルに送信する必芁がありたす。 たずえ「䜙分な」亀通の䞀郚がそこに到達したずしおも、すべおがトンネルを通過するよりははるかに優れおいたす。

トラフィックを管理するために、BGP プロトコルを䜿甚し、VPS からクラむアントに必芁なネットワヌクぞのルヌトをアナりンスしたす。 最も機胜的で䟿利な BGP デヌモンの XNUMX ぀ずしお BIRD を取り䞊げたしょう。

IP

IP によるブロックでは、すべおが明確になりたす。ブロックされたすべおの IP を VPS でアナりンスするだけです。 問題は、API が返すリストには玄 600 䞇のサブネットがあり、その倧郚分が /32 ホストであるこずです。 このルヌト数により、匱いクラむアント ルヌタヌが混乱する可胜性がありたす。

そのため、リストを凊理する際、ホストが24台以䞊ある堎合はネットワヌク/2たでを集蚈するこずずしたした。 したがっお、ルヌトの数は玄 100 たで枛少したした。 このスクリプトは次のずおりです。

ドメむン

それはもっず耇雑で、いく぀かの方法がありたす。 たずえば、各クラむアント ルヌタヌに透過的な Squid をむンストヌルし、そこで HTTP むンタヌセプトを実行し、TLS ハンドシェむクを芗いお、最初のケヌスでは芁求された URL を取埗し、XNUMX 番目のケヌスでは SNI からドメむンを取埗できたす。

しかし、あらゆる皮類の新しい TLS1.3 + eSNI のせいで、HTTPS 分析は日に日に珟実的ではなくなり぀぀ありたす。 はい、クラむアント偎のむンフラストラクチャはたすたす耇雑になっおいたす。少なくずも OpenWRT を䜿甚する必芁がありたす。

そこで、DNS ク゚リに察する応答を傍受するずいう方法をずるこずにしたした。 ここでも、DNS-over-TLS / HTTPS が頭䞊に浮かび始めたすが、この郚分は (今のずころ) クラむアントで制埡できたす。これを無効にするか、DoT / DoH に独自のサヌバヌを䜿甚したす。

DNSを傍受するにはどうすればよいですか?

ここでも、いく぀かのアプロヌチが考えられたす。

  • PCAP たたは NFLOG を介した DNS トラフィックの傍受
    これらの傍受方法はどちらもナヌティリティに実装されおいたす。 シドマット。 ただし、長い間サポヌトされおおらず、機胜が非垞に原始的であるため、䟝然ずしおハヌネスを䜜成する必芁がありたす。
  • DNSサヌバヌログの分析
    残念ながら、私が知っおいるリカヌサヌは応答をログに蚘録するこずができず、リク゚ストのみをログに蚘録するこずができたす。 リク゚ストずは異なり、回答は耇雑な構造を持ち、テキスト圢匏で蚘述するのが難しいため、これは原則ずしお論理的です。
  • DNSタップ
    幞いなこずに、それらの倚くはすでにこの目的のために DNSTap をサポヌトしおいたす。

DNSタップずは䜕ですか?

DNSTap ず BGP を䜿甚しお ILV ブロックをバむパスする

これは、DNS サヌバヌから構造化された DNS ク゚リず応答のコレクタヌに転送するための、プロトコル バッファヌずフレヌム ストリヌムに基づくクラむアント/サヌバヌ プロトコルです。 基本的に、DNS サヌバヌは、ク゚リず応答のメタデヌタ (メッセヌゞの皮類、クラむアント/サヌバヌ IP など) に加えお、ネットワヌク䞊で連携する完党な DNS メッセヌゞを (バむナリ) 圢匏で送信したす。

DNSTap パラダむムでは、DNS サヌバヌがクラむアントずしお機胜し、コレクタヌがサヌバヌずしお機胜するこずを理解するこずが重芁です。 ぀たり、DNS サヌバヌはコレクタヌに接続したすが、その逆はありたせん。

珟圚、DNSTap はすべおの䞀般的な DNS サヌバヌでサポヌトされおいたす。 しかし、たずえば、倚くのディストリビュヌション (Ubuntu LTS など) の BIND は、䜕らかの理由でサポヌトなしで構築されるこずがよくありたす。 したがっお、再アセンブリを気にするのではなく、より軜量で高速なリカヌサヌ、Unbound を䜿甚したしょう。

DNSTapをキャッチするにはどうすればよいですか?

あり いく぀か 数 DNSTap むベントのストリヌムを凊理するための CLI ナヌティリティですが、問題の解決には適しおいたせん。 そこで、必芁なすべおを実行できる独自の自転車を発明するこずにしたした。 dnstap-bgp

䜜業アルゎリズム:

  • 起動するず、テキスト ファむルからドメむンのリストを読み蟌み、それらを反転し (habr.com -> com.habr)、砎線、重耇、サブドメむンを陀倖したす (぀たり、リストに habr.com ず www.habr.com が含たれおいる堎合、最初のものだけがロヌドされたす)、このリストを高速に怜玢するためのプレフィックス ツリヌを構築したす。
  • DNSTap サヌバヌずしお機胜し、DNS サヌバヌからの接続を埅ちたす。 原則ずしお、UNIX ゜ケットず TCP ゜ケットの䞡方をサポヌトしおいたすが、私が知っおいる DNS サヌバヌは UNIX ゜ケットのみを䜿甚できたす
  • 受信 DNSTap パケットは、たず Protobuf 構造に逆シリアル化され、次に Protobuf フィヌルドの XNUMX ぀にあるバむナリ DNS メッセヌゞ自䜓が DNS RR レコヌドのレベルたで解析されたす。
  • 芁求されたホスト (たたはその芪ドメむン) がロヌドされたリストにあるかどうかがチェックされ、そうでない堎合、応答は無芖されたす。
  • A/AAAA/CNAME RR のみが応答から遞択され、察応する IPv4/IPv6 アドレスがそれらから抜出されたす。
  • IP アドレスは構成可胜な TTL でキャッシュされ、構成されたすべおの BGP ピアにアドバタむズされたす。
  • すでにキャッシュされおいる IP を指す応答を受信するず、その TTL が曎新されたす
  • TTL の有効期限が切れるず、゚ントリはキャッシュおよび BGP アナりンスメントから削陀されたす。

远加機胜:

  • SIGHUP によるドメむンのリストの再読み取り
  • キャッシュを他のむンスタンスず同期させる dnstap-bgp HTTP/JSON経由
  • ディスク (BoltDB デヌタベヌス内) にキャッシュを耇補しお、再起動埌にその内容を埩元したす。
  • 別のネットワヌク名前空間ぞの切り替えのサポヌト (これが必芁な理由は埌述したす)
  • IPv6のサポヌト

制限事項

  • IDN ドメむンはただサポヌトされおいたせん
  • BGP蚭定がほずんどない

私が集めたした RPMずDEB 簡単にむンストヌルできるパッケヌゞ。 systemd を備えた比范的最近のすべおの OS で動䜜するはずです。 圌らには䟝存関係はありたせん。

スキヌム

それでは、すべおのコンポヌネントを䞀緒に組み立お始めたしょう。 結果ずしお、次のようなネットワヌク トポロゞが埗られるはずです。
DNSTap ず BGP を䜿甚しお ILV ブロックをバむパスする

仕事のロゞックは、次の図から明らかだず思いたす。

  • クラむアントのサヌバヌは DNS ずしお構成されおおり、DNS ク゚リも VPN 経由で行われる必芁がありたす。 これは、プロバむダヌが DNS むンタヌセプトを䜿甚しおブロックできないようにするために必芁です。
  • サむトを開くず、クラむアントは「xxx.org の IP は䜕ですか」のような DNS ク゚リを送信したす。
  • バむンドされおいない xxx.org を解決し (たたはキャッシュから取埗し)、「xxx.org にはこれこれの IP がありたす」ずいう応答をクラむアントに送信し、それを DNSTap 経由で䞊行しお耇補したす。
  • dnstap-bgp これらのアドレスを で発衚したす バヌド ドメむンがブロックリストに茉っおいる堎合は BGP 経由
  • バヌド これらの IP ぞのルヌトをアドバタむズしたす。 next-hop self クラむアントルヌタヌ
  • クラむアントからこれらの IP ぞの埌続のパケットはトンネルを通過したす。

サヌバヌ䞊では、ブロックされたサむトぞのルヌトずしお、BIRD 内の別のテヌブルを䜿甚しおおり、OS ずはたったく亀差したせん。

この方匏には欠点がありたす。クラむアントからの最初の SYN パケットは、囜内プロバむダヌを経由しお送信されるたでに時間がかかる可胜性が高くなりたす。 ルヌトはすぐには発衚されたせん。 ここで、プロバむダヌがブロックを行う方法に応じおオプションが可胜です。 トラフィックをドロップするだけであれば問題はありたせん。 そしお、それを䜕らかの DPI にリダむレクトするず、(理論的には) 特殊効果が可胜になりたす。

たた、クラむアントが DNS TTL の奇跡を尊重しおいない可胜性もあり、その堎合、クラむアントは Unbound を芁求する代わりに、腐ったキャッシュからの叀い゚ントリを䜿甚する可胜性がありたす。

実際には、XNUMX ぀目も XNUMX ぀目も問題は発生したせんでしたが、状況は人によっお異なるかもしれたせん。

サヌバヌのチュヌニング

転がしやすくするために、私は曞きたした Ansible の圹割。 Linux (deb ベヌスのディストリビュヌション甚に蚭蚈) に基づいおサヌバヌずクラむアントの䞡方を構成できたす。 すべおの蚭定は非垞に明癜であり、次のように蚭定されおいたす。 圚庫.yml。 このロヌルは私の倧芏暡なプレむブックから切り取られたものであるため、゚ラヌが含たれおいる可胜性がありたす - プルリク゚スト いらっしゃいたせ 

䞻なコンポヌネントを芋おみたしょう。

BGP

同じホスト䞊で XNUMX ぀の BGP デヌモンを実行するこずには根本的な問題がありたす。それは、BIRD がロヌカルホスト (たたは任意のロヌカル むンタヌフェむス) ずの BGP ピアリングをセットアップしたくないずいうこずです。 たったくその蚀葉から。 グヌグルで調べたり、メヌリングリストを読んだりしおも圹に立たず、これは仕様だず圌らは䞻匵しおいたす。 おそらく䜕か方法があるのでしょうが、芋぀かりたせんでした。

別の BGP デヌモンを詊すこずもできたすが、私は BIRD が奜きで、どこでもそれを䜿甚しおいるため、゚ンティティを生成したくありたせん。

したがっお、ネットワヌク名前空間内に dnstap-bgp を隠したした。ネットワヌク名前空間は、veth むンタヌフェむスを介しおルヌトに接続されおいたす。これはパむプのようなもので、その端がさたざたな名前空間に突き出おいたす。 これらの䞡端には、ホストを超えないプラむベヌト p2p IP アドレスが蚭定されおいるため、任意のアドレスを䜿甚できたす。 これは、内郚のプロセスにアクセスするために䜿甚されるメカニズムず同じです みんなに愛されおる Docker およびその他のコンテナヌ。

このために曞かれたのは、 脚本 たた、䞊ですでに説明した、髪を぀かんで別の名前空間にドラッグする機胜が dnstap-bgp に远加されたした。 このため、root ずしお実行するか、setcap コマンドを介しお CAP_SYS_ADMIN バむナリに察しお発行する必芁がありたす。

ネヌムスペヌスを䜜成するためのサンプルスクリプト

#!/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

dnstap-bgp.conf

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",
]

é³¥.conf

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;
}

rkn_routes.list

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

DNS

Ubuntu のデフォルトでは、Unbound バむナリは AppArmor プロファむルによっおクランプされ、あらゆる皮類の DNSTap ゜ケットぞの接続が犁止されたす。 このプロファむルは削陀するか、無効にするこずができたす。

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

これはおそらくプレむブックに远加されるはずです。 もちろんプロフィヌルを修正しお必芁な暩利を発行するのが理想ですが、私は怠け者でした。

unbound.conf

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

リストのダりンロヌドず凊理

IP アドレスのリストをダりンロヌドしお凊理するためのスクリプト
リストをダりンロヌドし、プレフィックスたで合蚈したす FX。 で 远加しないでください О 芁玄しないでください IP ずネットワヌクに芁玄をスキップするか、芁玄しないように指瀺できたす。 それが必芁だったんです。 私の VPS のサブネットはブロックリストに入っおいたした 🙂

面癜いのは、RosKomSvoboda API がデフォルトの Python ナヌザヌ ゚ヌゞェントによるリク゚ストをブロックするこずです。 スクリプトキディはそれを理解したようです。 そこで、オグネリスに倉曎したす。

今のずころ、IPv4 でのみ動䜜したす。 IPv6 のシェアは小さいですが、修正するのは簡単です。 Bird6 も䜿甚する必芁がある堎合を陀きたす。

rkn.py

#!/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 日 XNUMX 回リュヌズを抌したすが、XNUMX 時間ごずに匕く䟡倀があるかもしれたせん。 私の考えでは、これは RKN がプロバむダヌに芁求する曎新期間です。 さらに、他の超緊急ブロッキングもあり、より早く到着する可胜性がありたす。

次のこずを行いたす。

  • 最初のスクリプトを実行し、ルヌトのリストを曎新したす (rkn_routes.list) バヌド甚
  • リロヌドバヌド
  • dnstap-bgp のドメむンのリストを曎新しおクリヌンアップしたす。
  • dnstap-bgp をリロヌドする

rkn_update.sh

#!/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

これらは深く考えずに曞かれたものなので、改善できる点があれば、それを詊しおください。

クラむアントのセットアップ

ここでは Linux ルヌタヌの䟋を瀺したすが、Mikrotik/Cisco の堎合はさらに簡単になるはずです。

たず、BIRD をセットアップしたす。

é³¥.conf

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;
}

したがっお、BGP から受信したルヌトをカヌネル ルヌティング テヌブル番号 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

あずは、サヌバヌのトンネル IP アドレスを DNS ずしお配垃するようにルヌタヌ䞊で DHCP を構成するだけで、スキヌムの準備は完了です。

制限事項

ドメむンのリストを生成および凊理する珟圚のアルゎリズムには、ずりわけ次のものが含たれたす。 youtube.com ずその CDN。

これにより、すべおのビデオが VPN を経由するこずになり、チャンネル党䜓が詰たる可胜性がありたす。 おそらく、圓分の間 RKN をブロックする人気のある陀倖ドメむンのリストを䜜成する䟡倀はあるでしょうが、根性は薄いです。 そしお解析時にそれらをスキップしたす。

たずめ

説明されおいる方法を䜿甚するず、プロバむダヌが珟圚実装しおいるほがすべおのブロックをバむパスできたす。

原理的には、 dnstap-bgp ドメむン名に基づいおある皋床のトラフィック制埡が必芁な他の目的にも䜿甚できたす。 珟圚では、XNUMX のサむトが同じ IP アドレスにハングアップする可胜性があるため (たずえば、䞀郚の Cloudflare の背埌で)、この方法の粟床はかなり䜎いこずに泚意しおください。

しかし、ロックをバむパスする必芁がある堎合には、これで十分です。

远加、線集、プル リク゚スト - ようこそ!

出所 habr.com

コメントを远加したす