Ponte Linux para máquinas virtuais que não encaminham pacotes IP (mas estão encaminhando ARP)

Ponte Linux para máquinas virtuais que não encaminham pacotes IP (mas estão encaminhando ARP)

Núcleo: 5.5.8-arch1-1

Estou tentando fazer com que a rede virtual funcione usando uma ponte conectada à minha interface física. Esta é uma configuração típica, nem estou tentando fazer nadaesquisito.

  • Ponte:br0
  • Interface física:enp6s0f0

O problema é que o Linux não encaminha nenhum tráfego IP pela interface física. Está encaminhandoTráfego ARPnos dois sentidos, já que a resolução ARP funciona, mas nenhum tráfego IP é obtidoenviado de enp6s0f0.

Coisas que tentei:

  • adicionando enp6s0f1à ponte, dando enp7s0f0à VM e usando um cabo para conectar enp7s0f0-se aenp6s0f1
    • mesmo resultado (tráfego ARP encaminhado, tráfego IP não)
  • parando o docker e liberando todas as tabelas
    • nenhuma mudança
  • desabilitando rp_filter
    • nenhuma mudança
  • usando a NIC integrada
    • nenhuma alteração (esta foi na verdade a configuração inicial e coloquei esta placa de quatro portas para ver se a NIC integrada estava causando o problema)
  • executando ping na VM de outra máquina
    • Eu pude ver a solicitação de eco chegandoeme pude vê-lo, br0mas não foi encaminhado para a porta VM (a porta vnet ou enp6s0f1)
  • habilitando STP na ponte (foi inicialmente desabilitado)
    • nenhuma mudança
○ → 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

Responder1

Dockercargasobr_netfiltermódulo (para obter osysctlproperty net.bridge.bridge-nf-call-iptables=1) quando usa iptables. Isto fazem pontequadros (Ethernet, camada 2) sujeitos atabelas de ipfiltragem (IP, camada 3):

O que é bridge-netfilter?

Desde o kernel Linux 3.18-rc1, você deve modificar o br_netfilter para ativar o bridge-netfilter.

O código bridge-netfilter permite a seguinte funcionalidade:

Tabelas {Ip,Ip6,Arp}podem filtrar pacotes IPv4/IPv6/ARP em ponte, mesmo quando encapsulado em uma VLAN 802.1Q ou cabeçalho PPPoE. Isso habilita a funcionalidade de um firewall transparente e com estado. Todos os recursos de filtragem, registro e NAT das 3 ferramentas podem, portanto, ser usados ​​em quadros em ponte. Combinado com ebtables, o código bridge-nf torna o Linux um firewall transparente muito poderoso. Isto permite, por exemplo, a criação de uma máquina de mascaramento transparente (ou seja, todos os hosts locais pensam que estão diretamente conectados à Internet). Permitir que tabelas {ip,ip6,arp} vejam o tráfego em ponte pode ser desabilitado ou habilitado usando as entradas proc apropriadas, localizado em /proc/sys/net/bridge/:

  • bridge-nf-call-arptables

  • bridge-nf-call-iptables

  • bridge-nf-call-ip6tables

Existe documentação explicando os efeitos colaterais causados ​​por este módulo. Esses efeitos colaterais sãopretendidoao usá-lo para firewall transparente de ponte. Também otabelas de ip physdev(que carrega br_netfilterquando carregado) match não pode funcionar corretamente sem ele (simplesmente não corresponderá mais). Também é explicado como prevenir seus efeitos, especialmente emCapítulo 7:

Por causa do código br-nf, existem 2 maneiras pelas quais um quadro/pacote pode passar pelas 3 cadeias de iptables fornecidas.A primeira maneira é quando o quadro está em ponte, então as cadeias do iptables são chamadas pelo código da ponte. A segunda maneira é quando o pacote é roteado.

Em vez de desativar a chamada paratabelas de ippelo br_netfiltercódigo de como este:

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

deve-se adaptartabelas de ipregras onde quer que estejam (incluindo qualquer que seja o namespace da rede), conforme explicado no capítulo 7, para evitar efeitos colaterais, adicionando, por exemplo, regras de aceitação na cadeia FORWARD destinadas não ao roteamento, mas à ponte. Simplesmente desativá-lo para corrigir um problema irá interromper os aplicativos que dependem dele, começando com o isolamento interno do contêiner do Docker.

Até recentementeem núcleo 5.3este módulo não tinha reconhecimento de namespace e tê-lo carregado repentinamente o habilitou em todos os namespaces de rede, causando todos os tipos de problemas quando inesperados. Desde então também é possível habilitá-lo por bridge ( ip link set dev BRIDGE type bridge nf_call_iptables 1) em vez de por namespace.

Uma vez que as ferramentas (Docker...) e o kernel (>= 5.3) seguem a evolução, simplesmente habilitá-los em namespaces e pontes de rede selecionados deve ser suficiente, mas hoje provavelmente não. Observe também quenúcleo 5.3também herdou firewall com estado de ponte nativa, utilizável pornftáveis, o que é um passo para tornar obsoleto o uso deste módulo (uma vez que o suporte de encapsulamento/descapsulação direto em bridge para VLAN e PPPoE esteja disponível):

Filtro de rede

Adicione suporte nativo de rastreamento de conexão para a ponte. Antes deste patchset, a única chance para as pessoas fazerem filtragem stateful era usar a camada de emulação br_netfilter, este é um passo à frente para desativá-lo

informação relacionada