O Linux não responde às mensagens de pedido ARP se o endereço IP solicitado estiver associado a outra interface (desativada)

6

Eu tenho um PC (kernel 3.2.0-23-generic ) que tem 192.168.1.2/24 configurado para eth0 interface e também usa 192.168.1.1 e 192.168.1.2 endereços para tun0 interface:

root@T42:~# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:16:41:54:01:93 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.2/24 scope global eth0
    inet6 fe80::216:41ff:fe54:193/64 scope link
       valid_lft forever preferred_lft forever
3: bond0: <BROADCAST,MULTICAST,MASTER> mtu 1500 qdisc noop state DOWN
    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
4: irda0: <NOARP> mtu 2048 qdisc noop state DOWN qlen 8
    link/irda 00:00:00:00 brd ff:ff:ff:ff
5: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:13:ce:8b:99:3e brd ff:ff:ff:ff:ff:ff
    inet 10.30.51.53/24 brd 10.30.51.255 scope global eth1
    inet6 fe80::213:ceff:fe8b:993e/64 scope link
       valid_lft forever preferred_lft forever
6: tun0: <POINTOPOINT,MULTICAST,NOARP> mtu 1500 qdisc pfifo_fast state DOWN qlen 100
    link/none
    inet 192.168.1.1 peer 192.168.1.2/32 scope global tun0
root@T42:~# ip route show dev eth0
192.168.1.0/24  proto kernel  scope link  src 192.168.1.2 
root@T42:~# 

Como visto acima, tun0 está desativado administrativamente ( ip link set dev tun0 down ). Agora, quando recebo solicitações de ARP para 192.168.1.2 , o PC não responde a essas solicitações:

root@T42:~# tcpdump -nei eth0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
15:30:34.875427 00:1a:e2:ae:cb:b7 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 60: Request who-has 192.168.1.2 tell 192.168.1.1, length 46
15:30:36.875268 00:1a:e2:ae:cb:b7 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 60: Request who-has 192.168.1.2 tell 192.168.1.1, length 46
15:30:39.138651 00:1a:e2:ae:cb:b7 > 00:1a:e2:ae:cb:b7, ethertype Loopback (0x9000), length 60:
^C
3 packets captured
3 packets received by filter
0 packets dropped by kernel
root@T42:~#

Somente depois de excluir a interface tun0 ( ip link del dev tun0 ), o PC responderá à solicitação ARP para 192.168.1.2 on eth0 interface.

A tabela de roteamento parece exatamente igual antes e depois de ip link del dev tun0 :

root@T42:~# netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         10.30.51.254    0.0.0.0         UG        0 0          0 eth1
10.30.51.0      0.0.0.0         255.255.255.0   U         0 0          0 eth1
192.168.1.0     192.168.1.2     255.255.255.0   UG        0 0          0 eth0
root@T42:~# ip link del dev tun0
root@T42:~# netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         10.30.51.254    0.0.0.0         UG        0 0          0 eth1
10.30.51.0      0.0.0.0         255.255.255.0   U         0 0          0 eth1
192.168.1.0     192.168.1.2     255.255.255.0   UG        0 0          0 eth0
root@T42:~# 

A entrada de roteamento abaixo já foi removida com o comando ip link set dev tun0 down :

Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
192.168.1.2     0.0.0.0         255.255.255.255 UH        0 0          0 tun0

No entanto, embora as tabelas de roteamento sejam exatamente iguais antes e depois do comando ip link del dev tun0 , o kernel real das decisões de roteamento não será:

T42:~# ip route get 192.168.1.1
local 192.168.1.1 dev lo  src 192.168.1.1 
    cache <local> 
T42:~# ip link del dev tun0
T42:~# ip route get 192.168.1.1
192.168.1.1 dev eth0  src 192.168.1.2 
    cache  ipid 0x8390
T42:~# 

Este é um comportamento esperado? Por que o kernel ignora a tabela de roteamento?

    
por Martin 26.05.2015 / 17:36

2 respostas

9

Sua tabela de roteamento não está sendo ignorada, exatamente. Está sendo anulada por uma tabela de roteamento de prioridade mais alta.

O que está acontecendo

A tabela de roteamento que você vê quando digita ip route show não é a única tabela de roteamento usada pelo kernel. Na verdade, há três tabelas de roteamento por padrão e elas são pesquisadas na ordem mostrada pelo comando ip rule :

# ip rule show
0:      from all lookup local
32766:  from all lookup main
32767:  from all lookup default

A tabela com a qual você está mais familiarizado é main , mas a tabela de roteamento de maior prioridade é local . Esta tabela é gerenciada pelo kernel para rastrear rotas locais e de broadcast: em outras palavras, a tabela local informa ao kernel como rotear para os endereços de suas próprias interfaces. Parece algo assim:

# ip route show table local
broadcast 127.0.0.0 dev lo  proto kernel  scope link  src 127.0.0.1
local 127.0.0.0/8 dev lo  proto kernel  scope host  src 127.0.0.1
local 127.0.0.1 dev lo  proto kernel  scope host  src 127.0.0.1
broadcast 127.255.255.255 dev lo  proto kernel  scope link  src 127.0.0.1
broadcast 192.168.1.0 dev eth0  proto kernel  scope link  src 192.168.1.2
local 192.168.1.1 dev tun0  proto kernel  scope host  src 192.168.1.1
local 192.168.1.2 dev eth0  proto kernel  scope host  src 192.168.1.2
broadcast 192.168.1.255 dev eth0  proto kernel  scope link  src 192.168.1.2

Confira essa linha fazendo referência a tun0 . Isso é o que está causando seus resultados estranhos de route get . Ele diz que 192.168.1.1 é um endereço local, o que significa que, se quisermos enviar uma resposta ARP para 192.168.1.1, é fácil; nós enviamos para nós mesmos. E como encontramos uma rota na tabela local , paramos de procurar uma rota e não nos preocupamos em verificar as tabelas main ou default .

Por que várias tabelas?

No mínimo, é bom poder digitar ip route e não ver todas essas rotas "óbvias" atravancando a exibição (tente digitar route print em uma máquina Windows). Ele também pode servir como proteção mínima contra configuração incorreta: mesmo se a tabela de roteamento principal estiver confusa, o kernel ainda sabe como falar consigo mesmo.

(Por que manter as rotas locais em primeiro lugar? Assim, o kernel pode usar o mesmo código de pesquisa para endereços locais, como faz para todo o resto. Isso torna as coisas mais simples internamente.)

Existem outras coisas interessantes que você pode fazer com este esquema de múltiplas tabelas. Em particular, você pode adicionar suas próprias tabelas e especificar regras para quando elas forem pesquisadas. Isso é chamado de "roteamento de políticas", e se você já quis rotear um pacote com base no seu endereço source , é assim que é feito no Linux.

Se você estiver fazendo coisas especialmente complicadas ou experimentais, adicione ou remova local de rotas, especificando table local no comando ip route . A menos que você saiba o que está fazendo, é provável que confunda o kernel. E, claro, o kernel ainda continuará adicionando e removendo suas próprias rotas, então você tem que assistir para ter certeza que o seu não seja sobrescrito.

Finalmente, se você quiser ver todas as tabelas de roteamento de uma só vez:

# ip route show table all

Para mais informações, confira a página do manual ip-rule(8) ou os iproute2 docs . Você também pode tentar o HOWTO de controle avançado de tráfego e roteamento para obter alguns exemplos do que você pode fazer.

    
por 04.06.2015 / 10:09
1

Sua configuração caminho reverso de filtragem provavelmente é o problema. RFC3704 - seção 2.4

Em distribuições do Enterprise Linux (RHEL, CentOS, Scientific Linux, e outros), a melhor maneira de resolver isso é modificar /etc/sysctl.conf com rp_filter = 2

link

    
por 03.06.2015 / 01:08