Por que a túa regra de iptables nunca ve o tráfico VPN pontado
As tramas pontadas poden saltar a cadea IP que estás a vixiar. Compara a familia bridge nativa co antigo br_netfilter antes de engadir outra regra.
Dúas máquinas virtuais no mesmo host chegan á LAN a través dunha ponte, e unha regra situada na cadea ip forward mostra un contador que nunca se move. As tramas son reais, o tráfico pasa e a regra simplemente non está no seu camiño. Comparar as dúas formas en que Linux expón o tráfico pontado explica ese silencio, e tamén explica por que cargar un módulo antigo é unha resposta peor do que parece.
Dous camiños a través dun só host
Un paquete pode saír deste host de dúas maneiras moi distintas, e a diferenza decide que hooks o ven. Se o destino está máis alá dun porto físico e a trama conmútase entre dous portos da ponte, o host reenvía unha trama Ethernet; non se consulta o código de encamiñamento e non se produce ningún salto encamiñado. Se o destino é o propio host, ou unha rede alcanzada por unha interface de túnel, o paquete encamíñase e os hooks da capa IP si se aplican. Ten presente esa bifurcación, porque cada pregunta posterior sobre cadeas e familias depende de cal dos dous camiños toma unha trama.
Esa distinción é toda a historia detrás dunha regra que non conta nada. Unha trama pontada de veth9a1 a enp3s0 cruza a ponte, non a pila IP, así que unha cadea ip forward non ve nada co que coincidir. Os nomes de interface dun exemplo máis antigo non determinan que camiño tes, e por iso o primeiro paso é mirar a topoloxía e non o conxunto de regras.
Un túnel engade un terceiro caso que merece un nome. Un dispositivo TUN entrega paquetes IP ao host, así que se encamiñan e si atravesan cadeas IP, mentres que un dispositivo TAP conectado a unha ponte entrega tramas e compórtase como o caso pontado. O tipo de dispositivo, non o nome do produto, é o que decide.
Compara as dúas familias que poden ver unha trama pontada
Linux admite filtrado de ponte nativo mediante a familia bridge de nftables, e non necesita ningún módulo antigo para inspeccionar e descartar tramas en voo. A propia documentación da ponte do kernel fai esa recomendación directamente, algo que convén saber antes de que un resultado de busca che diga que cargues un módulo.
| 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 |
Usar o comando nft en lugar de iptables non coloca, por si só, unha regra na familia correcta. Unha cadea declarada na familia bridge ve tramas; unha cadea declarada en ip, ip6 ou inet non as ve, sen importar que binario a creou. A familia é unha propiedade da cadea, non da ferramenta que a escribiu.
O camiño antigo funciona doutro xeito, e por iso convén comparar en lugar de escoller un bando por costume. Cargar br_netfilter e activar os axustes bridge-nf-call volve expor o tráfico IPv4 e IPv6 pontado a través dos hooks da capa IP, de modo que unha regra normal de iptables por fin pode coincidir con el. As tramas non cambian; o que cambia é o conxunto de hooks que atravesan, o que significa que cada regra de host existente ten agora un público novo.
Le o camiño efectivo antes de engadir unha regra
Tres comandos establecen onde estás: a que está conectada a ponte, se o módulo antigo está activo e que cadeas existen xa na familia bridge. Execútaos antes de escribir nada, porque a resposta decide cal dos dous deseños estás a ampliar. Saltarse este paso é como unha regra correcta acaba nunha cadea que nada atravesa.
bridge link show
lsmod | grep br_netfilter
nft list ruleset | grep -A4 "chain forward"
A saída separa os casos con claridade. Os portos listados baixo a ponte dinche que interfaces se conmutan; un resultado baleiro de lsmod significa ningunha visibilidade na capa IP das tramas pontadas; unha cadea forward existente da familia bridge significa que xa hai un propietario da política e que a túa regra pertence alí en lugar de a unha cadea nova propia.
Logo engade unha regra fácil de reler, cun contador e sen cambiar o veredicto, e fai pasar un único fluxo representativo pola ponte. Un contador que se move demostra que a trama chegou á regra. Iso é todo o que demostra, así que continúa tamén co camiño denegado, xa que unha política que o acepta todo tamén produce un contador en movemento.
nft add rule bridge filter forward iifname "veth9a1" oifname "enp3s0" counter acceptOnde cambia o comportamento o módulo antigo
Activar o camiño antigo nunha ponte en funcionamento non é un acto neutro de engadir visibilidade. As regras que antes eran inalcanzables para o tráfico pontado pasan a ser alcanzables, incluídas regras de host escritas para outra interface, e unha política drop predeterminada na cadea ip forward pode aplicarse de súpeto a tramas que antes pasaban intactas. Nun host administrado a través desa ponte, o resultado é un bloqueo sen consola. Ese non é un modo de fallo hipotético; é a consecuencia ordinaria de ampliar un conxunto de hooks nunha máquina á que chegas polo camiño que acabas de ampliar.
A secuencia máis segura é decidir que familia posúe a política, escribir alí as regras e manter un camiño de recuperación independente antes de cambiar calquera sysctl. Se dúas familias teñen regras, documenta cal é a autoridade; dúas políticas superpostas son a forma en que un paquete se acepta nun lugar e se descarta noutro sen un só ficheiro que ler.
O illamento en si aínda necesita un deseño completo. Permitir unha orixe cara a un destino só demostra que un fluxo funciona, mentres que o requisito adoita ser que unha VM non poida alcanzar os seus veciños nin o host. Os contadores das regras de denegación importan máis que o contador da regra de aceptación, porque o contador de aceptación é o que xa esperabas que se movese.
Por último, mantén separado o caso da entrada do host. O tráfico dirixido á propia IP da ponte chega a input, non a forward, e unha regra en forward nunca o verá, escollas a familia que escollas. Tres casos, dúas familias, unha lección: o camiño decide o hook, e o hook decide se a túa regra existe sequera.