Puente Linux para máquinas virtuales que no reenvía paquetes IP (pero reenvía ARP)

Puente Linux para máquinas virtuales que no reenvía paquetes IP (pero reenvía ARP)

Núcleo: 5.5.8-arch1-1

Estoy intentando que la red virtual funcione mediante un puente conectado a mi interfaz física. Esta es una configuración típica, ni siquiera estoy intentando hacer nada.extraño.

  • Puente:br0
  • Interfaz física:enp6s0f0

El problema es que Linux no reenvía ningún tráfico IP desde la interfaz física. esta reenviandoTráfico ARPEn ambos sentidos ya que la resolución ARP funciona, pero no llega tráfico IP.enviado desde enp6s0f0.

Cosas que he probado:

  • agregando enp6s0f1al puente, dando enp7s0f0a la VM y usando un cable para vincularse enp7s0f0aenp6s0f1
    • Mismo resultado (tráfico ARP reenviado, tráfico IP no)
  • detener Docker y vaciar todas las tablas
    • ningún cambio
  • deshabilitando rp_filter
    • ningún cambio
  • usando la NIC integrada
    • sin cambios (esta fue en realidad la configuración inicial y dejé caer esta tarjeta de cuatro puertos para ver si la NIC integrada estaba causando un problema)
  • hacer ping a la VM desde otra máquina
    • Pude ver venir la solicitud de eco.eny pude verlo br0pero no fue reenviado al puerto VM (ni al puerto vnet ni a enp6s0f1)
  • habilitar STP en el puente (inicialmente estaba deshabilitado)
    • ningún cambio
○ → ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: enp6s0f0: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc mq master br0 state UP group default qlen 1000
    link/ether 00:10:18:85:1c:c0 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::210:18ff:fe85:1cc0/64 scope link 
       valid_lft forever preferred_lft forever
3: enp6s0f1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 00:10:18:85:1c:c2 brd ff:ff:ff:ff:ff:ff
4: enp7s0f0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 00:10:18:85:1c:c4 brd ff:ff:ff:ff:ff:ff
5: enp7s0f1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 00:10:18:85:1c:c6 brd ff:ff:ff:ff:ff:ff
6: enp9s0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether b4:2e:99:a6:22:f9 brd ff:ff:ff:ff:ff:ff
7: wlp8s0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 08:71:90:4e:e9:77 brd ff:ff:ff:ff:ff:ff
8: br-183e1a17d7f6: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:ba:03:e1:9d brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.1/16 brd 172.18.255.255 scope global br-183e1a17d7f6
       valid_lft forever preferred_lft forever
9: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:02:61:00:66 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
10: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 00:10:18:85:1c:c0 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.205/24 brd 192.168.1.255 scope global dynamic noprefixroute br0
       valid_lft 9730sec preferred_lft 7930sec
    inet6 fe80::210:18ff:fe85:1cc0/64 scope link 
       valid_lft forever preferred_lft forever
11: vnet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br0 state UNKNOWN group default qlen 1000
    link/ether fe:54:00:be:eb:3e brd ff:ff:ff:ff:ff:ff
    inet6 fe80::fc54:ff:febe:eb3e/64 scope link 
       valid_lft forever preferred_lft forever

○ → brctl showstp br0
br0
 bridge id      8000.001018851cc0
 designated root    1000.44e4d9d88a00
 root port         1            path cost          4
 max age          19.99         bridge max age        19.99
 hello time        1.99         bridge hello time      1.99
 forward delay        14.99         bridge forward delay      14.99
 ageing time         299.99
 hello timer           0.00         tcn timer          0.00
 topology change timer     0.00         gc timer          25.78
 flags          


enp6s0f0 (1)
 port id        8001            state            forwarding
 designated root    1000.44e4d9d88a00   path cost          4
 designated bridge  1000.44e4d9d88a00   message age timer     19.21
 designated port    800d            forward delay timer    0.00
 designated cost       0            hold timer         0.00
 flags          

vnet0 (2)
 port id        8002            state            forwarding
 designated root    1000.44e4d9d88a00   path cost        100
 designated bridge  8000.001018851cc0   message age timer      0.00
 designated port    8002            forward delay timer    0.00
 designated cost       4            hold timer         0.22
 flags          

○ → bridge -d link show
2: enp6s0f0: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 master br0 state forwarding priority 32 cost 4 
    hairpin off guard off root_block off fastleave off learning on flood on mcast_flood on mcast_to_unicast off neigh_suppress off vlan_tunnel off isolated off enp6s0f0
8: br-183e1a17d7f6: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 master br-183e1a17d7f6 br-183e1a17d7f6
9: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 master docker0 docker0
10: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master br0 br0
11: vnet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master br0 state forwarding priority 32 cost 100 
    hairpin off guard off root_block off fastleave off learning on flood on mcast_flood on mcast_to_unicast off neigh_suppress off vlan_tunnel off isolated off vnet0

○ → sysctl net.bridge.bridge-nf-call-iptables
net.bridge.bridge-nf-call-iptables = 1

○ → sysctl net.ipv4.conf.br0.forwarding
net.ipv4.conf.br0.forwarding = 1

Respuesta1

Estibadorcargaselbr_netfiltermódulo (para obtener elsistemapropiedad net.bridge.bridge-nf-call-iptables=1) cuando usa iptables. Esto hacepuenteadotramas (Ethernet, capa 2) sujetas aiptablesfiltrado (IP, capa 3):

¿Qué es bridge-netfilter?

Desde el kernel de Linux 3.18-rc1, debe modificar br_netfilter para habilitar bridge-netfilter.

El código bridge-netfilter habilita la siguiente funcionalidad:

Las tablas {Ip,Ip6,Arp} pueden filtrar paquetes IPv4/IPv6/ARP puenteados., incluso cuando está encapsulado en un encabezado PPPoE o VLAN 802.1Q. Esto habilita la funcionalidad de un firewall transparente con estado. Por lo tanto, todas las funciones de filtrado, registro y NAT de las 3 herramientas se pueden utilizar en marcos puenteados. Combinado con ebtables, el código bridge-nf convierte a Linux en un cortafuegos transparente muy potente. Esto permite, por ejemplo, la creación de una máquina de enmascaramiento transparente (es decir, todos los hosts locales piensan que están conectados directamente a Internet). Permitir que las tablas {ip,ip6,arp} vean el tráfico puenteado se puede deshabilitar o habilitar usando las entradas de proceso apropiadas, situado en /proc/sys/net/bridge/:

  • bridge-nf-call-arptables

  • bridge-nf-call-iptables

  • bridge-nf-call-ip6tables

Existe documentación que explica los efectos secundarios causados ​​por este módulo. Esos efectos secundarios sondestinadocuando se utiliza para cortafuegos transparentes de puentes. También eliptables physdev(que se carga br_netfiltercuando se carga) no puede funcionar correctamente sin él (simplemente ya no coincidirá). También se explica cómo prevenir sus efectos, especialmente enCapítulo 7:

Debido al código br-nf, hay 2 formas en que una trama/paquete puede pasar a través de las 3 cadenas de iptables dadas.La primera forma es cuando el marco está puenteado, por lo que las cadenas de iptables son llamadas mediante el código puente.. La segunda forma es cuando se enruta el paquete.

En lugar de desactivar la llamada aiptablespor br_netfiltercódigo como este:

sysctl -w net.bridge.bridge-nf-call-iptables=0

uno debe adaptarseiptablesreglas dondequiera que estén (incluido cualquiera que sea el espacio de nombres de la red) como se explica en el capítulo 7 para evitar efectos secundarios, agregando, por ejemplo, reglas de aceptación en la cadena FORWARD destinadas no al enrutamiento sino al puente. Simplemente deshabilitarlo para solucionar un problema interrumpirá las aplicaciones que dependen de él, comenzando con el aislamiento interno del contenedor de Docker.

Hasta hace pocoen núcleo 5.3este módulo no tenía en cuenta el espacio de nombres y, al cargarlo, de repente lo habilitó en todos los espacios de nombres de la red, lo que provocó todo tipo de problemas inesperados. Desde entonces también es posible habilitarlo por puente ( ip link set dev BRIDGE type bridge nf_call_iptables 1) en lugar de por espacio de nombres.

Una vez que las herramientas (Docker...) y el kernel (>= 5.3) sigan la evolución, simplemente tenerlo habilitado en puentes y espacios de nombres de red seleccionados debería ser suficiente, pero hoy probablemente no. También tenga en cuenta quenúcleo 5.3También heredó el cortafuegos con estado del puente nativo, utilizable pornftables, lo cual es un paso para dejar obsoleto el uso de este módulo (una vez que esté disponible el soporte de encapsulación/decapsulación directa en puente para VLAN y PPPoE):

Filtro de red

Agregue soporte de seguimiento de conexión nativo para el puente. Antes de este conjunto de parches, la única posibilidad que tenían las personas de realizar filtrado con estado era utilizar la capa de emulación br_netfilter, este es un paso adelante para dejarlo de lado.

información relacionada