11

I'd love if there was a single command line tool for packet sniffing a single command in Linux. something like sniff dumpfile command so that you could just run the command you want to packet sniff in the terminal and get a dump of the packets somewhere else.

I'd like to dump / save / see only the network traffic of the single command that I enter, not all the TCP traffic on my single network interface. So if I was logged into my computer and had IRC running in the background, and I did sniff somefile wget http://www.google.com, I'd want to see all the network traffic that the wget command did to download http://www.google.com. I don't want 'somefile' to have the IRC network traffic confusing things.

There are lots of linux/unix commands that accept a different command and do something different. From sudo (run as superuser), nice change nice level, trickle (limit the bandwidth of a command)

Amandasaurus
  • 33,461

12 Answers12

10

There isn't any that I know of, but it theoretically shouldn't be hard to get something similar. Strace can be used to intercept networking syscalls.

# strace -f -e trace=network -s 10000 /usr/bin/command arguments

This will give you information about the data sent between the kernel and the process. The output of strace isn't exactly what you'd want. However, strace uses the ptrace syscall to intercept system calls. It might be possible to write a program to output the data a little more usefully.

Alternatively, you can also intercept the nice useful socket, bind and listen syscalls. It might be possible to write a small program that used ptrace on these calls and libpcap to dynamically change the capture filter every time a new socket is opened.

David Pashley
  • 23,963
8

Tracedump

Tracedump is a single application IP packet sniffer, which captures all TCP and UDP packets of a single Linux process.

Download and description here: http://mutrics.iitis.pl/tracedump

splattne
  • 28,776
pjf
  • 81
4

Try Wireshark -- the command will be tshark

  • tshark allows you to select filters on the traffic captured from an interface
  • use other utilities like the debian lsof to identify the kind of communication done by your application of interest.

Or, Do you really just want LSOF?


I don't think there is a tool that will dynamically keep filtering for all communication associated to a process. However, you could try tracking the process communications with tools like lsof and once you have a good filter that can isolate communication of that process from all other traffic running on your system, you could get the correct capture.

For, example, with wget usually the destination IP address is distinct from other process related traffic. Even if you take something like skype the destination port range is usually fixed for an instance.


This is a bit like the uncertainty principle. You can usually know what is going through a set of communication paths (with a sniffer filtering on identified group of flows), or where different communication links are being made (with lsof).

I would really like to know if both can be done for an application. I think it should be feasible. But, have not seen any tool do that yet.

nik
  • 7,140
4

Learn to use filter expressions.

Whilst this won't do the fancy trace stuff that you are asking for.

It will allow you to remove nearly all of the "confusing stuff like IRC" from the capture.

Additionally it's very useful to know the filter syntax for quick reference in the future.

Dan Carley
  • 26,127
2

Specifically for a web browser / web page something like the Firebug plug-in for Firefox may give you some of the information you are looking for: http://getfirebug.com/net.html

For more general applications, you may need to use netstat to identify the port(s) used by the application and then Wireshark/tshark/dtrace with a filter to capture just that traffic. Not the one line answer you were looking for though...

Peter
  • 5,513
1

One idea, try VMWare

-setup a vm
-configure that vm to use a particular interface
-sniff on that interface from the host (its like a man in the middle attack)

If you isolate what network applications are running on that vm you might have your answer

A more ideal solution, I suppose, is to do what VMWare does in terms of how it specifies how it chooses an interface to talk over. I think its magic comes from the kernel modules it uses, in this case, probably vmnet kernel module.

To my knowledge applications are not aware for what interface they talk over and I believe this is by design; they shouldn't have to worry about such things.

Furthermore,
Perhaps a program already exists, I don't know. But if one was written you could call it nettrace (for example) and Usage could be like

nettrace program interface

then sniff the interface it uses and add routes (maybe it does the automatically) to your real interface

rev
  • 113
1

Assuming that you are the only person on the box attempting to connect to google at the time, I'd think something like this should do the trick:

tcpdump -w <outfile> -i <interface> tcp dst host www.google.com and dst port 80

If you are not the only connection attempting to connect to google on the box, then if you can identify the IP/port you are connecting from you can also specify the src port/src ip.

Identifying the src port may be a problem unless you can specify it on whatever client you use. I'm not sure if you can with wget.

I strongly suspect that you can specify both src and dst ports with netcat so if it was really google you were interested in, you could do your GET (manually) through netcat.

Of course the man page will give you specifics

Jason Tan
  • 2,792
1

The tcpdump man page and many web sites give in-depth examples of filters, and there are even a few online repositories of tcpdump filter expressions. It should be able to do almost anything you can dream of, assuming that you know something about the network traffic (source, destination, ports, protocols, etc.) beyond just what program is generating it.

If you're working on a server or headless box, you can always have tcpdump write a dump file and then open it in Wireshark on your workstation and get advanced filtering and a graphical interface.

Jason Antman
  • 1,536
1

Maybe this script will do what you want with appropriate modifications to the tshark command:

#!/bin/bash

# Start tshark in the background before we run the commsnd to be sniffed.
# Add more options to tshark, as appropriate to your command....
setsid tshark  -w dump -i eth0 tcp port 8080 >/dev/null 2>&1  &

sleep 2

wget www.google.com

# tshark keeps running if you don't kill it. 
# This kills all other tsharks that may be running.
pkill -9 tshark

Read the dump file later:

tshark -r dump
Not Now
  • 3,602
0

The ptrace method used by tracedump was my initial idea, but it has some drawbacks. If it does what you need, stick with it. If not, there’s another approach you can consider

The problem with using the ptrace approach is that it’s very invasive. Per the documentation of tracedump, some applications will crash under some circumstances. It’s very difficult to do this elegantly with ptrace without that risk

Another high-level approach would be to utilize network namespaces - essentially per-process containerized networking- with a virtual Ethernet device pair to route and mirror traffic

Using this approach, the traffic from your process will always route through a single point, separate from other processes, creating an opportunity to capture it

Roughly:

  1. Create a new network namespace
  2. Create and configure a virtual Ethernet device pair
  3. Set up forwarding from the namespace via the virtual Ethernet device pair, using iptables
  4. Set up tcpdump on one of the virtual Ethernet devices
  5. Finally, move the process of interest into the new network namespace

Optionally, you could also modify the traffic using this method. You would redirect the traffic to a userland forwarder outside of the namespace rather than routing it directly via iptables. That userland application would be responsible for sending the packets on to their final location

For more on this general idea, the best resources would probably be guides on “transpart proxying”, even though most of those use-cases involve (effectively) rewriting a packet so that it uses a socks or http proxy to reach its destination (something you won’t want, except for certain types of applications)

There are plenty of potential problems with this approach, depending on the details of what you need to do and how the process communicates and operates. For example, potential problems may be:

  1. Handling traffic that goes to loopback
  2. Handling the case where the process forks, and you don’t want to capture the traffic of the child
  3. … plenty of other exceptional cases

So YMMV

Here are a few posts/docs that may help to understand this if you’re not familiar with it:

... they don’t perfectly fit your use-case, but they’re very closely related and they demonstrate the commands required to do per-process network isolation

I’m curious if there are any projects out there that help to automate this in a user-friendly way. I’ll add a reference if I find one as I currently do this manually, case-by-case

mzpq
  • 111
0

Dtrace should allow this, although I don't know whether it's quite made it into Linux yet.

Toto
  • 738
-1

How about ptcpdump:

sudo ptcpdump -i any -- CMD
sudo ptcpdump -i any -w out.pcapng -- CMD
$ sudo ptcpdump -i any -- curl serverfault.com
2024/06/09 14:19:07 capturing...
2024/06/09 14:19:07 start to run "curl serverfault.com"
14:19:07.579103 lo Out IP (tos 0x0, ttl 64, id 22733, offset 0, flags [DF], ip_proto UDP (17), length 72)
    127.0.0.1.45684 > 127.0.0.53.53: 46388+ [1au] A? serverfault.com. (44)
    Process (pid 1945406, cmd /usr/bin/curl, args curl serverfault.com)
14:19:07.579166 lo Out IP (tos 0x0, ttl 64, id 22734, offset 0, flags [DF], ip_proto UDP (17), length 72)
    127.0.0.1.45684 > 127.0.0.53.53: 6705+ [1au] AAAA? serverfault.com. (44)
    Process (pid 1945406, cmd /usr/bin/curl, args curl serverfault.com)
14:19:07.893502 wlp4s0 Out IP (tos 0x0, ttl 64, id 17131, offset 0, flags [DF], ip_proto TCP (6), length 60)
    192.168.1.50.54308 > 172.64.148.218.80: Flags [S], cksum 0x324, seq 239503187, win 64240, options [mss 1460,sackOK,TS val 2499084311 ecr 0,nop,wscale 7], length 0
    Process (pid 1945406, cmd /usr/bin/curl, args curl serverfault.com)
...