Por que os pacotes recebidos em uma interface TAP são vistos com o tcpdump, mas não com o iptables?

7

Um programa injeta pacotes em uma interface Linux TAP (esses pacotes são provenientes de uma máquina virtual) . Especificamente, essas são solicitações DHCP (portanto, elas são UDP). Eu posso ver os pacotes com tcpdump , mas não com iptables , e eles não alcançam o servidor DHCP local também. Por que não, e como conserto isso?

Atualização : tentei injetar pacotes IP direcionados ao endereço da interface tap0 . Vejo as solicitações ARP vindas da VM em tcpdump -i tap0 , mas a camada de rede não responde. Se eu enviar solicitações ARP para a VM, ele as verá e responderá ao host (e as respostas serão exibidas em tcpdump , mas serão perdidas).

Outra observação: ifconfig tap0 mostra que a contagem de pacotes perdidos de TX é incrementada para cada pacote que é injetado no host. Por que TX?

# ifconfig tap0
…
          TX packets:0 errors:0 dropped:958 overruns:0 carrier:0
          collisions:0 txqueuelen:500
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

A longa história: Em um host Linux (executando o Ubuntu 10.04), estou executando uma máquina virtual que, entre outras coisas, emula uma placa Ethernet. Ele faz isso comunicando-se com um programa auxiliar encarregado de injetar e capturar pacotes Ethernet na pilha de rede do host. A máquina virtual é um emulador de chip ARM e o programa auxiliar é chamado nicserver ; tudo o que sei sobre isso é o que é encontrado na documentação do ARM .

Eu quero estabelecer um link Ethernet entre a VM e o host e, acima disso, eu quero um link IP. A VM obtém seu endereço IP pelo DHCP. Eu não quero nenhuma comunicação entre a VM e o resto do mundo, apenas com o host, então criei uma interface de rede virtual tap0 com

tunctl -u gilles
ifconfig tap0 192.168.56.1 netmask 255.255.255.0 up
nicserver -p 7801 -a tap0 &

Agora eu inicializo a VM, e posso ver que está enviando solicitações DHCP com tcpdump -n -i tap0 -vv (o cliente DHCP não expira, estou mostrando apenas uma solicitação de amostra aqui):

tcpdump: listening on tap0, link-type EN10MB (Ethernet), capture size 96 bytes
18:29:23.941574 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 576)
    0.0.0.0.68 > 255.255.255.255.67: [no cksum] BOOTP/DHCP, Request from 02:52:56:47:50:03, length 548, xid 0x238a7979, secs 46, Flags [none] (0x0000)
          Client-Ethernet-Address 02:52:56:47:50:03 [|bootp]

Eu configurei o Dnsmasq no host para atender às solicitações, mas não está vendo nenhuma solicitação recebida. O servidor Dnsmasq nem sequer vê as requisições recebidas (eu as chamei). Então eu tentei observar os pacotes com o Iptables. (Todas as regras do filtro / INPUT são mostradas; não há regras mangle ou nat).

Chain INPUT (policy ACCEPT 2366K packets, 5334M bytes)
 pkts bytes target     prot opt in     out     source               destination 
  119 39176 LOG        udp  --  *      *       0.0.0.0/0            0.0.0.0/0           udp dpt:67 LOG flags 4 level 4 prefix '[DHCP request] '
  119 39176 DROP       udp  --  eth1   *       0.0.0.0/0            0.0.0.0/0           udp dpt:67
    2   490 LOG        udp  --  tap0   *       0.0.0.0/0            0.0.0.0/0           LOG flags 4 level 4 prefix '[in=tap0] '
   26  6370 ACCEPT     udp  --  tap0   *       0.0.0.0/0            0.0.0.0/0   
    0     0 ACCEPT     all  --  tap0   *       0.0.0.0/0            0.0.0.0/0   
 3864  457K ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0   

Todas essas solicitações DHCP recebidas estão em eth1 (e eu tenho cuidado para não ignorar essas para não irritar meus colegas e meu administrador de rede). Esses pacotes UDP em tap0 vêm do servidor Samba local. Os pacotes de requisição DHCP que eu vejo com o tcpdump não parecem passar pelo filtro de pacotes!

Por que vejo pacotes de transmissão de entrada em tap0 com tcpdump , mas não com iptables (nem com programas ouvindo na máquina)? E o que preciso corrigir para que esses pacotes sejam vistos, como seriam se estivessem vindo em uma interface Ethernet?

    
por Gilles 08.11.2011 / 19:01

1 resposta

1

Aqui está mais adivinhação. Espero que isso seja útil, mas também pode ser um envergonho errado.

tap0 tem duas extremidades, a extremidade da pilha da rede do kernel e a interface do programa. Parece-me que se você fornecer 'nicserver' com tap0, ele não será anexado a ele da maneira pretendida com dispositivos de toque, usando a interface do programa. Em vez disso, o nicserver simplesmente gravará nele a partir do final da pilha de rede e, sem nenhuma leitura do aplicativo no final da interface do programa, você acabará transbordando na fila de dispositivos. Isso explica os pacotes descartados. Além disso, nenhum pacote será entregue, o que pode explicar o resultado do iptables.

Eu acho que se você deixar a captura do tcpdump no tap0, ela realmente será conectada ao final da interface do programa do tap0 e, voila, você verá os pacotes. Eu procurei na internet, mas não encontrei nenhuma fonte para confirmar esse comportamento. Para falsificar essa teoria, capture tap0 e veja como isso afeta o drop de pacotes e o log do iptables.

Por fim, um conselho que solucione seu problema original: que tal usar o dispositivo de loopback? Assim:

nicserver -p 7801 -a lo
    
por 16.11.2011 / 00:13