如何捕获单个进程的网络流量?


92

我想检查由单个进程处理的网络流量,但是由于我正在处理如此繁忙的系统(许多其他流量同时发生),因此无法进行简单的网络捕获。有没有一种方法可以将单个特定进程的网络通信隔离tcpdumpwireshark捕获?(使用netstat不足。)

Answers:


21

确实,有一种使用Wireshark过滤器的方法。但是您不能直接按进程名称或PID进行过滤(因为它们不是网络数量)。

您应该首先弄清进程使用的协议和端口(上一条注释中的netstat命令运行良好)。

然后使用Wireshark使用刚检索的端口过滤入站(或出站)端口。那应该隔离您的过程的传入和传出流量。


6
对于一个简单的连接,这是可能的,但是我需要跟踪所有涌入的DNS,HTTP等,因此没有一种简单的方法可以netstat在繁忙的机器上使用和简单的网络捕获过滤器。
Kees Cook

好的,许多应用程序都使用HTTP和DNS公共端口,但是相应的专用端口是唯一的。那么,为什么不尝试按专用端口进行过滤呢?
OpenNingia 2010年

因为快速的小请求不会被看到netstat; 我将只能抓住长期存在的联系。:(
Kees Cook

如果进程在运行时使用动态端口怎么办,那么您将无法使用静态端口过滤器
Unix Janitor 2010年

我认为您在这里是最好的答案...遗憾的是,网络嗅探工具在网络堆栈的最低级别运行,试图捕获所有内容,但它完全没有意识到OS上正在运行的进程。要找出某个呼叫的起源是非常困难的。数据包嗅探器最终可能(通过端口号)找出进程ID,但由于完全独立(因此很可能触发了调用的内核网络堆栈),因此无法找出哪个DNS查找了进程。但是通过过滤和停止其他进程,您应该能够实现自己的目标。
惠更斯地区2010年

134

要启动和监视新过程:

strace -f -e trace=network -s 10000 PROCESS ARGUMENTS

要监视具有已知PID的现有过程:

strace -p $PID -f -e trace=network -s 10000
  • -f 用于“遵循新流程”
  • -e 定义一个过滤器
  • -s 将字符串的限制设置为大于32
  • -p 需要附加的进程ID

2
这很有用,因为可以在没有root访问权限或特殊权限的情况下使用它(无论如何,在某些Linux发行版上-在Ubuntu上,您可能需要特殊权限)。
罗宾·格林

1
这也很有用,因为它可以针对已经启动的进程运行,并且几乎可以在任何Linux机器上使用。
zakmck

53

我知道这个线程有点旧,但是我认为这可能对某些人有帮助:

如果您的内核允许,通过在一个隔离的网络名称空间中运行该进程并在该名称空间中也使用wireshark(或其他标准联网工具)来捕获单个进程的网络流量非常容易。

设置可能看起来有些复杂,但是一旦您了解并熟悉了它,它将大大简化您的工作。

这样做:

  • 创建一个测试网络名称空间:

    ip netns add test
    
  • 创建一对虚拟网络接口(veth-a和veth-b):

    ip link add veth-a type veth peer name veth-b
    
  • 更改veth-a接口的活动名称空间:

    ip link set veth-a netns test
    
  • 配置虚拟接口的IP地址:

    ip netns exec test ifconfig veth-a up 192.168.163.1 netmask 255.255.255.0
    ifconfig veth-b up 192.168.163.254 netmask 255.255.255.0
    
  • 在测试名称空间中配置路由:

    ip netns exec test route add default gw 192.168.163.254 dev veth-a
    
  • 激活ip_forward并建立NAT规则以转发来自您创建的名称空间的流量(您必须调整网络接口和SNAT ip地址):

    echo 1 > /proc/sys/net/ipv4/ip_forward
    iptables -t nat -A POSTROUTING -s 192.168.163.0/24 -o <your internet interface, e.g. eth0> -j SNAT --to-source <your ip address>
    

    (如果愿意,还可以使用MASQUERADE规则)

  • 最后,您可以在新的名称空间中运行要分析的过程,也可以使用wireshark:

    ip netns exec test thebinarytotest
    ip netns exec test wireshark
    

    您必须监视veth-a界面。


4
好主意,但要提防“局限性”。由于这是一个单独的名称空间,因此您无法使用环回地址或UNIX域套接字与默认名称空间中的本地进程进行通信。后者影响通过D-Bus的通信。
Lekensteyn

@Lekensteyn,您仍然可以跨网络名称空间afaik使用Unix域套接字。文件系统没有被它们隔离。
randunel '16

1
@randunel我应该对此更精确。我的意思是说,“抽象套接字名称空间”(不使用文件系统)中的Unix域套接字不能在网络名称空间之间直接访问。解决方法是,您可以使用代理,例如socat
Lekensteyn '16

您将哪个IP地址与--to-source参数一起使用iptables?这是您传递给该-o选件的接口的IP地址,您组成的IP地址还是??? 我想,不需要伪装版本--to-source如这里所描述,那工作!
ntc2'2

3
所有这些似乎都需要root访问。
simplegamer

15
netstat -taucp | grep <pid or process name>

这将显示应用程序正在建立的连接,包括正在使用的端口。


8
这将显示该瞬间存在的连接,但不会提供流量本身的日志。
Kees Cook

1
不确定Kees Cook的评论。一个简单的netstat可以立即显示有关连接的信息,但是使用标志-c可以每秒获取该状态的快照(请参阅“ man netstat”)。也许它没有全部流量,但不是连接的唯一快照。
tremendows

3
好吧,我确定。这不会捕获进程的所有网络流量。
Reinier Post

这对于确定哪个端口号被内部防火墙阻止很有用。它显示了我正在运行的命令正在发送的TCP SYN(以及目标地址和端口号)。
Anthony Geoghegan

11

只是一个想法:是否可以将您的应用程序绑定到其他IP地址?如果是这样,则可以使用通常的可疑对象(tcpdump等)

用于无法绑定到另一个IP地址的应用程序的工具:

http://freshmeat.net/projects/fixsrcip

fixsrcip是用于将传出的TCP和UDP客户端套接字(IPv4)绑定到多宿主主机上的特定源IP地址的工具

http://freshmeat.net/projects/force_bind

force_bind允许您强制绑定到特定的IP和/或端口。它可与IPv4和IPv6一起使用


大多数应用程序不支持指定其源IP,但是实际上可以通过使用具有CLONE_NEWNET而不是CLONE_NEWNS的容器来实现。
Kees Cook

或者,您可以创建一个网络名称空间,并在其中运行您的应用程序www.evolware.org/?p=293
Flint

9

我得出了一个类似的问题,我能在此基础上整理出这个答案通过的ioerror使用NFLOG所描述的,在这里

# iptables -A OUTPUT -m owner --uid-owner 1000 -j CONNMARK --set-mark 1
# iptables -A INPUT -m connmark --mark 1 -j NFLOG --nflog-group 30 
# iptables -A OUTPUT -m connmark --mark 1 -j NFLOG --nflog-group 30 
# dumpcap -i nflog:30 -w uid-1000.pcap

然后,您可以使用一个不执行任何其他操作的用户帐户来创建正在运行的流程-瞧,您只是从单个流程中隔离并捕获了流量。

只是想发回邮件,以防万一。



5

这是一个肮脏的hack,但我建议使用给定UID的iptables转移目标或日志目标。例如:

iptables -t nat -A OUTPUT -p tcp -m owner --uid-owner $USER -m tcp -j LOG 
iptables -t nat -A OUTPUT -p udp -m owner --uid-owner $USER -m udp -j LOG 

对于该日志目标,可能值得研究类似“ --log-tcp-sequence”,“-log-tcp-options”,“-log-ip-options”,“-log-uid”之类的东西。 。尽管我怀疑这只会帮助您后期处理包含大量其他数据的pcap。

如果要标记数据包,然后某些标记的数据包将通过netlink套接字发送到您选择的进程,则NFLOG目标可能有用。我想知道这对于用wireshark破解某些东西以及您以特定用户身份运行的特定应用程序是否有用?


但这仅适用于传出,传入怎么办?
resultsway

5

您可以尝试使用tracedump- http: //mutrics.iitis.pl/tracedump

它可以完全满足您的要求,您可以给它一个进程ID或要运行的程序。


1
很好的项目,但是...不幸的是,“ Tracedump当前仅在32位Linux主机上运行”对我来说杀死了它。
gertvdijk 2014年

4

尝试在strace下运行您感兴趣的过程:

strace ping www.askubuntu.com

它将为您提供有关流程执行情况的非常详细的信息。由于进程可以将其想要打开的任何端口打开到任何地方,因此使用预定义的筛选器可能会丢失某些内容。

另一种方法是在网络上使用精简虚拟机或测试机,并在此基础上独立放置您的进程。然后,您可以使用Wireshark从该计算机上捕获所有信息。您将非常确定,您捕获的流量将是相关的。


添加“ -e trace = network”会删减某些输出,但会丢失丢失实际写入网络的数据。如果您只关心“已打开的套接字数”或类似的内容,这将使事情变得容易。
dannysauer

3

基于ioerror的答案,我怀疑您可以用来iptables --uid-owner在流量上设置标记,然后可以要求Wireshark仅捕获带有该标记的流量。您可能可以使用DSCP(差异服务标记),流id或qos标记。

或者确实可以使用此命令将那些数据包发送到另一个接口,然后仅在该接口上捕获。




-1

我认为您可以创建一个Shell脚本来循环执行netstat并将其记录到文本文件中。有点像(非常粗糙的步骤):

echo "press q to quit"
while [ <q is not pressed>]
do
    `netstat -taucp | grep <pid or process name> 1>>logfile.txt`
done

我不是程序员,所以我无法完善这一点。但是这里有人可以从我离开的地方开始,为您创建一个有效的脚本。


还不够好。问题是捕获所有网络流量,而不仅仅是捕获在您检查时发生的活动。
Reinier Post
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.