Quando uma estação deseja enviar um pacote para outra estação ou gateway de uma rede, é necessário, além de conhecer o endereço IP de destino, saber qual é o endereço ethernet (MAC address) de destino. Neste momento o protocolo ARP é acionado para encontrar a partir de um endereço IP o endereço ethernet correspondente.
Se o host-192-168-0-9 deseja enviar um datagrama IP para o host-192-168-0-100 então é necessário primeiro conhecer o endereço ethernet (mac address), que no exemplo abaixo é "00:0e:35:50:xx:xx":
host-192-168-0-9:~ $ tcpdump -ni en1 arp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decodelistening on en1, link-type EN10MB (Ethernet), capture size 96 bytes
00:28:34.090647 arp who-has 192.168.0.100 tell 192.168.0.9
00:28:34.094124 arp reply 192.168.0.100 is-at 00:0e:35:50:xx:xx
Até aqui tudo normal.
Quando um host com linux instalado possui duas ou mais interfaces de rede conectadas a um mesmo segmento de rede, podem ocorrer problemas com o mapeamento entre os endereços de camada 2 (ethernet) e camada 3 (IP). Isso ocorre pois o host responderá uma requisição ARP pelas duas interfaces de rede. Este comportamento pode gerar confusão na tabela de ARP do host que disparou a requisição ARP. Este comportamento é chamado de ARP Flux. É importante ressaltar também que este comportamento somente irá ocorrer quando duas ou mais interfaces estiverem conectadas à um mesmo segmento de rede (mesmo domínio de broadcast).
Um exemplo de ARP Flux:
[root@real-client]# arping -I eth0 -c 3 10.10.20.67
ARPING 10.10.20.67 from 10.10.20.33 eth0
Unicast reply from 10.10.20.67 [00:80:C8:7E:71:D4] 11.298ms
Unicast reply from 10.10.20.67 [00:80:C8:E8:1E:FC] 12.077ms
Unicast reply from 10.10.20.67 [00:80:C8:E8:1E:FC] 1.542ms
Unicast reply from 10.10.20.67 [00:80:C8:E8:1E:FC] 1.547ms
Sent 3 probes (1 broadcast(s))
Received 4 response(s)
Note que para um mesmo endereço IP há duas respostas com dois endereços ethernet distintos. Como não é possível saber qual das respostas será processada primeiro pelo host que disparou a requisição é possível que o endereço errado seja incluído na tabela ARP e a comunicação entre os dois hosts não aconteça.
Há basicamente quatro maneiras diferentes de resolver este problema. No kernel 2.4 pode-se utilizar a opção arp_filter do sysctl. Nos kernels 2.2 é necessário utilizar a opção hidden do systcl. Estas duas opções controlam a forma como são tratadas as requisições ARP por interface.
As outras soluções envolvem a utilização do a ferramenta ip arp e a opção noarp route flag. A ferramenta ip arp e a filtragem do protocolo ARP está documentada aqui.
Como utilizar a opção arp_filter?
Basicamente a utilização da opção arp_filter (/proc/sys/net/ipv4/conf/$DEV/arp_filter) faz com que um host utilize a tabela de roteamento para encontrar por qual interface o mesmo deve encaminhar a resposta de uma requisição ARP, ao invés da opção padrão de encaminhar a resposta por TODAS as interfaces.
De modo geral, a utilização da opção arp_filter resolve o problema de ARP Flux e pode gerar problemas somente em cenários mais complexos onde é necessário controlar de forma mais detalhada as requisições e respostas do protocolo ARP.
Para alterar esta opção podemos utilizar "o bom e velho" echo, por exemplo, para a interface eth0:
user@host-192-168-0-9:~ $ echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_filter
Para mais informações sobre o protocolo ARP e o problema do ARP Flux, consultar este material (em inglês).
Gustavo, não entendi muito bem.
ResponderExcluirVocê diz que "Quando um host com linux instalado possui duas ou mais interfaces de rede conectadas a um mesmo segmento de rede, podem ocorrer problemas com o mapeamento entre os endereços de camada 2 (ethernet) e camada 3 (IP). Isso ocorre pois o host responderá uma requisição ARP pelas duas interfaces de rede."
Mas isso só irá acontecer se a máquina possuir as 2 interfaces com o mesmo IP (como você demonstra com o arping).
Desculpe, mas não entendi muito bem onde você quis chegar com seu artigo.
Salvo alguns casos especiais onde duas interfaces possuem o mesmo IP, imagino que não esteja correto que mais do que uma interface possua o mesmo endereço de rede.
Sem interfaces com o mesmo endereço não consigo enxergar os problemas citados po
r você.
Obrigado,
Kon
Caro Kon,
ResponderExcluirTalvez a frase "duas ou mais interfaces de rede conectadas a um mesmo segmento de rede" não esteja muito clara, portanto, vamos às explicações. Quando digo SEGMENTO de rede eu não quero dizer mesma rede (endereçamento de camada 3). Vamos utilizar o exemplo do arping para mostrar isso.
Imagine que exista em uma máquina linux duas interfaces: eth0 com endereço IP 10.10.20.67 e uma interface eth1 com endereço 200.122.122.2 e, ainda, por algum motivo estas duas interfaces estão conectadas em um mesmo switch - utilizando a mesma vlan. Neste cenário as duas interfaces estão conectadas à um mesmo domínio de broadcast (camada 2).
Se um outro host da rede, por exemplo o host 10.10.20.33 disparar um arping (é exatamente isso que acontece no exemplo), as requisições de arp serão recebidas e respondidas pelas duas interfaces - que possuem endereços MAC e IP distintos MAS estão no mesmo domínio de broadcast.
Se ainda não estiver claro, por favor avise para que a gente continue conversando...
Um abraço e obrigado pela pergunta! :-)
Gustavo.
Grande Gustavo!
ResponderExcluirTive a oportunidade e o desafio de ter que resolver um caso de ARP Flux no meu "lab" (sim, agora são mais de 7 Cobalts em casa rsrs).
As soluções que você propõe são válidas pro Kernel 2.2 e 2.4.
O Kernel 2.6 já endereça este assunto diretamente no /etc/sysctl.conf , basta adicionar :
# Deal with arp flux
net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.eth0.arp_ignore=1
net.ipv4.conf.eth1.arp_ignore=1
net.ipv4.conf.all.arp_announce=2
net.ipv4.conf.eth0.arp_announce=2
net.ipv4.conf.eth1.arp_announce=2
Um forte abraço!
SAULO BRITTO
Ah, um detalhe importante (provavelmente sou eu que estou fazendo ~lamba~):
ResponderExcluir- Isso funciona muito bem, mas o linux aparentente "elege" uma das interfaces como a principal do sistema. No meu caso, foi a eth0.
(A eth1 está desconectada e a eth2 é a 2a NIC com mesma subnet)
Até ai, confirmei que cada interface está respondendo pelo seu IP independente, maaaas... se você por exemplo retira o cabo da que subiu primeiro (no meu caso a eth0), automaticamente a eth2 deixa de responder.
Isso só se resolve se você entrar na máquina e der um ifconfig eth0 down !
Gustavo, onde estou errando? :-S
Abrcs!
SAULO GUÉGS
Hmmm!
ResponderExcluirA tabela de roteamento me respondeu!!!
[root@vendetta2 ~]# netstat -anr
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth2
169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth2
0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0
Quem me responde como Default gateway? A eth0! ou seja, ela é o "caminho de volta", sempre!
Logo, se ela está link down, por onde os pacotes vão voltar? Só desablitando mesmo (ifconfig eth0 down) pra tabela de roteamento passar a usar a eth2!
Para isso, só achei uma saída, usar o "Policy Routing" e o iproute2...
Com os comandos abaixo:
ip route add 192.168.1.0/24 dev eth2 src 192.168.1.250 table admin
ip route add default via 192.168.1.1 dev eth2 table admin
ip rule add from 192.168.1.250/32 table admin
ip rule add to 192.168.1.250/32 table admin
ip route flush cache
Criei a regra que eu precisava pra eth2!
[root@vendetta2 ~]# ip rule show
0: from all lookup local
32764: from all to 192.168.1.250 lookup admin
32765: from 192.168.1.250 lookup admin
32766: from all lookup main
32767: from all lookup default
[root@vendetta2 ~]#
Assim meu amigo, acho que resolvi a encrenca... posso puxar qualquer cabo agora, que cada IP, mesmo da mesma subrede, e ligados num switch "porco" como o meu, vão continuar funcionando independentemente!
Abrcs, mande notícias "primo"!!!
Saulo