como configurar a ponte linux dentro de um container?

2

Estou trabalhando dentro de um contêiner, tentando demonstrar a ponte do Linux e a conexão da Camada 2.

Eu iniciei um novo contêiner:

host$ docker run -it --rm --name c1 --privileged networking sh

No contêiner, usei o seguinte para criar a interface da ponte e tocar na interface

c1$ ip link add br0 type bridge
c1$ ip link set eth0 master br0
c1$ ip tuntap add tap0 mode tap
c1$ ip link set tap0 master br0
c1$ ip link set tap0 up
c1$ ip link set br0 up
c1$ ping -I tap0 172.17.0.2

O último comando ping não está funcionando. O que estou fazendo de errado ? a interface de toque é a correta para usar? Como posso mostrar a conexão da camada 2 em um container com bridge linux?

seguindo a resposta @grawity, tentei o seguinte:

ip link add dev veth1 type veth peer name veth2
ip link set dev veth1 up
ip link add br0 type bridge
ip link set veth1 master br0
ip link set eth0 master br0
ip link set br0 up
ip link set veth1 up
ip link set veth2 up
ip addr add 10.0.0.3/24 dev veth1
ip addr add 10.0.0.4/24 dev veth2
ip addr add 10.0.0.2/24 dev br0


/ # brctl show
bridge name bridge id       STP enabled interfaces
br0     8000.0242ac110002   no      veth1
                                    eth0

ping para todas as interfaces funciona

/ # ping -c1 10.0.0.2
PING 10.0.0.2 (10.0.0.2): 56 data bytes
64 bytes from 10.0.0.2: seq=0 ttl=64 time=0.068 ms

--- 10.0.0.2 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.068/0.068/0.068 ms
/ # ping -c1 10.0.0.3
PING 10.0.0.3 (10.0.0.3): 56 data bytes
64 bytes from 10.0.0.3: seq=0 ttl=64 time=0.072 ms

--- 10.0.0.3 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.072/0.072/0.072 ms
/ # ping -c1 10.0.0.4
PING 10.0.0.4 (10.0.0.4): 56 data bytes
64 bytes from 10.0.0.4: seq=0 ttl=64 time=0.095 ms

--- 10.0.0.4 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.095/0.095/0.095 ms

o ping e o arping não estão funcionando de veth2 para eth0.

ping -I veth2 -c1 172.17.0.2

saída do link ip

10: veth2@veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000\    link/ether f2:8e:e4:f7:fc:7c brd ff:ff:ff:ff:ff:ff
11: veth1@veth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UP mode DEFAULT group default qlen 1000\    link/ether 1a:3a:26:02:8a:a1 brd ff:ff:ff:ff:ff:ff
12: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000\    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
21: eth0@if22: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UP mode DEFAULT group default \    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0

e ip uma saída

/ # ip -o a
1: lo    inet 127.0.0.1/8 scope host lo\       valid_lft forever preferred_lft forever
1: lo    inet6 ::1/128 scope host \       valid_lft forever preferred_lft forever
10: veth2    inet 10.0.0.4/24 scope global veth2\       valid_lft forever preferred_lft forever
10: veth2    inet6 fe80::f08e:e4ff:fef7:fc7c/64 scope link \       valid_lft forever preferred_lft forever
11: veth1    inet 10.0.0.3/24 scope global veth1\       valid_lft forever preferred_lft forever
11: veth1    inet6 fe80::183a:26ff:fe02:8aa1/64 scope link \       valid_lft forever preferred_lft forever
12: br0    inet 10.0.0.2/24 scope global br0\       valid_lft forever preferred_lft forever
12: br0    inet6 fe80::42:acff:fe11:2/64 scope link \       valid_lft forever preferred_lft forever
21: eth0    inet 172.17.0.2/16 scope global eth0\       valid_lft forever preferred_lft forever
21: eth0    inet6 fe80::42:acff:fe11:2/64 scope link \       valid_lft forever preferred_lft forever

tcpdump tem o seguinte

09:29:31.253321 ARP, Request who-has 6e2b9b27d81b (Broadcast) tell 10.0.0.4, length 28
09:29:31.253509 ARP, Request who-has 172.17.0.1 tell 6e2b9b27d81b, length 28
09:29:31.253541 ARP, Reply 172.17.0.1 is-at 02:42:be:d6:a7:81 (oui Unknown), length 28
09:29:31.253541 ARP, Reply 172.17.0.1 is-at 02:42:be:d6:a7:81 (oui Unknown), length 28
09:29:36.263281 ARP, Request who-has 172.17.0.1 tell 6e2b9b27d81b, length 28
09:29:36.263313 ARP, Reply 172.17.0.1 is-at 02:42:be:d6:a7:81 (oui Unknown), length 28
09:29:36.263313 ARP, Reply 172.17.0.1 is-at 02:42:be:d6:a7:81 (oui Unknown), length 28
09:29:36.268142 ARP, Request who-has 6e2b9b27d81b (Broadcast) tell 10.0.0.4, length 28
09:29:41.284187 ARP, Request who-has 6e2b9b27d81b (Broadcast) tell 10.0.0.4, length 28
09:29:41.284196 ARP, Request who-has 6e2b9b27d81b (Broadcast) tell 10.0.0.4, length 28

O que eu estou perdendo? o que é 6e2b9b27d81b ?

    
por odedpr 02.02.2017 / 09:56

1 resposta

1

Primeiro: sua interface não tem um endereço IP configurado, então você não pode realmente enviar e receber pacotes IP sem ter um endereço. ( ping usa o ICMP, um protocolo IP.)

Segundo: Não é assim que as interfaces de toque funcionam - elas não "refletirão" os pacotes ping de volta à ponte; em vez disso, eles esperam estar conectados a um programa , por exemplo OpenVPN ou outro software VPN.

Portanto, sua abordagem funcionaria se você tentasse, por exemplo, configurar o OpenVPN com ponte para a rede host (compartilhando uma única sub-rede). Mas se você quiser apenas ver como as pontes Linux funcionam, você terá mais sorte com as interfaces veth .

E se tudo que você quer é uma conexão L2 com a LAN externa, então você está criando a ponte no lugar errado - essas coisas geralmente são feitas no host , não em um container.

Pense em uma interface de rede como tendo duas extremidades: a extremidade 'host' é mostrada no sistema operacional e usada por todos os softwares; a outra extremidade está conectada à rede real (por exemplo, uma porta Ethernet física). Se os pacotes chegam através de uma extremidade, eles passam pelo final outro . (Pontes obviamente podem ter múltiplas portas, não apenas duas, mas o mesmo princípio geral se aplica.)

Quando você faz o bridge de uma interface, a bridge assume o lado host dessa interface, de modo que só vê os pacotes que vieram da rede. Mas se você usar ping -I eth0 ou ping -I tap0 , estará ignorando a ponte e enviando tudo para a rede real.

ping ──› [eth0 ──› NIC] ──› network

ping ──› [tap0 ──› VPN software] ──› ???

               ┌─› [eth0 ──› NIC] ──› network
ping ──› br0 ──┤
               └─› [tap0 ──› VPN software] ──› ???
                     ∧
     ping -I tap0 ───┘

Assim, na sua situação, a interface de toque é inútil - todos os pacotes que você tentar enviar através dela serão descartados, já que não há nenhum programa anexado à outra extremidade. (Se você verificar ip link , provavelmente verá com o NO-CARRIER flag.)

Em vez disso, você poderia usar, por exemplo, uma interface veth (o mesmo tipo que os contêineres costumam usar) - eles são sempre criados em pares conectados uns aos outros. Portanto, se você disser ping para enviar pacotes através de veth0 , eles retornarão e passarão pelo host do veth1 , onde a ponte poderá recebê-los e encaminhará pela eth0, se necessário.

      ┌── [eth0 ──› NIC] ──› network
br0 ──┤
      └── [veth1 ‹───› veth0] ‹── ping -I veth0
    
por 02.02.2017 / 12:02