Como capturar tráfego em interfaces virtuais?

12

Eu gostaria de capturar o tráfego nas interfaces virtuais do Linux, para fins de depuração. Tenho feito experiências com veth, tune dummyinterface de tipos; nos três, estou tendo problemas tcpdumppara mostrar qualquer coisa.

Aqui está como eu configuro a interface fictícia:

ip link add dummy10 type dummy
ip addr add 99.99.99.1 dev dummy10
ip link set dummy10 up

Em um terminal, assista-o com tcpdump:

tcpdump -i dummy10

Em um segundo, ouça com nc:

nc -l 99.99.99.1 2048

Em um terceiro, faça uma solicitação HTTP com curl:

curl http://99.99.99.1:2048/

Embora no terminal 2 possamos ver os dados da curlsolicitação, nada aparece tcpdump.

Um tutorial Tun / Tap esclarece algumas situações em que o kernel pode realmente não enviar pacotes quando um está operando em uma interface local:

Olhando para a saída do tshark, não vemos ... nada. Não há tráfego passando pela interface. Isso está correto: como estamos executando o ping do endereço IP da interface, o sistema operacional decide corretamente que nenhum pacote precisa ser enviado "on the wire" e o próprio kernel está respondendo a esses pings. Se você pensar bem, é exatamente o que aconteceria se você pingasse o endereço IP de outra interface (por exemplo, eth0): nenhum pacote seria enviado. Isso pode parecer óbvio, mas pode ser uma fonte de confusão a princípio (era para mim).

No entanto, é difícil ver como isso pode se aplicar aos pacotes de dados TCP.

Talvez tcpdumpdeva estar vinculado à interface de uma maneira diferente?

solidsnack
fonte
Não sei por que é difícil ver isso acontecendo nos pacotes TCP. Como pings, esses são processados ​​no kernel. A mesma coisa está acontecendo.
Derobert
@derobert No caso de pings, o kernel pode responder. No caso de pacotes de dados, imaginei que eles teriam que "passar" pela interface para que o aplicativo pudesse responder a eles.
Solidsnack #
1
Os aplicativos falam com o kernel usando leitura, gravação etc. Muitos aplicativos de rede nem precisam estar cientes de que existem interfaces. Para que o tráfego passe por um deles, o kernel precisa vê-lo como não local. Por exemplo, configure um túnel OpenVPN, para capturar o tráfego passando por tun0. (Claro, tun0 é uma maneira especial para aplicativos para falar com o kernel, para implementar uma interface de rede em userland, que é o OpenVPN faz.)
derobert

Respostas:

8

O tráfego está passando pela lointerface.

Quando um IP é adicionado a uma caixa, uma rota para esse endereço é adicionada à tabela 'local'. Todas as rotas nesta tabela direcionam o tráfego pela interface de loopback.

Você pode visualizar o conteúdo da tabela 'local' com o seguinte:

ip route show table local

Que no meu sistema se parece com isso:

local 10.230.134.38 dev tun0  proto kernel  scope host  src 10.230.134.38 
broadcast 10.230.134.38 dev tun0  proto kernel  scope link  src 10.230.134.38 
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 172.17.0.0 dev docker0  proto kernel  scope link  src 172.17.42.1 
local 172.17.42.1 dev docker0  proto kernel  scope host  src 172.17.42.1 
broadcast 172.17.255.255 dev docker0  proto kernel  scope link  src 172.17.42.1 
broadcast 192.168.0.0 dev enp6s0  proto kernel  scope link  src 192.168.0.20 
local 192.168.0.20 dev enp6s0  proto kernel  scope host  src 192.168.0.20 
broadcast 192.168.0.255 dev enp6s0  proto kernel  scope link  src 192.168.0.20 

Então, basicamente, se eu enviar qualquer tráfego para 10.230.134.38, 127.0.0.0/8, 127.0.0.1(redundante) , 172.17.42.1ou 192.168.0.20, o tráfego vai ser encaminhadas através da interface de auto-retorno, mesmo que esses IPs são realmente em uma interface diferente.

Patrick
fonte
1

Você pode usar tcpdumpcom qualquer interface no host ( tcpdump -i any ...)

Charles nakhel
fonte
0

Isso deve ser possível invocando um segundo sistema (pode até ser uma VM nesse host).

Você pode usar DNATna OUTGOINGcadeia da nattabela e redirecionar os pacotes para uma interface que o kernel não controla. Você precisa refleti-los lá:

iptables -t nat -A OUTPUT -p tcp -d 99.99.99.1 --dport 2048 \
  -j DNAT --to-destination 1.2.3.4
Hauke ​​Laging
fonte