Criando junção multicast para capturas de tcpdump

11

Eu quero escrever um script de shell linux que irá capturar o tráfego multicast específico. Específico como em, quero criar um arquivo pcap que tenha todo o tráfego para um grupo / porta multicast específico.

Aqui está a linha de comando que estou usando para visualizar o tráfego:

tcpdump -nnXs 0 -i eth1 udp port 22001 and dst 233.54.12.234

Isso funciona bem desde que eu tenha uma assinatura multicast para esse grupo já estabelecido. Por exemplo, se eu executar isso em outro console:

mdump 233.54.12.234 22001 10.13.252.51

tcpdumpverá pacotes. Se mdumpnão estiver em execução, tcpdumpnão vê nada.

Existe uma maneira linux-y padrão para estabelecer essas junções multicast antes de iniciar as capturas? Eu poderia usar mdumppara estabelecer essas junções, mas isso parece um desperdício, já mdumpque processará todos os dados do grupo, mas eu apenas vou jogá-los fora.

Observe que, devido ao meu ambiente específico, fui desencorajado de colocar a interface no modo promíscuo. De fato, pode ser proibido.

John Dibling
fonte
1
A menos que você estiver executando uma versão não-padrão de tcpdump, você está colocando a interface em modo promíscuo - a -pbandeira, em versões padrão do tcpdump, transforma o modo promíscuo off , como é on por padrão. No modo promíscuo, ele deve ver todo o tráfego, incluindo o tráfego multicast, independentemente de você ter a assinatura estabelecida - a menos que você esteja em uma rede comutada e seja necessário que a assinatura seja estabelecida para que o comutador encaminhe o tráfego.
1
@GuyHarris: Obrigado pelo esclarecimento. Estou em uma rede comutada. Sem a assinatura já estabelecida (ou seja, com a mdumpexecução em outro console), tcpdumpnão vê nada.
John Dibling
E se eles não querem que você execute no modo promíscuo, provavelmente também não querem que você (ou nem permita ) configure uma "porta espelhada" no comutador (supondo que o comutador seja compatível com isso) para obter cópias de todo o tráfego através do switch (ou todo o tráfego através de portas específicas, se isso for possível).
Então, o que há de errado em fazer isso com um script? O que importa é se o trabalho é realizado, e não se alguém o considera "da maneira usual" - o que é "incomum" no script?
O modo promíscuo está desabilitado porque a ativação, aparentemente, afetaria as outras VMs no host. Isso é indesejável. I pode configurar uma porta espelhada no interruptor - estes são 40GB aristas - mas eu não tenho certeza que eu vejo o seu ponto.
John Dibling

Respostas:

5

TL; DR - Escolha um:

sudo ip addr add 233.54.12.234/32 dev eth1 autojoin

socat STDIO UDP4-RECV:22001,ip-add-membership=233.54.12.234:eth1 > /dev/null


No começo eu dizia "apenas use ip maddress adde termine com isso". O problema ip maddressafeta apenas os endereços multicast da camada de link e não os endereços multicast do protocolo ( man 8 ip-maddress).

Dito isto, usar a autojoinbandeira com o verbo endereço faz o truque muito bem.

Isso levanta algumas questões subsequentes. Presumo que você estará executando tcpdumpou tsharkque tenha permissão de root. No caso de você não ter 22001, é uma porta com numeração alta e outros utilitários como socattambém farão as coisas.

Mas não aceite minha palavra. Apenas para testar isso, podemos gerar pacotes UDP multicast com socatou ncat(geralmente empacotados via nmap/ nmap-ncat).

Em algum número de hosts, execute uma das duas combinações a seguir:

Opção 1:

sudo ip addr add 233.54.12.234/32 dev eth1 autojoin

Opção 2:

socat -u UDP4-RECV:22001,ip-add-membership=233.54.12.234:eth1 /dev/null &

A primeira opção exigirá raiz ou pelo menos a capacidade CAP_NET_ADMIN . A segunda opção não requer raiz, mas também espera ser executada em primeiro plano e, portanto, pode ser menos propícia a scripts (embora rastrear o ID do processo filho e limpá-lo com um trapBASH possa ser exatamente o que você está procurando.

Uma vez feito isso (mas antes de enlouquecermos testando nosso tcpdump/ tsharkcomando), verifique se o kernel reconhece a interface que ingressou no grupo IGMP correto. Se você está se sentindo super extravagante, pode enlouquecer ao analisar o feitiço /proc/net/igmp, mas eu sugiro apenas correr netstat -gn.

Depois de verificar se você vê a interface inscrita no grupo correto, inicie o comando tcpdump:

tcpdump -nnXs 0 -i eth1 udp port 22001 and dst 233.54.12.234

Como alternativa, se você não quiser seguir completamente a rota do tcpdump (ou se deparou com essa resposta e está curioso para ver a difusão seletiva em ação), use o socatcomando acima para ingressar e ecoar o conteúdo STDOUTsubstituindo /dev/nullpor STDOUT:

socat -u UDP4-RECV:22001,ip-add-membership=233.54.12.234:eth1

Em outra máquina, use uma das duas opções a seguir para enviar alguns dados de teste simples:

Opção 1:

socat STDIO UDP-DATAGRAM:233.54.12.234:22001

Opção 2:

ncat  -u 233.54.12.234 22001

Quando você executa um desses comandos, ele espera interativamente a entrada. Basta digitar algumas coisas, pressionar enter para enviar e CTRL+Dquando terminar de enviar uma EOFmensagem.

Nesse ponto, você deveria ter visto um teste de ponta a ponta e com alguns comandos criados o pior e mais inseguro sistema de bate-papo do mundo.

Brian Redbeard
fonte
1
Uau, demorou 4 anos para obter uma resposta! Eu nem estou mais fazendo isso e realmente não tenho como testar, mas aceitarei mesmo assim.
John Dibling 08/09
1
Vem a calhar agora mesmo! : D Graças Brian :)
quaylar