Tema është goxha e rrahur, e di. Për shembull, ka një të madhe artikull, por aty merret parasysh vetëm pjesa IP e listës së bllokimit. Ne gjithashtu do të shtojmë domene.
Për shkak të faktit se gjykatat dhe RKN bllokojnë gjithçka djathtas dhe majtas, dhe ofruesit po përpiqen shumë që të mos bien nën gjobat e lëshuara nga Revizorro, humbjet e lidhura nga bllokimi janë mjaft të mëdha. Dhe midis faqeve të bllokuara "me ligj" ka shumë të dobishme (përshëndetje, rutracker)
Unë jetoj jashtë juridiksionit të RKN-së, por prindërit, të afërmit dhe miqtë e mi kanë mbetur në shtëpi. Kështu u vendos që të krijohej një mënyrë e thjeshtë për njerëzit larg IT-së për të anashkaluar bllokimin, mundësisht pa pjesëmarrjen e tyre fare.
Në këtë shënim, unë nuk do t'i përshkruaj gjërat bazë të rrjetit me hapa, por do të përshkruaj parimet e përgjithshme se si mund të zbatohet kjo skemë. Pra, njohuria se si funksionon rrjeti në përgjithësi dhe në Linux në veçanti është një domosdoshmëri.
Llojet e bravave
Së pari, le të rifreskojmë kujtesën tonë për atë që po bllokohet.
Ekzistojnë disa lloje bravash në XML-në e shkarkuar nga RKN:
IP
Домен
URL
Për thjeshtësi, ne do t'i reduktojmë ato në dy: IP dhe domen, dhe thjesht do ta heqim domenin nga bllokimi me URL (më saktë, ata tashmë e kanë bërë këtë për ne).
njerëz të mirë nga Roskomsvoboda realizoi një të mrekullueshme API, përmes së cilës ne mund të marrim atë që na nevojitet:
Për ta bërë këtë, na duhen disa VPS të vogla të huaja, mundësisht me trafik të pakufizuar - ka shumë prej tyre për 3-5 dollarë. Ju duhet ta merrni atë në afërsi jashtë vendit, në mënyrë që ping-u të mos jetë shumë i madh, por përsëri, merrni parasysh që interneti dhe gjeografia nuk përkojnë gjithmonë. Dhe meqenëse nuk ka SLA për 5 dollarë, është më mirë të marrësh 2+ pjesë nga ofrues të ndryshëm për tolerancën e gabimeve.
Më pas, duhet të konfigurojmë një tunel të koduar nga ruteri i klientit në VPS. Unë përdor Wireguard si konfigurimin më të shpejtë dhe më të lehtë. Unë gjithashtu kam ruter klientësh të bazuar në Linux (APU2 ose diçka në OpenWRT). Në rastin e disa Mikrotik / Cisco, mund të përdorni protokollet e disponueshme në to si OpenVPN dhe GRE-over-IPSEC.
Identifikimi dhe ridrejtimi i trafikut me interes
Sigurisht, mund të fikni të gjithë trafikun e Internetit përmes vendeve të huaja. Por, ka shumë të ngjarë, shpejtësia e punës me përmbajtje lokale do të vuajë shumë nga kjo. Plus, kërkesat e gjerësisë së brezit në VPS do të jenë shumë më të larta.
Prandaj, do të duhet të ndajmë disi trafikun në faqet e bllokuara dhe ta drejtojmë në mënyrë selektive në tunel. Edhe nëse një pjesë e trafikut "shtesë" arrin atje, është akoma shumë më mirë sesa të ngasësh gjithçka përmes tunelit.
Për të menaxhuar trafikun, ne do të përdorim protokollin BGP dhe do të njoftojmë rrugët drejt rrjeteve të nevojshme nga VPS-ja jonë te klientët. Le ta marrim BIRD si një nga demonët më funksionalë dhe më të përshtatshëm të BGP.
IP
Me bllokimin nga IP, gjithçka është e qartë: ne thjesht shpallim të gjitha IP-të e bllokuara me VPS. Problemi është se ka rreth 600 mijë nënrrjeta në listën që API kthen, dhe shumica dërrmuese e tyre janë /32 host. Ky numër rrugësh mund të ngatërrojë ruterat e dobët të klientëve.
Prandaj, gjatë përpunimit të listës, u vendos që të përmblidhet deri në rrjet / 24 nëse ka 2 ose më shumë host. Kështu, numri i rrugëve u reduktua në ~ 100 mijë. Skenari për këtë do të vijojë.
domains
Është më e ndërlikuar dhe ka disa mënyra. Për shembull, mund të instaloni një Squid transparent në çdo ruter klienti dhe të bëni përgjim HTTP atje dhe të shikoni në shtrëngimin e duarve TLS në mënyrë që të merrni URL-në e kërkuar në rastin e parë dhe domenin nga SNI në të dytin.
Por për shkak të të gjitha llojeve të TLS1.3 + eSNI të reja, analiza HTTPS po bëhet gjithnjë e më pak reale çdo ditë. Po, dhe infrastruktura në anën e klientit po bëhet më e ndërlikuar - do të duhet të përdorni të paktën OpenWRT.
Prandaj, vendosa të marr rrugën e përgjimit të përgjigjeve ndaj kërkesave DNS. Edhe këtu, çdo DNS-mbi-TLS / HTTPS fillon të rri pezull mbi kokën tuaj, por ne mund (për momentin) ta kontrollojmë këtë pjesë te klienti - ose ta çaktivizojmë ose të përdorim serverin tuaj për DoT / DoH.
Si të përgjoni DNS?
Këtu, gjithashtu, mund të ketë disa qasje.
Përgjimi i trafikut DNS nëpërmjet PCAP ose NFLOG
Të dyja këto metoda të përgjimit zbatohen në shërbim sidmat. Por nuk është mbështetur për një kohë të gjatë dhe funksionaliteti është shumë primitiv, kështu që ju ende duhet të shkruani një parzmore për të.
Analiza e regjistrave të serverit DNS
Fatkeqësisht, rekursorët e njohur për mua nuk janë në gjendje të regjistrojnë përgjigjet, por vetëm kërkesat. Në parim, kjo është logjike, pasi, ndryshe nga kërkesat, përgjigjet kanë një strukturë komplekse dhe është e vështirë t'i shkruash ato në formë teksti.
DNSTAp
Për fat të mirë, shumë prej tyre tashmë mbështesin DNSTap për këtë qëllim.
Çfarë është DNSTap?
Është një protokoll klient-server i bazuar në Protocol Buffers dhe Frame Streams për transferimin nga një server DNS në një koleksionues të pyetjeve dhe përgjigjeve të strukturuara DNS. Në thelb, serveri DNS transmeton metadatat e pyetjeve dhe përgjigjeve (lloji i mesazhit, IP-ja e klientit/serverit, etj.) plus mesazhet e plota DNS në formën (binare) në të cilën punon me ta përmes rrjetit.
Është e rëndësishme të kuptohet se në paradigmën DNSTap, serveri DNS vepron si klient dhe mbledhësi vepron si server. Kjo do të thotë, serveri DNS lidhet me kolektorin, dhe jo anasjelltas.
Sot DNSTap mbështetet në të gjithë serverët e njohur DNS. Por, për shembull, BIND në shumë shpërndarje (si Ubuntu LTS) shpesh ndërtohet për ndonjë arsye pa mbështetjen e tij. Pra, le të mos shqetësohemi me rimontimin, por të marrim një rekursor më të lehtë dhe më të shpejtë - Pa lidhje.
Si të kapni DNSTap?
Ka disanumër Shërbimet CLI për të punuar me një rrymë ngjarjesh DNSTap, por ato nuk janë të përshtatshme për zgjidhjen e problemit tonë. Prandaj, vendosa të shpik biçikletën time që do të bëjë gjithçka që është e nevojshme: dnstap-bgp
Algoritmi i punës:
Kur lëshohet, ngarkon një listë domenesh nga një skedar teksti, i kthen ato (habr.com -> com.habr), përjashton linjat e prishura, dublikatat dhe nëndomainët (d.m.th. nëse lista përmban habr.com dhe www.habr.com, vetëm i pari do të ngarkohet) dhe ndërton një pemë prefikse për një kërkim të shpejtë në këtë listë.
Duke vepruar si një server DNSTap, ai pret për një lidhje nga një server DNS. Në parim, ai mbështet të dy bazat UNIX dhe TCP, por serverët DNS që unë njoh mund të përdorin vetëm bazat UNIX
Paketat hyrëse DNSTap fillimisht deserializohen në një strukturë Protobuf dhe më pas vetë mesazhi binar DNS, i vendosur në një nga fushat Protobuf, analizohet në nivelin e regjistrimeve DNS RR
Kontrollohet nëse hosti i kërkuar (ose domeni i tij prind) është në listën e ngarkuar, nëse jo, përgjigja shpërfillet
Vetëm RR-të A/AAAA/CNAME zgjidhen nga përgjigja dhe adresat përkatëse IPv4/IPv6 janë nxjerrë prej tyre
Adresat IP ruhen me TTL të konfigurueshme dhe u reklamohen të gjithë kolegëve të konfiguruar BGP
Kur merrni një përgjigje që tregon një IP tashmë të ruajtur në memorie, TTL-ja e saj përditësohet
Pas skadimit të TTL, hyrja hiqet nga cache dhe nga njoftimet BGP
Funksionalitet shtesë:
Rileximi i listës së domeneve nga SIGHUP
Mbajtja e cache-së në sinkron me instancat e tjera dnstap-bgp nëpërmjet HTTP/JSON
Dublikojeni cache-në në disk (në bazën e të dhënave BoltDB) për të rivendosur përmbajtjen e tij pas një rifillimi
Mbështetje për kalimin në një hapësirë tjetër emri rrjeti (përse kjo është e nevojshme do të përshkruhet më poshtë)
Mbështetje IPv6
kufizimet:
Domenet IDN nuk mbështeten ende
Pak cilësime BGP
kam mbledhur RPM dhe DEB paketa për instalim të lehtë. Duhet të funksionojë në të gjitha OS-të relativisht të fundit me systemd. ata nuk kanë asnjë varësi.
skemë
Pra, le të fillojmë të montojmë të gjithë përbërësit së bashku. Si rezultat, ne duhet të marrim diçka si kjo topologji rrjeti:
Logjika e punës, mendoj, është e qartë nga diagrami:
Klienti ka serverin tonë të konfiguruar si DNS, dhe pyetjet DNS duhet të kalojnë gjithashtu mbi VPN. Kjo është e nevojshme në mënyrë që ofruesi të mos mund të përdorë përgjimin DNS për të bllokuar.
Kur hap faqen, klienti dërgon një pyetje DNS si "cilat janë IP-të e xxx.org"
i pavarur zgjidh xxx.org (ose e merr atë nga cache) dhe i dërgon një përgjigje klientit "xxx.org ka këtë dhe atë IP", duke e dublikuar atë paralelisht nëpërmjet DNSTap
dnstap-bgp shpall këto adresa në BIRD nëpërmjet BGP nëse domeni është në listën e bllokuar
BIRD reklamon një rrugë drejt këtyre IP-ve me next-hop self ruteri i klientit
Paketat pasuese nga klienti në këto IP kalojnë nëpër tunel
Në server, për rrugët drejt sajteve të bllokuara, unë përdor një tabelë të veçantë brenda BIRD dhe ajo nuk ndërpritet në asnjë mënyrë me OS.
Kjo skemë ka një pengesë: paketa e parë SYN nga klienti, ka shumë të ngjarë, do të ketë kohë të largohet përmes ofruesit vendas. itinerari nuk shpallet menjëherë. Dhe këtu opsionet janë të mundshme në varësi të mënyrës se si ofruesi e bën bllokimin. Nëse ai thjesht heq trafikun, atëherë nuk ka asnjë problem. Dhe nëse ai e ridrejton atë në disa DPI, atëherë (teorikisht) efektet speciale janë të mundshme.
Është gjithashtu e mundur që klientët të mos respektojnë mrekullitë DNS TTL, gjë që mund të bëjë që klienti të përdorë disa hyrje të ndenjura nga cache e tij të kalbur në vend që të kërkojë Unbound.
Në praktikë, as e para dhe as e dyta nuk më shkaktuan probleme, por kilometrazhi juaj mund të ndryshojë.
Akordimi i serverit
Për lehtësinë e rrotullimit, kam shkruar rol për Ansible. Mund të konfigurojë si serverët ashtu edhe klientët bazuar në Linux (i projektuar për shpërndarje të bazuara në deb). Të gjitha cilësimet janë mjaft të dukshme dhe janë vendosur inventar.yml. Ky rol është prerë nga libri im i madh i lojërave, kështu që mund të përmbajë gabime - tërheq kërkesa mire se erdhe 🙂
Le të kalojmë nëpër komponentët kryesorë.
BGP
Drejtimi i dy demonëve BGP në të njëjtin host ka një problem thelbësor: BIRD nuk dëshiron të konfigurojë BGP peering me localhost (ose ndonjë ndërfaqe lokale). Nga fjala fare. Googlimi dhe leximi i listave të postës nuk ndihmuan, ata pretendojnë se kjo është me dizajn. Ndoshta ka ndonjë mënyrë, por nuk e gjeta.
Mund të provoni një demon tjetër BGP, por mua më pëlqen BIRD dhe përdoret kudo nga unë, nuk dua të prodhoj entitete.
Prandaj, fsheha dnstap-bgp brenda hapësirës së emrave të rrjetit, e cila është e lidhur me rrënjën përmes ndërfaqes veth: është si një tub, skajet e të cilit dalin në hapësira të ndryshme emrash. Në secilën prej këtyre skajeve, ne varim adresa IP private p2p që nuk shkojnë përtej hostit, kështu që ato mund të jenë çdo gjë. Ky është i njëjti mekanizëm që përdoret për të hyrë në proceset brenda e dashur nga të gjithë Docker dhe kontejnerë të tjerë.
Për këtë ishte shkruar skenar dhe funksionaliteti i përshkruar tashmë më sipër për të tërhequr veten nga flokët në një hapësirë tjetër emri u shtua në dnstap-bgp. Për shkak të kësaj, ai duhet të ekzekutohet si rrënjë ose të lëshohet në binarin CAP_SYS_ADMIN nëpërmjet komandës setcap.
Shembull i skriptit për krijimin e hapësirës së emrave
#!/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
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_rrugët.lista
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
Si parazgjedhje, në Ubuntu, binarja Unbound mbërthehet nga profili AppArmor, i cili e ndalon atë të lidhet me të gjitha llojet e prizave DNSTap. Ju ose mund ta fshini këtë profil ose ta çaktivizoni atë:
Kjo ndoshta duhet të shtohet në librin e lojërave. Është ideale, sigurisht, të korrigjoj profilin dhe të lëshoj të drejtat e nevojshme, por unë isha shumë dembel.
i palidhur.konf
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
Shkarkimi dhe përpunimi i listave
Skript për shkarkimin dhe përpunimin e një liste adresash IP
Ai shkarkon listën, përmbledh në prefiksin pfx. Në mos_shto и mos_përmbledh ju mund t'u thoni IP-ve dhe rrjeteve të kalojnë ose të mos përmbledhin. Më duhej. nënrrjeti i VPS-së sime ishte në listën e bllokimit 🙂
Gjëja qesharake është se API RosKomSvoboda bllokon kërkesat me agjentin e parazgjedhur të përdoruesit Python. Duket se djali i skenarit e ka kuptuar. Prandaj, ne e ndryshojmë atë në Ognelis.
Deri më tani, funksionon vetëm me IPv4. pjesa e IPv6 është e vogël, por do të jetë e lehtë të rregullohet. Përveç nëse duhet të përdorni edhe 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)
Skript për përditësim
E drejtoj në kurorë një herë në ditë, ndoshta ia vlen ta tërheq çdo 4 orë. kjo, për mendimin tim, është periudha e rinovimit që RKN kërkon nga ofruesit. Plus, ata kanë disa bllokime të tjera super-urgjente, të cilat mund të arrijnë më shpejt.
Bën sa vijon:
Ekzekuton skriptin e parë dhe përditëson listën e rrugëve (rkn_routes.list) për BIRD
Ringarko BIRD
Përditëson dhe pastron listën e domeneve për dnstap-bgp
Ringarko 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
Ato janë shkruar pa u menduar shumë, kështu që nëse shihni diçka që mund të përmirësohet - shkoni për të.
Konfigurimi i klientit
Këtu do të jap shembuj për ruterat Linux, por në rastin e Mikrotik / Cisco duhet të jetë edhe më e lehtë.
Së pari, ne vendosëm BIRD:
zog.konf
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;
}
Kështu, ne do të sinkronizojmë rrugët e marra nga BGP me tabelën e kursimit të kernelit numër 222.
Pas kësaj, mjafton t'i kërkoni kernelit të shikojë këtë pllakë përpara se të shikoni atë të paracaktuar:
# 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
Gjithçka, mbetet të konfiguroni DHCP në ruter për të shpërndarë adresën IP të tunelit të serverit si DNS, dhe skema është gati.
Kufizimet
Me algoritmin aktual për gjenerimin dhe përpunimin e listës së domeneve, ai përfshin ndër të tjera, youtube.com dhe CDN-të e tij.
Dhe kjo çon në faktin se të gjitha videot do të kalojnë përmes VPN, i cili mund të bllokojë të gjithë kanalin. Ndoshta ia vlen të përpilohet një listë e domeneve-përjashtimeve të njohura që bllokojnë RKN për momentin, guximi është i hollë. Dhe kaloni ato kur analizoni.
Përfundim
Metoda e përshkruar ju lejon të anashkaloni pothuajse çdo bllokim që ofruesit aktualisht zbatojnë.
Në parim, dnstap-bgp mund të përdoret për çdo qëllim tjetër ku nevojitet një nivel i caktuar i kontrollit të trafikut bazuar në emrin e domenit. Vetëm mbani në mend se në kohën tonë, një mijë sajte mund të varen në të njëjtën adresë IP (prapa disa Cloudflare, për shembull), kështu që kjo metodë ka një saktësi mjaft të ulët.
Por për nevojat e anashkalimit të bravave, kjo është mjaft e mjaftueshme.
Shtesa, modifikime, kërkesa për tërheqje - mirëpritur!