Waarom jou iptables-reël nooit gebrugde VPN-verkeer sien nie
Gebrugde rame kan die IP-ketting wat jy dophou, omseil. Vergelyk die inheemse brugfamilie met die ou br_netfilter voordat jy nog 'n reël byvoeg.
Twee virtuele masjiene op dieselfde gasheer bereik die LAN deur 'n brug, en 'n reël in die ip forward-ketting wys 'n teller wat nooit beweeg nie. Die rame is werklik, die verkeer gaan deur, en die reël is bloot nie op sy pad nie. Die vergelyking van die twee maniere waarop Linux bruggerkeer blootstel, verduidelik die stilte, en dit verduidelik ook waarom die laai van een ou module 'n slegter antwoord is as wat dit lyk.
Twee paaie deur een gasheer
In pakket kan hierdie gasheer op twee baie verskillende maniere verlaat, en die verskil bepaal watter hake dit sien. As die bestemming anderkant 'n fisiese poort is en die raam tussen twee brugpoorte geskakel word, stuur die gasheer 'n Ethernet-raam oor; die roeteringkode word nie geraadpleeg nie, en geen geroeteerde sprong vind plaas nie. As die bestemming die gasheer self is, of 'n netwerk wat deur 'n tonnelkoppelvlak bereik word, word die pakket geroeteer en die IP-laag-hake geld wel. Hou daardie vurk in gedagte, want elke latere vraag oor kettings en families volg uit watter van die twee 'n raam neem.
Daardie onderskeid is die hele verhaal agter 'n reël wat niks tel nie. 'n Gebrugde raam van veth9a1 na enp3s0 kruis die brug, nie die IP-stapel nie, so 'n ip forward-ketting sien niks om te pas nie. Koppelvlakname in 'n ouer voorbeeld besluit nie watter pad jy het nie, en daarom is die eerste stap om na die topologie te kyk eerder as na die reëlversameling.
'n Tonnel voeg 'n derde geval by wat die moeite werd is om te noem. 'n TUN-toestel lewer IP-pakkette aan die gasheer, so dié word geroeteer en beweeg wel deur IP-kettings, terwyl 'n TAP-toestel wat aan 'n brug gekoppel is, rame lewer en soos die gebrugde geval optree. Die toesteltipe, nie die produknaam nie, besluit.
Vergelyk die twee families wat 'n brugraam kan sien
Linux ondersteun inheemse brugfiltering deur nftables se brugfamilie, en dit het geen ou module nodig om rame in vlug te ondersoek en te laat val nie. Die kernel se eie brugdokumentasie maak daardie aanbeveling regstreeks, wat die moeite werd is om te weet voordat 'n soekresultaat jou vertel om 'n module te laai.
| 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 |
Om die nft-opdrag in plaas van iptables te gebruik, plaas nie op sigself 'n reël in die regte familie nie. 'n Ketting wat in die brugfamilie verklaar word, sien rame; 'n ketting wat in ip, ip6 of inet verklaar word, sien dit nie, maak nie saak watter binêre dit geskep het nie. Die familie is 'n eienskap van die ketting, nie van die gereedskap wat dit getik het nie.
Die ou pad werk anders, en dit is die rede om te vergelyk eerder as om uit gewoonte 'n kant te kies. Om br_netfilter te laai en die bridge-nf-call-instellings te aktiveer, stel gebrugde IPv4- en IPv6-verkeer weer deur die IP-laag-hake bloot, sodat 'n gewone iptables-reël dit uiteindelik kan pas. Die rame verander nie; die stel hake waardeur hulle beweeg, verander wel, wat beteken elke bestaande gasheerreël het nou 'n nuwe gehoor.
Lees die effektiewe pad voordat jy 'n reël byvoeg
Drie opdragte stel vas waar jy is: waaraan die brug gekoppel is, of die ou module aktief is, en watter kettings reeds in die brugfamilie bestaan. Voer hulle uit voordat jy iets skryf, want die antwoord bepaal watter van die twee ontwerpe jy uitbrei. Om hierdie stap oor te slaan, is hoe 'n korrekte reël in 'n ketting beland waardeur niks beweeg nie.
bridge link show
lsmod | grep br_netfilter
nft list ruleset | grep -A4 "chain forward"
Die uitset skei die gevalle skoon. Poorte wat onder die brug gelys word, vertel jou watter koppelvlakke geskakel word; 'n leë lsmod-uitset beteken glad geen IP-laag-sigbaarheid van gebrugde rame nie; 'n bestaande brugfamilie-forward-ketting beteken 'n beleidseienaar bestaan reeds en jou reël hoort daar eerder as in 'n nuwe ketting van sy eie.
Voeg dan een reël by wat maklik is om terug te lees, met 'n teller en geen verandering aan die uitspraak nie, en stuur 'n enkele verteenwoordigende vloei deur die brug. 'n Teller wat beweeg, bewys die raam het die reël bereik. Dit is al wat dit bewys, so volg dit ook met die geweierde pad, want 'n beleid wat alles aanvaar, lewer ook 'n bewegende teller.
nft add rule bridge filter forward iifname "veth9a1" oifname "enp3s0" counter acceptWaar die ou module gedrag verander
Om die ou pad op 'n lopende brug te aktiveer, is nie 'n neutrale daad van sigbaarheid byvoeg nie. Reëls wat voorheen onbereikbaar was vir gebrugde verkeer, word bereikbaar, insluitend gasheerreëls wat vir 'n ander koppelvlak geskryf is, en 'n verstek-drop-beleid in die ip forward-ketting kan skielik geld op rame wat vantevore onaangeraak deurgegaan het. Op 'n gasheer wat oor daardie brug bestuur word, is die resultaat 'n uitsluiting sonder konsole. Dit is nie 'n hipotetiese foutmodus nie; dit is die gewone gevolg van die uitbreiding van 'n stel hake op 'n masjien wat jy bereik deur die pad wat jy pas verbreed het.
Die veiliger volgorde is om te besluit watter familie die beleid besit, die reëls daar te skryf, en 'n onafhanklike herstelpad te behou voordat enige sysctl verander word. As twee families albei reëls hou, dokumenteer watter een gesaghebbend is; twee oorvleuelende beleide is hoe 'n pakket op een plek aanvaar en op 'n ander laat val word sonder 'n enkele lêer om te lees.
Isolasie self het steeds 'n volledige ontwerp nodig. Om een bron na een bestemming toe te laat, bewys net dat een vloei werk, terwyl die vereiste gewoonlik is dat 'n VM nie sy bure of die gasheer kan bereik nie. Tellers op die weier-reëls maak meer saak as tellers op die aanvaardingsreël, want die aanvaardingsteller is die een wat jy reeds verwag het sou beweeg.
Laastens, hou die gasheer-invoer-geval apart. Verkeer wat aan die brug se eie IP gerig is, kom by input aan, nie by forward nie, en 'n reël in forward sal dit nooit sien nie, maak nie saak watter familie jy kies nie. Drie gevalle, twee families, een les: die pad besluit die haak, en die haak besluit of jou reël hoegenaamd bestaan.