Dues màquines virtuals al mateix amfitrió arriben a la LAN a través d’un pont, i una regla col·locada a la cadena ip forward mostra un comptador que no es mou mai. Les trames són reals, el tràfic passa i la regla simplement no és al seu camí. Comparar les dues maneres com Linux exposa el tràfic pontat explica aquest silenci, i també explica per què carregar un mòdul antic és una resposta pitjor del que sembla.

Dos camins a través d’un sol amfitrió

Un paquet pot sortir d’aquest amfitrió de dues maneres molt diferents, i la diferència decideix quins hooks el veuen. Si la destinació és més enllà d’un port físic i la trama es commuta entre dos ports del pont, l’amfitrió reenvia una trama Ethernet; no es consulta el codi d’encaminament i no es produeix cap salt encaminat. Si la destinació és l’amfitrió mateix, o una xarxa a la qual s’arriba per una interfície de túnel, el paquet s’encamina i els hooks de la capa IP sí que s’apliquen. Tingueu aquesta bifurcació present, perquè cada pregunta posterior sobre cadenes i famílies depèn de quin dels dos camins pren una trama.

Aquesta distinció és tota la història d’una regla que no compta res. Una trama pontada de veth9a1 a enp3s0 travessa el pont, no la pila IP, així que una cadena ip forward no veu res per fer coincidir. Els noms d’interfície d’un exemple més antic no determinen quin camí teniu, i per això el primer pas és mirar la topologia i no el conjunt de regles.

Un túnel afegeix un tercer cas que val la pena anomenar. Un dispositiu TUN lliura paquets IP a l’amfitrió, així que s’encaminen i sí que travessen cadenes IP, mentre que un dispositiu TAP connectat a un pont lliura trames i es comporta com el cas pontat. El tipus de dispositiu, no el nom del producte, és el que decideix.

Compareu les dues famílies que poden veure una trama pontada

Linux admet filtratge de pont natiu mitjançant la família bridge de nftables, i no necessita cap mòdul antic per inspeccionar i descartar trames en vol. La documentació del pont del propi nucli fa aquesta recomanació directament, cosa que val la pena saber abans que un resultat de cerca us digui de carregar un mòdul.

Observation pointWhat it seesWhat it costs
nftables bridge family chainsEthernet frames forwarded between bridge ports, in both directionsRules must be written in bridge syntax with link-layer matches
Legacy br_netfilter plus an ip chainBridged IPv4 and IPv6 packets, re-exposed through IP-layer hooksExisting host rules may begin matching traffic they never saw before
inet chain for routed trafficPackets the host routes, including traffic arriving from a TUN deviceNo visibility into purely switched frames

Fer servir l’ordre nft en lloc d’iptables no col·loca, per si sol, una regla a la família correcta. Una cadena declarada a la família bridge veu trames; una cadena declarada a ip, ip6 o inet no les veu, sigui quin sigui el binari que l’hagi creada. La família és una propietat de la cadena, no de l’eina que l’ha escrita.

El camí antic funciona diferent, i per això cal comparar en lloc de triar un bàndol per costum. Carregar br_netfilter i activar els paràmetres bridge-nf-call torna a exposar el tràfic IPv4 i IPv6 pontat a través dels hooks de la capa IP, de manera que una regla d’iptables corrent finalment hi pot coincidir. Les trames no canvien; el que canvia és el conjunt de hooks que travessen, cosa que significa que cada regla d’amfitrió existent té ara un públic nou.

Llegiu el camí efectiu abans d’afegir una regla

Tres ordres estableixen on sou: a què està connectat el pont, si el mòdul antic és actiu i quines cadenes ja existeixen a la família bridge. Executeu-les abans d’escriure res, perquè la resposta decideix quin dels dos dissenys esteu ampliant. Saltar-se aquest pas és com una regla correcta acaba en una cadena que ningú no travessa.

bridge link show
lsmod | grep br_netfilter
nft list ruleset | grep -A4 "chain forward"

La sortida separa els casos netament. Els ports llistats sota el pont us diuen quines interfícies es commuten; un resultat buit de lsmod vol dir cap visibilitat a la capa IP de les trames pontades; una cadena forward existent de la família bridge vol dir que ja hi ha un propietari de la política i que la vostra regla hi pertany, i no a una cadena nova pròpia.

Després afegiu una regla fàcil de rellegir, amb un comptador i sense canviar el veredicte, i feu passar un únic flux representatiu pel pont. Un comptador que es mou demostra que la trama ha arribat a la regla. Això és tot el que demostra, així que seguiu-lo també amb el camí denegat, ja que una política que ho accepta tot també produeix un comptador que es mou.

nft add rule bridge filter forward iifname "veth9a1" oifname "enp3s0" counter accept

On el mòdul antic canvia el comportament

Activar el camí antic en un pont en funcionament no és un acte neutral d’afegir visibilitat. Les regles que abans eren inabastables per al tràfic pontat es tornen abastables, incloent-hi regles d’amfitrió escrites per a una altra interfície, i una política drop per defecte a la cadena ip forward pot aplicar de sobte a trames que abans passaven intactes. En un amfitrió gestionat a través d’aquell pont, el resultat és un bloqueig sense consola. Aquest no és un mode de fallada hipotètic; és la conseqüència ordinària d’ampliar un conjunt de hooks en una màquina a la qual arribeu pel camí que acabeu d’ampliar.

La seqüència més segura és decidir quina família posseeix la política, escriure-hi les regles i mantenir un camí de recuperació independent abans de canviar cap sysctl. Si dues famílies tenen regles, documenteu quina és l’autoritat; dues polítiques superposades són com un paquet s’accepta en un lloc i es descarta en un altre sense cap fitxer únic per llegir.

L’aïllament mateix encara necessita un disseny complet. Permetre un origen cap a una destinació només demostra que un flux funciona, mentre que el requisit sol ser que una VM no pugui arribar als seus veïns ni a l’amfitrió. Els comptadors de les regles de denegació importen més que el comptador de la regla d’acceptació, perquè el comptador d’acceptació és el que ja esperàveu que es mogués.

Finalment, manteniu el cas d’entrada de l’amfitrió a part. El tràfic adreçat a la pròpia IP del pont arriba a input, no a forward, i una regla a forward no el veurà mai, trieu la família que trieu. Tres casos, dues famílies, una lliçó: el camí decideix el hook, i el hook decideix si la vostra regla existeix o no.

Articles relacionats