Linux 如何捕获每个 PID 的网络数据包?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7842533/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I capture network packets per PID?
提问by Adam Monsen
Anyone know an easy way to ask Linux to "display every internet packet to/from google chrome" or "display every internet packet to/from telnet process with PID 10275"?
任何人都知道一种简单的方法来要求 Linux“显示每个互联网数据包到/来自谷歌浏览器”或“显示每个互联网数据包到/来自 PID 10275 的 telnet 进程”?
The telnet example is not too useful, since I can just use wireshark or tcpdump to see all TCP conversations involving port 23. That and nobody uses telnet anymore. But sniffing all packets to/from complex applications which use many ports seems like a useful thing.
telnet 示例并不是很有用,因为我可以只使用wireshark 或 tcpdump 来查看所有涉及端口 23 的 TCP 对话。这样就没有人再使用 telnet 了。但是从使用许多端口的复杂应用程序中嗅探所有数据包似乎是一件很有用的事情。
I found some related answers exploring different ways to corroborate ports and PIDs (or programs names) and such, but nothing about packets
我找到了一些相关的答案,探索了验证端口和 PID(或程序名称)等的不同方法,但与数据包无关
- How to tie a network connection to a PID without using lsof or netstat?
- How I can get ports associated to the application that opened them?
- How to do like "netstat -p", but faster?
Looks like someone might have been willing to pay for this answer a while back:
看起来有人可能愿意为这个答案买单:
NetHogsis useful for quickly seeing what programs are creating traffic over an interface, but it doesn't have a way to capture packets.
NetHogs可用于快速查看哪些程序正在通过接口创建流量,但它无法捕获数据包。
回答by Shayan Pooya
I would use lsof -i
to get the port numbers associated with the application I want.
The code would be like this:
我会lsof -i
用来获取与我想要的应用程序关联的端口号。代码如下:
process=firefox for _port in `lsof -i | grep $process | cut -d' ' -f18 | cut -d: -f2 | cut -d'-' -f1` do port=$_port [[ "$_port" == +([a-zA-Z]) ]] && port=`cat /etc/services | grep '^$_port' | cut -d' ' -f12 | cut -d'/' -f1 | uniq | head -n 1` echo "tcpdump -w ${port}.pcap port $port &" tcpdump -w ${port}.pcap port $port & done
Note that the output of the commands might be different on different versions/distributions. Therefore, you'd better check the right fileds are cut before using the script.
请注意,命令的输出在不同的版本/发行版上可能会有所不同。因此,您最好在使用脚本之前检查正确的文件是否被剪切。
Also, this script does not monitor the ports that are opened later. For that, I would consider a more complicated script that checks ports regularly (using something like watch
)
此外,此脚本不会监视稍后打开的端口。为此,我会考虑一个更复杂的脚本来定期检查端口(使用类似的东西watch
)
And remember to kill all of the tcpdump processes afterwards.
并记住之后杀死所有 tcpdump 进程。
回答by JoeriBe
Tcpdump can tell you the PID/process a packet comes from/to.
Throw '-k NP' in your options.
Tcpdump 可以告诉您数据包来自/到达的 PID/进程。
在您的选项中加入“-k NP”。
Version supported: tcpdump version 4.3.0 -- Apple version 56
支持的版本:tcpdump 版本 4.3.0 -- Apple 版本 56
回答by Greg Bray
In my case I wanted to capture syslog traffic but only from rsyslog. It only had one listening port under lsof -p $(pidof rsyslog)
and always used that as the source port, so I was able to get the packets using:
就我而言,我想捕获 syslog 流量,但仅从 rsyslog 中捕获。它下面只有一个侦听端口,lsof -p $(pidof rsyslog)
并且始终将其用作源端口,因此我能够使用以下方法获取数据包:
tcpdump -i eth0 -A "host 10.0.0.100 and dst port 514 and src port $(lsof -i 4 -a -p `pidof rsyslogd` | grep -Po '(?<=\*:)[0-9]*') and udp"
The grep uses a positive lookbehind assertionto turn the *:portnumber into just the port number.
该grep的使用正向后断言打开*:端口号逼到端口号。
回答by higuita
Not directly a tcpdump, but can give you info about the network traffic, check https://bytefreaks.net/gnulinux/how-to-capture-all-network-traffic-of-a-single-process
不是直接的 tcpdump,但可以为您提供有关网络流量的信息,请查看https://bytefreaks.net/gnulinux/how-to-capture-all-network-traffic-of-a-single-process
strace -f -e trace=network -s 10000 <PROCESS WITH ARGUMENTS>;
If the process is already started and you know its PID you can use the following 1
如果该进程已经启动并且您知道其 PID,则可以使用以下 1
strace -f -e trace=network -s 10000 -p <PID>;
Another alternative is more complex, using network namespaces, check the above link or use the tool nsntrace, but either can only work on new process, you can not change existent process network namespaces (AFAIK)
另一种选择更复杂,使用网络命名空间,检查上面的链接或使用工具nsntrace,但要么只能在新进程上工作,你不能改变现有的进程网络命名空间(AFAIK)