我想编写一个 Linux shell 脚本来捕获特定的多播流量。具体如下,我想创建一个 pcap 文件,其中包含一个特定多播组/端口的所有流量。
这是我用来查看流量的命令行:
tcpdump -nnXs 0 -i eth1 udp port 22001 and dst 233.54.12.234
只要我已经建立了对该组的多播订阅,这就可以正常工作。例如,如果我在另一个控制台中运行此命令:
mdump 233.54.12.234 22001 10.13.252.51
tcpdump
将看到数据包。如果mdump
没有运行,则tcpdump
什么也看不到。
在开始捕获之前是否有标准的 linux-y 方法来建立这些多播连接?我可以用来mdump
建立这些连接,但这似乎很浪费,因为mdump
将处理组上的所有数据,但我只是将其丢弃。
请注意,由于我的特定环境,我不鼓励将接口置于混杂模式。事实上,它可能会被禁止。
答案1
TL;DR - 选择一项:
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
起初我想说“只要使用ip maddress add
它就可以了”。问题ip maddress
只是影响链路层多播地址不协议多播地址(man 8 ip-maddress
)。
话虽这么说,使用autojoin
带有地址动词就可以很好地发挥作用。
但这引发了一些后续问题。我假设您将运行tcpdump
或者tshark
您拥有 root 权限。 如果您不这样做22001 是一个高编号端口,其他实用程序(例如)socat
也可以完成任务。
不过,请不要相信我的话。为了测试这一点,我们可以使用socat
或生成多播 UDP 数据包ncat
(通常通过nmap
/打包nmap-ncat
)。
在一定数量的主机上运行一以下两种组合:
选项1:
sudo ip addr add 233.54.12.234/32 dev eth1 autojoin
选项2:
socat -u UDP4-RECV:22001,ip-add-membership=233.54.12.234:eth1 /dev/null &
第一个选项需要 root,或者至少需要 root能力 CAP_NET_ADMIN
。第二个选项不需要 root,但也期望在前台运行,因此可能不太有利于脚本编写(尽管跟踪子进程 ID 并使用trap
in BASH 可能正是您正在寻找的。
一旦完成(但在我们疯狂测试tcpdump
/tshark
命令之前),请确保内核识别出已加入正确 IGMP 组的接口。如果你感觉超级喜欢,你可以疯狂地解析十六进制/proc/net/igmp
,但我建议只是运行netstat -gn
。
一旦您确认看到订阅了正确组的接口,即可启动 tcpdump 命令:
tcpdump -nnXs 0 -i eth1 udp port 22001 and dst 233.54.12.234
或者,如果您不想完全走 tcpdump 的路线(或者偶然发现这个答案并且只是想看看多播的实际情况),您可以使用socat
上面的命令来加入并回显内容,STDOUT
方法是替换/dev/null
为STDOUT
:
socat -u UDP4-RECV:22001,ip-add-membership=233.54.12.234:eth1
然后,从另一台机器使用以下两个选项之一发送一些简单的测试数据:
选项1:
socat STDIO UDP-DATAGRAM:233.54.12.234:22001
选项2:
ncat -u 233.54.12.234 22001
当您运行这些命令中的任何一个时,它将以交互方式等待输入。只需输入一些内容,按 Enter 键即可发送,CTRL+D
完成后即可发送EOF
消息。
此时,您应该已经看到了端到端测试,并使用一些命令构建了世界上最糟糕、最不安全的聊天系统。
注意:如果您想离开使用ip addr add ...
(选项 1)加入的多播组,您可以执行以下操作:
sudo ip addr del 233.54.12.234/32 dev eth1 autojoin