Konfigurera BGP för att kringgå blockering, eller "Hur jag slutade vara rädd och blev kär i RKN"

Tja, okej, om "älskad" är en överdrift. Snarare "kunde samexistera med."

Som ni alla vet har Roskomnadzor sedan den 16 april 2018 blockerat tillgången till resurser på Internet i extremt stora drag, och lagt till det "Enade registret över domännamn, sidindex för webbplatser på Internet och nätverksadresser som tillåter identifiering av webbplatser på Internet", som innehåller information vars distribution är förbjuden i Ryska federationen" (i texten - bara ett register) av /10 ibland. Som ett resultat lider medborgare i Ryska federationen och företag, efter att ha förlorat tillgången till de helt lagliga resurser de behöver.

Efter att jag sa i kommentarerna till en av artiklarna om Habré att jag var redo att hjälpa offer med att upprätta ett bypass-system, kom flera personer till mig och bad om sådan hjälp. När allt fungerade för dem rekommenderade en av dem att beskriva tekniken i en artikel. Efter lite funderande bestämde jag mig för att bryta tystnaden på sajten och för en gångs skull försöka skriva något mellanliggande mellan ett projekt och ett Facebook-inlägg, d.v.s. habrapost. Resultatet ligger framför dig.

Villkor

Eftersom det inte är särskilt lagligt att publicera sätt att kringgå blockering av åtkomst till information som är förbjuden på Ryska federationens territorium, kommer syftet med denna artikel att vara att prata om en metod som låter dig automatisera att få tillgång till resurser som är tillåtna på Ryska federationens territorium, men på grund av någon annans handlingar är inte direkt tillgängliga via din leverantör. Och tillgång till andra resurser som erhållits som ett resultat av åtgärder från artikeln är en olycklig bieffekt och är inte på något sätt syftet med artikeln.

Dessutom, eftersom jag i första hand är nätverksarkitekt till yrket, yrke och livsväg, är programmering och Linux inte mina starka sidor. Därför kan såklart skript skrivas bättre, säkerhetsfrågor i VPS kan utarbetas djupare osv. Dina förslag kommer att accepteras med tacksamhet, om de är tillräckligt detaljerade - jag lägger gärna till dem i artikelns text.

TL; DR

Vi automatiserar åtkomst till resurser genom din befintliga tunnel med hjälp av en kopia av registret och BGP-protokollet. Målet är att ta bort all trafik adresserad till blockerade resurser in i tunneln. Minimala förklaringar, mestadels steg-för-steg-instruktioner.

Vad behöver du för detta?

Tyvärr är det här inlägget inte för alla. För att använda denna teknik måste du sätta ihop flera element:

  1. Du måste ha en linux-server någonstans utanför blockeringsfältet. Eller åtminstone önskan att ha en sådan server - som tur är kostar den nu från $9/år, och möjligen mindre. Metoden är också lämplig om du har en separat VPN-tunnel, då kan servern placeras inne i blockeringsfältet.
  2. Din router borde vara smart nog att kunna
    • valfri VPN-klient du gillar (jag föredrar OpenVPN, men det kan vara PPTP, L2TP, GRE+IPSec eller något annat alternativ som skapar ett tunnelgränssnitt);
    • BGPv4-protokoll. Vilket betyder att det för SOHO kan vara Mikrotik eller vilken router som helst med OpenWRT/LEDE/liknande anpassad firmware som låter dig installera Quagga eller Bird. Det är inte heller förbjudet att använda en PC-router. Om det gäller ett företag, leta efter BGP-stöd i dokumentationen för din gränsrouter.
  3. Du bör ha en förståelse för Linux-användning och nätverksteknik, inklusive BGP-protokollet. Eller åtminstone vill få en sådan idé. Eftersom jag inte är redo att omfamna ofantligheten denna gång, måste du studera några aspekter som är obegripliga för dig på egen hand. Men jag kommer naturligtvis att svara på specifika frågor i kommentarerna och det är osannolikt att jag är den enda som svarar, så tveka inte att fråga.

Vad används i exemplet

  • En kopia av registret - från https://github.com/zapret-info/z-i 
  • VPS - Ubuntu 16.04
  • Routningstjänst - fågel 1.6.3   
  • Router - Mikrotik hAP ac
  • Arbetsmappar - eftersom vi arbetar som root kommer det mesta av allt att finnas i rotens hemmapp. Respektive:
    • /root/blacklist - arbetsmapp med kompileringsskriptet
    • /root/zi - kopia av registret från github
    • /etc/bird - standardmapp för fågeltjänstinställningar
  • Den externa IP-adressen för VPS med routingservern och tunnelavslutningspunkten är 194.165.22.146, ASN 64998; extern IP-adress för routern - 81.177.103.94, ASN 64999
  • IP-adresserna inuti tunneln är 172.30.1.1 respektive 172.30.1.2.

Konfigurera BGP för att kringgå blockering, eller "Hur jag slutade vara rädd och blev kär i RKN"

Naturligtvis kan du använda alla andra routrar, operativsystem och mjukvaruprodukter, anpassa lösningen till deras logik.

Kortfattat - lösningens logik

  1. Förberedande åtgärder
    1. Skaffa en VPS
    2. Höjning av en tunnel från routern till VPS
  2. Vi tar emot och uppdaterar regelbundet en kopia av registret
  3. Installera och konfigurera routingtjänsten
  4. Vi skapar en lista över statiska rutter för routingtjänsten baserat på registret
  5. Vi ansluter routern till tjänsten och konfigurerar att skicka all trafik genom tunneln.

Den faktiska lösningen

Förberedande åtgärder

Det finns många tjänster på Internet som tillhandahåller VPS till extremt rimliga priser. Hittills har jag hittat och använder alternativet för $9/år, men även om du inte bryr dig för mycket, finns det många alternativ för 1E/månad på varje hörn. Frågan om att välja en VPS ligger långt utanför ramen för denna artikel, så om någon inte förstår något om detta, fråga i kommentarerna.

Om du använder en VPS inte bara för routingtjänsten, utan också för att avsluta en tunnel på den, måste du höja den här tunneln och, nästan säkert, konfigurera NAT för den. Det finns ett stort antal instruktioner om dessa åtgärder på Internet, jag kommer inte att upprepa dem här. Huvudkravet för en sådan tunnel är att den måste skapa ett separat gränssnitt på din router som stödjer tunneln mot VPS. De flesta använda VPN-tekniker uppfyller detta krav – till exempel är OpenVPN i tun-läge perfekt.

Få en kopia av registret

Som Jabrail sa, "Den som hindrar oss kommer att hjälpa oss." Eftersom RKN skapar ett register över förbjudna resurser skulle det vara synd att inte använda detta register för att lösa vårt problem. Vi kommer att få en kopia av registret från github.

Vi går till din Linux-server, faller in i rotkontexten (sudo su —) och installera git om det inte redan är installerat.

apt install git

Gå till din hemkatalog och dra ut en kopia av registret.

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

Vi sätter upp en cron-uppdatering (jag gör det en gång var 20:e minut, men du kan välja vilket intervall som helst som intresserar dig). För att göra detta lanserar vi crontab -e och lägg till följande rad:

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

Vi ansluter en krok som skapar filer för routingtjänsten efter uppdatering av registret. För att göra detta, skapa en fil /root/zi/.git/hooks/post-merge med följande innehåll:

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

och glöm inte att göra det körbart

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

Vi kommer att skapa makebgp-skriptet som kroken hänvisar till lite senare.

Installera och konfigurera en routingtjänst

Installera fågel. Tyvärr är versionen av fågel som för närvarande publiceras i Ubuntu-förråden jämförbar i färskhet med Archeopteryx-avföring, så vi måste först lägga till den officiella PPA för mjukvaruutvecklarna till systemet.

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

Efter detta inaktiverar vi omedelbart bird för IPv6 - vi kommer inte att behöva det i den här installationen.

systemctl stop bird6
systemctl disable bird6

Nedan finns en minimalistisk konfigurationsfil för fågeltjänst (/etc/bird/bird.conf), vilket är tillräckligt för oss (och jag påminner dig än en gång om att ingen förbjuder att utveckla och ställa in idén för att passa dina egna behov)

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

router-id - routeridentifierare, som visuellt ser ut som en IPv4-adress, men inte är en. I vårt fall kan det vara vilket 32-bitars nummer som helst i IPv4-adressformatet, men det är bra att ange exakt IPv4-adressen för din enhet (i det här fallet VPS).

Protocol direct definierar vilka gränssnitt som kommer att fungera med routingprocessen. Exemplet ger ett par exempelnamn, du kan lägga till andra. Du kan helt enkelt ta bort raden, i det här fallet kommer servern att lyssna på alla tillgängliga gränssnitt med en IPv4-adress.

Protocol static är vår magi som laddar listor med prefix och IP-adresser (som faktiskt är /32 prefix, naturligtvis) från filer för efterföljande tillkännagivande. Var dessa listor kommer ifrån kommer att diskuteras nedan. Observera att laddning av IP-adresser kommenteras bort som standard, anledningen till detta är den stora uppladdningsvolymen. Som jämförelse, i skrivande stund finns det 78 rader i listan med prefix och 85898 85 i listan över IP-adresser. Jag rekommenderar starkt att du startar och felsöker endast på listan med prefix, och huruvida IP-laddning ska aktiveras eller inte. framtiden är upp till dig att bestämma efter att ha experimenterat med din router. Inte var och en av dem kan lätt smälta XNUMX tusen poster i routingtabellen.

protokoll bgp ställer faktiskt in bgp-peering med din router. IP-adressen är adressen till routerns externa gränssnitt (eller adressen till tunnelgränssnittet på routersidan), 64998 och 64999 är antalet autonoma system. I det här fallet kan de tilldelas i form av alla 16-bitars nummer, men det är god praxis att använda AS-nummer från det privata intervallet som definieras av RFC6996 - 64512-65534 inklusive (det finns ett format för 32-bitars ASN, men i vårt fall är detta definitivt överdrivet). Den beskrivna konfigurationen använder eBGP-peering, där numren på de autonoma systemen för routingtjänsten och routern måste vara olika.

Som du kan se behöver tjänsten känna till IP-adressen för routern, så om du har en dynamisk eller icke-routbar privat (RFC1918) eller delad (RFC6598) adress, har du inte möjlighet att öka peering på den externa gränssnittet, men tjänsten kommer fortfarande att fungera inne i tunneln.

Det är också ganska tydligt att från en tjänst kan du tillhandahålla rutter till flera olika routrar - duplicera bara inställningarna för dem genom att kopiera protokollet bgp-avsnittet och ändra grannens IP-adress. Det är därför som exemplet visar inställningar för peering utanför tunneln, som de mest universella. Det är lätt att ta bort dem i tunneln genom att ändra IP-adresserna i inställningarna i enlighet därmed.

Bearbetar registret för routingtjänsten

Nu behöver vi i själva verket skapa listor med prefix och IP-adresser, som nämndes i protokollet statiskt i föregående skede. För att göra detta tar vi registerfilen och skapar de filer vi behöver från den med hjälp av följande skript, placerat i /root/blacklist/makebgp

#!/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]{1,3}[.]){3}[0-9]{1,3}" | sed 's_.*_route &/32 reject;_' > /etc/bird/iplist.txt
/etc/init.d/bird reload
logger 'bgp list compiled'

Glöm inte att göra det körbart

chmod +x /root/blacklist/makebgp

Nu kan du köra det manuellt och observera hur filerna ser ut i /etc/bird.

Troligtvis fungerar inte bird för dig just nu, eftersom du i föregående skede bad den att leta efter filer som inte fanns ännu. Därför lanserar vi den och kontrollerar att den har startat:

systemctl start bird
birdc show route

Utdata från det andra kommandot bör visa cirka 80 poster (detta är för nu, men när du ställer in det kommer allt att bero på RKN:s nitiskhet för att blockera nätverk) ungefär så här:

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

Team

birdc show protocol

kommer att visa status för protokoll inom tjänsten. Tills du har konfigurerat routern (se nästa punkt), kommer OurRouter-protokollet att vara i starttillståndet (Anslut eller aktiv fas), och efter en lyckad anslutning går det till upptillståndet (etablerad fas). Till exempel, på mitt system ser resultatet av detta kommando ut så här:

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

Ansluta en router

Alla är nog trötta på att läsa den här fotduken, men var rädd – slutet är nära. Dessutom kommer jag inte i det här avsnittet att kunna ge steg-för-steg-instruktioner - det kommer att vara olika för varje tillverkare.

Jag kan dock visa dig ett par exempel. Huvudlogiken är att höja BGP-peering och tilldela nexthop till alla mottagna prefix, pekar på vår tunnel (om vi behöver skicka trafik genom ett p2p-gränssnitt) eller nexthop IP-adressen om trafiken kommer att gå till ethernet).

Till exempel på Mikrotik i RouterOS löses detta enligt följande

/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 multihop=yes name=VPS remote-address=194.165.22.146 remote-as=64998 ttl=default
/routing filter add action=accept chain=dynamic-in protocol=bgp comment="Set nexthop" set-in-nexthop=172.30.1.1

och i Cisco IOS - så här

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

Om samma tunnel används både för BGP-peering och för att överföra användbar trafik, är det inte nödvändigt att ställa in nexthop, den kommer att ställas in korrekt med protokollet. Men om du ställer in det manuellt kommer det inte att göra det värre heller.

På andra plattformar måste du ta reda på konfigurationen själv, men om du har några svårigheter, skriv i kommentarerna, jag ska försöka hjälpa.

Efter att din BGP-session har startat, rutter till stora nätverk har anlänt och installerats i tabellen, trafik har strömmat till adresserna från dem och lyckan är nära, kan du återvända till fågeltjänsten och försöka avkommentera posten där som kopplar samman lista över IP-adresser, kör efter det

systemctl reload bird

och se hur din router överförde dessa 85 tusen rutter. Var beredd att dra ur kontakten och fundera på vad du ska göra med den :)

Totalt

Rent teoretiskt, efter att ha slutfört stegen som beskrivs ovan, har du nu en tjänst som automatiskt omdirigerar trafik till IP-adresser som är förbjudna i Ryska federationen förbi filtreringssystemet.

Det kan naturligtvis förbättras. Det är till exempel ganska enkelt att sammanfatta en lista över IP-adresser med hjälp av perl- eller pythonlösningar. Ett enkelt Perl-skript som gör detta med Net::CIDR::Lite förvandlar 85 tusen prefix till 60 (inte tusen), men täcker naturligtvis ett mycket större antal adresser än vad som är blockerat.

Eftersom tjänsten fungerar på den tredje nivån av ISO/OSI-modellen, kommer den inte att rädda dig från att blockera en webbplats/sida om den löser sig till fel adress som registrerats i registret. Men tillsammans med registret kommer filen nxdomain.txt från github, som med några få scriptdrag lätt förvandlas till en adresskälla för till exempel SwitchyOmega-pluginen i Chrome.

Det är också nödvändigt att nämna att lösningen kräver ytterligare förfining om du inte bara är en Internetanvändare, utan även publicerar vissa resurser på egen hand (till exempel en webbplats eller e-postserver körs på denna anslutning). Med hjälp av routerns medel är det nödvändigt att strikt binda utgående trafik från denna tjänst till din allmänna adress, annars kommer du att förlora anslutningen med de resurser som täcks av listan över prefix som mottas av routern.

Om du har några frågor, fråga, jag är redo att svara.

UPD. Tack navion и TerAnYu för parametrar för git som tillåter att minska nedladdningsvolymerna.

UPD2. Kolleger, det ser ut som att jag gjorde ett misstag genom att inte lägga till instruktioner för att sätta upp en tunnel mellan VPS:n och routern i artikeln. Det väcker många frågor.
För säkerhets skull ska jag återigen notera att innan du startar den här guiden har du redan konfigurerat en VPN-tunnel i den riktning du behöver och kontrollerat dess funktionalitet (till exempel genom att vända trafik dit som standard eller statiskt). Om du inte har slutfört den här fasen ännu, är det inte mycket meningsfullt att följa stegen i artikeln. Jag har ingen egen text om detta än, men om du googlar "set upp en OpenVPN-server" tillsammans med namnet på operativsystemet som är installerat på VPS, och "ställer in en OpenVPN-klient" med namnet på din router , kommer du med största sannolikhet att hitta ett antal artiklar om detta ämne, inklusive om Habré.

UPD3. Ouppoffrad Jag skrev en kod som gör dump.csv till en resulterande fil för bird med valfri sammanfattning av IP-adresser. Därför kan avsnittet "Bearbeta registret för routingtjänsten" ersättas genom att anropa dess program. https://habr.com/post/354282/#comment_10782712

UPD4. Lite arbete med fel (jag lade inte till dem i texten):
1) istället systemctl ladda om fågeln det är vettigt att använda kommandot birdc konfigurera.
2) i Mikrotik-routern, istället för att ändra nexthop till IP:n på den andra sidan av tunneln /routing filter add action=acceptera kedja=dynamic-in protocol=bgp comment=»Ställ in nexthop» set-in-nexthop=172.30.1.1 det är vettigt att specificera rutten direkt till tunnelgränssnittet, utan en adress /routing filter add action=acceptera chain=dynamic-in protocol=bgp comment=»Ställ in nexthop» set-in-nexthop-direct=<gränssnittsnamn>

UPD5. En ny tjänst har dykt upp https://antifilter.download, varifrån du kan hämta färdiga listor med IP-adresser. Uppdateras varje halvtimme. På klientsidan återstår bara att rama in posterna med motsvarande "rutt... avvisa".
Och vid det här laget räcker det förmodligen med att trasa din mormor och uppdatera artikeln.

UPD6. En reviderad version av artikeln för dig som inte vill ta reda på det, men vill komma igång - här.

Källa: will.com

Lägg en kommentar