Estou trabalhando dentro de um contêiner, tentando demonstrar a ponte Linux e a conexão da Camada 2.
Comecei um novo contêiner:
host$ docker run -it --rm --name c1 --privileged networking sh
No contêiner usei o seguinte para criar a interface de ponte e a interface de toque
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 tap é a correta para usar? Como posso mostrar a conexão da camada 2 em um contêiner com ponte Linux?
seguindo a resposta do @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
executar 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
tanto o ping quanto 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 estou perdendo? o que é 6e2b9b27d81b
?
Responder1
Primeiro: sua interface não possui um endereço IP configurado, portanto você não pode enviar e receber pacotes IP através dela sem ter um endereço. ( ping
usa ICMP, um protocolo IP.)
Segundo: não é assim que as interfaces tap funcionam – elas não “refletirão” os ping
pacotes de volta para a ponte; em vez disso, eles esperam estar conectados a umprograma, por exemplo, OpenVPN ou outro software VPN.
Portanto, sua abordagem funcionaria se você tentasse, por exemplo, configurar o OpenVPN conectado à rede host (compartilhando uma única sub-rede). Mas se você quiser apenas ver como funcionam as pontes do Linux, terá mais sorte com veth
interfaces.
E se tudo o que você deseja é uma conexão L2 com a LAN externa, então você está criando a ponte no lugar errado – essas coisas geralmente são feitas nohospedar, não em um contêiner.
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 por uma extremidade, eles passam pelaoutrofim. (É claro que as pontes podem ter múltiplas portas, não apenas duas, mas o mesmo princípio geral se aplica.)
Quando você conecta uma interface, a ponte assume o controlehospedarlado dessa interface, então ele só vê os pacotes que vieramdea 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 ───┘
Portanto, na sua situação, a interface tap é inútil – todos os pacotes que você tentar enviar através dela serão descartados, já que não há nenhum programa anexado na outra extremidade. (Se você verificar, ip link
provavelmente o verá com a NO-CARRIER
bandeira.)
Em vez disso, você poderia usar, por exemplo, uma veth
interface (do mesmo tipo que os contêineres costumam usar) – elas são sempre criadas em pares conectados entre si. Portanto, se você solicitar ping
o envio de pacotes veth0
, eles retornarão e passarão pelo lado do host veth1
, onde a ponte poderá recebê-los e encaminhá-los pela eth0, se necessário.
┌── [eth0 ──› NIC] ──› network
br0 ──┤
└── [veth1 ‹───› veth0] ‹── ping -I veth0