Kodėl jūsų iptables taisyklė niekada nemato VPN srauto per tiltą
Per tiltą einantys kadrai gali apeiti IP grandinę, kurią stebite. Palyginkite vietinę bridge šeimą su senuoju br_netfilter prieš pridėdami dar vieną taisyklę.
Dvi virtualios mašinos tame pačiame hoste pasiekia LAN per tiltą, o taisyklė, įdėta į ip forward grandinę, rodo skaitiklį, kuris niekada nejuda. Kadrai yra tikri, srautas eina, ir taisyklė tiesiog nėra jo kelyje. Dviejų būdų, kuriais Linux parodo srautą per tiltą, palyginimas paaiškina šią tylą, ir jis taip pat paaiškina, kodėl vieno seno modulio įkėlimas yra prastesnis atsakymas, nei atrodo.
Du keliai per vieną hostą
Paketas gali palikti šį hostą dviem labai skirtingais būdais, ir skirtumas nulemia, kurie hookai jį matys. Jei paskirties vieta yra už fizinio prievado ir kadras perjungiamas tarp dviejų tilto prievadų, hostas persiunčia Ethernet kadrą; maršrutizavimo kodas neklausiamas, ir joks maršrutizuotas šuolis neįvyksta. Jei paskirties vieta yra pats hostas arba tinklas, pasiekiamas per tunelio sąsają, paketas maršrutizuojamas ir IP sluoksnio hookai tikrai galioja. Turėkite omenyje šią šaką, nes kiekvienas vėlesnis klausimas apie grandines ir šeimas kyla iš to, kurį iš dviejų kelių kadras pasirenka.
Šis skirtumas yra visa istorija už taisyklės, kuri nieko neskaičiuoja. Kadras per tiltą iš veth9a1 į enp3s0 kerta tiltą, o ne IP steką, todėl ip forward grandinė nemato nieko, ką būtų galima sutapatinti. Sąsajų pavadinimai senesniame pavyzdyje nenulemia, kuris kelias jūsų, todėl pirmas žingsnis yra žiūrėti į topologiją, o ne į taisyklių rinkinį.
Tunelis prideda trečią atvejį, kurį verta pavadinti. TUN įrenginys perduoda IP paketus hostui, todėl jie maršrutizuojami ir tikrai praeina per IP grandines, o prie tilto prijungtas TAP įrenginys perduoda kadrus ir elgiasi kaip tilto atvejis. Nulemia įrenginio tipas, o ne produkto pavadinimas.
Palyginkite dvi šeimas, kurios gali matyti kadrą per tiltą
Linux palaiko vietinį tilto filtravimą per nftables bridge šeimą, ir jam nereikia jokio seno modulio kadrams skrydžio metu tikrinti ir išmesti. Pati branduolio tilto dokumentacija tiesiogiai pateikia šią rekomendaciją, ką verta žinoti prieš paieškos rezultatui pasakant įkelti modulį.
| Observation point | What it sees | What it costs |
|---|---|---|
nftables bridge family chains | Ethernet frames forwarded between bridge ports, in both directions | Rules must be written in bridge syntax with link-layer matches |
Legacy br_netfilter plus an ip chain | Bridged IPv4 and IPv6 packets, re-exposed through IP-layer hooks | Existing host rules may begin matching traffic they never saw before |
inet chain for routed traffic | Packets the host routes, including traffic arriving from a TUN device | No visibility into purely switched frames |
Naudojant nft komandą vietoj iptables, taisyklė pati savaime neatsiduria teisingoje šeimoje. Bridge šeimoje deklaruota grandinė mato kadrus; ip, ip6 arba inet deklaruota grandinė jų nemato, nesvarbu, kuris dvejetainis failas ją sukūrė. Šeima yra grandinės savybė, o ne įrankio, kuris ją įvedė.
Senas kelias veikia kitaip, ir būtent todėl verta lyginti, o ne rinktis pusę iš įpročio. Įkėlus br_netfilter ir įjungus bridge-nf-call nustatymus, srautas per tiltą IPv4 ir IPv6 vėl parodomas per IP sluoksnio hookus, todėl įprasta iptables taisyklė pagaliau gali jį sutapatinti. Kadrai nesikeičia; keičiasi hookų, per kuriuos jie praeina, rinkinys, o tai reiškia, kad kiekviena esama hosto taisyklė dabar turi naują auditoriją.
Perskaitykite veiksmingą kelią prieš pridėdami taisyklę
Trys komandos nustato, kur esate: prie ko prijungtas tiltas, ar senas modulis aktyvus ir kokios grandinės jau yra bridge šeimoje. Paleiskite jas prieš ką nors rašydami, nes atsakymas nulemia, kurią iš dviejų konstrukcijų praplečiate. Šio žingsnio praleidimas yra būdas, kuriuo teisinga taisyklė atsiduria grandinėje, per kurią niekas neina.
bridge link show
lsmod | grep br_netfilter
nft list ruleset | grep -A4 "chain forward"
Išvestis švariai atskiria atvejus. Prievadai, išvardyti po tiltu, pasako, kurios sąsajos perjungiamos; tuščias lsmod rezultatas reiškia jokio IP sluoksnio matomumo kadrams per tiltą; esama bridge šeimos forward grandinė reiškia, kad politika jau turi šeimininką ir jūsų taisyklė priklauso ten, o ne į naują savo grandinę.
Tada pridėkite vieną lengvai perskaitomą taisyklę su skaitikliu ir nekeisdami sprendimo, ir per tiltą praleiskite vieną reprezentatyvų srautą. Judantis skaitiklis įrodo, kad kadras pasiekė taisyklę. Tai viskas, ką jis įrodo, todėl tęskite ir su atmestu keliu, nes politika, priimanti viską, taip pat sukuria judantį skaitiklį.
nft add rule bridge filter forward iifname "veth9a1" oifname "enp3s0" counter acceptKur senas modulis keičia elgesį
Seno kelio įjungimas veikiančiame tilte nėra neutralus matomumo pridėjimo veiksmas. Taisyklės, anksčiau nepasiekiamos srautui per tiltą, tampa pasiekiamos, įskaitant hosto taisykles, parašytas kitai sąsajai, o numatytoji drop politika ip forward grandinėje gali staiga imti taikytis kadrams, kurie anksčiau praeidavo nepaliesti. Hoste, valdomame per tą tiltą, rezultatas yra užraktas be konsolės. Tai ne hipotetinis gedimo režimas; tai įprasta pasekmė išplečiant hookų rinkinį mašinoje, kurią pasiekiate per ką tik išplėstą kelią.
Saugesnė seka yra nuspręsti, kuri šeima valdo politiką, ten rašyti taisykles ir išlaikyti nepriklausomą atkūrimo kelią prieš keičiant bet kurį sysctl. Jei dvi šeimos turi taisyklių, dokumentuokite, kuri yra pagrindinė; dvi persidengiančios politikos yra būdas, kuriuo paketas priimamas vienoje vietoje ir atmetamas kitoje, neturint nė vieno failo perskaityti.
Izoliacija pati savaime vis dar reikalauja visos konstrukcijos. Leidimas vienam šaltiniui pasiekti vieną paskirties vietą įrodo tik tai, kad vienas srautas veikia, o reikalavimas paprastai yra tas, kad VM negalėtų pasiekti savo kaimynų ar hosto. Skaitikliai atmetimo taisyklėse svarbesni už skaitiklį priėmimo taisyklėje, nes priėmimo skaitiklis yra tas, kurį jau tikėjotės judant.
Galiausiai laikykite hosto įvesties atvejį atskirai. Srautas, adresuotas į paties tilto IP, patenka į input, o ne į forward, ir taisyklė forward grandinėje jo niekada nematys, kad ir kurią šeimą pasirinktumėte. Trys atvejai, dvi šeimos, viena pamoka: kelias nulemia hooką, o hookas nulemia, ar jūsų taisyklė apskritai egzistuoja.