Miért nem látja soha az iptables-szabályod a hídon átmenő VPN-forgalmat
A hídon átmenő keretek megkerülhetik a figyelt IP-láncot. Hasonlítsd össze a natív bridge családot a régi br_netfilterrel, mielőtt újabb szabályt adsz hozzá.
Két virtuális gép ugyanazon a hoszton egy hídon keresztül éri el a LAN-t, és az ip forward láncba tett szabály olyan számlálót mutat, amely soha nem mozdul. A keretek valódiak, a forgalom átmegy, és a szabály egyszerűen nincs az útvonalán. Annak összehasonlítása, hogy a Linux kétféleképpen teszi láthatóvá a hídon átmenő forgalmat, megmagyarázza ezt a csendet, és azt is megmagyarázza, miért rosszabb válasz egy régi modul betöltése, mint amilyennek látszik.
Két útvonal egy hoszton keresztül
Egy csomag két nagyon különböző módon hagyhatja el ezt a hosztot, és a különbség dönti el, mely hookok látják. Ha a cél egy fizikai porton túl van, és a keret két hídport között kapcsolódik, a hoszt Ethernet-keretet továbbít; a routing kódot nem kérdezik meg, és nem történik routolt ugrás. Ha a cél maga a hoszt, vagy egy alagút-interfészen keresztül elért hálózat, a csomag routolódik, és az IP-réteg hookjai valóban érvényesülnek. Tartsd szem előtt ezt az elágazást, mert minden későbbi kérdés a láncokról és családokról abból következik, hogy a keret melyik utat választja.
Ez a megkülönböztetés a teljes történet egy olyan szabály mögött, amely semmit nem számol. Egy hídon átmenő keret veth9a1-tól enp3s0-ig a hidat szeli át, nem az IP-vermet, ezért egy ip forward lánc nem lát semmit, amivel egyezhetne. Egy régebbi példa interfésznevei nem döntik el, melyik útvonalad van, ezért az első lépés a topológiára nézni, nem a szabálykészletre.
Az alagút egy harmadik esetet ad hozzá, amely nevet érdemel. Egy TUN-eszköz IP-csomagokat ad át a hosztnak, ezért azok routolódnak és valóban áthaladnak IP-láncokon, míg a hídhoz csatolt TAP-eszköz kereteket ad át, és a hidas esethez hasonlóan viselkedik. Az eszköz típusa dönt, nem a termék neve.
Hasonlítsd össze a két családot, amely lát egy hídon átmenő keretet
A Linux natív hídszűrést támogat az nftables bridge családján keresztül, és nincs szüksége semmilyen régi modulra a keretek repülés közbeni vizsgálatához és eldobásához. Maga a kernel híd-dokumentációja közvetlenül ezt javasolja, amit érdemes tudni, mielőtt egy keresési találat azt mondja, hogy tölts be egy modult.
| 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 |
Az nft parancs használata az iptables helyett önmagában nem teszi a szabályt a megfelelő családba. A bridge családban deklarált lánc látja a kereteket; az ip, ip6 vagy inet családban deklarált lánc nem látja őket, függetlenül attól, melyik bináris hozta létre. A család a lánc tulajdonsága, nem az eszközé, amely begépelte.
A régi útvonal másképp működik, és éppen ezért érdemes összehasonlítani ahelyett, hogy szokásból oldalt választanánk. A br_netfilter betöltése és a bridge-nf-call beállítások engedélyezése újra láthatóvá teszi a hídon átmenő IPv4- és IPv6-forgalmat az IP-réteg hookjain keresztül, így egy közönséges iptables-szabály végre egyezhet vele. A keretek nem változnak; az változik, hogy mely hookokon haladnak át, ami azt jelenti, hogy minden meglévő hosztszabálynak most új közönsége van.
Olvasd el a tényleges útvonalat, mielőtt szabályt adsz hozzá
Három parancs tisztázza, hol vagy: mihez csatlakozik a híd, aktív-e a régi modul, és milyen láncok léteznek már a bridge családban. Futtasd őket, mielőtt bármit írnál, mert a válasz dönti el, a két terv közül melyiket bővíted. Ennek a lépésnek a kihagyása az, ahogy egy helyes szabály olyan láncba kerül, amelyen semmi nem halad át.
bridge link show
lsmod | grep br_netfilter
nft list ruleset | grep -A4 "chain forward"
A kimenet tisztán szétválasztja az eseteket. A híd alatt felsorolt portok megmondják, mely interfészek kapcsolódnak; egy üres lsmod eredmény azt jelenti, hogy a hídon átmenő kereteknek nincs semmilyen láthatósága az IP-rétegen; egy meglévő bridge család forward lánc azt jelenti, hogy már van szabálytulajdonos, és a szabályod oda tartozik, nem egy saját új láncba.
Ezután adj hozzá egy könnyen visszaolvasható szabályt, számlálóval és az ítélet megváltoztatása nélkül, és küldj át egyetlen reprezentatív folyamot a hídon. A mozgó számláló bizonyítja, hogy a keret elérte a szabályt. Ez minden, amit bizonyít, ezért kövesd a megtagadott útvonallal is, mert a mindent elfogadó szabályzat szintén mozgó számlálót ad.
nft add rule bridge filter forward iifname "veth9a1" oifname "enp3s0" counter acceptAhol a régi modul megváltoztatja a viselkedést
A régi útvonal engedélyezése egy futó hídon nem a láthatóság hozzáadásának semleges cselekedete. A korábban elérhetetlen szabályok elérhetővé válnak a hídon átmenő forgalom számára, beleértve a másik interfészre írt hosztszabályokat is, és az ip forward lánc alapértelmezett drop szabályzata hirtelen érvényesülhet olyan keretekre, amelyek korábban érintetlenül haladtak át. Egy olyan hoszton, amelyet ezen a hídon keresztül kezelnek, az eredmény konzol nélküli kizárás. Ez nem hipotetikus hibaállapot; ez a hookok halmazának bővítésének szokásos következménye egy olyan gépen, amelyet éppen a bővített útvonalon érsz el.
A biztonságosabb sorrend eldönteni, melyik család birtokolja a szabályzatot, ott megírni a szabályokat, és független helyreállítási útvonalat tartani, mielőtt bármelyik sysctl-t módosítanád. Ha két család is tart szabályokat, dokumentáld, melyik a mérvadó; két átfedő szabályzat az, ahogy egy csomag az egyik helyen elfogadásra, a másikon eldobásra kerül anélkül, hogy egyetlen fájlt is el lehetne olvasni.
Maga az elkülönítés még mindig teljes tervet igényel. Egy forrás engedélyezése egy cél felé csak azt bizonyítja, hogy egy folyam működik, miközben a követelmény általában az, hogy egy VM ne érhesse el a szomszédait vagy a hosztot. Az elutasító szabályokon lévő számlálók fontosabbak, mint az elfogadó szabály számlálója, mert az elfogadó számláló az, amelyről már eleve azt vártad, hogy mozogni fog.
Végül tartsd külön a hoszt-bemenet esetét. A híd saját IP-címére címzett forgalom az inputra érkezik, nem a forwardra, és a forwardban lévő szabály soha nem fogja látni, bármelyik családot választod. Három eset, két család, egy tanulság: az útvonal dönti el a hookot, és a hook dönti el, hogy létezik-e egyáltalán a szabályod.