How to Schedule Tcpdump to Run for a Specific Period of Time

How to schedule tcpdump to run for a specific period of time?

You can combine -G {sec} (rotate dump files every x seconds) and -W {count} (limit # of dump files) to get what you want:

tcpdump -G 15 -W 1 -w myfile -i eth0 'port 8080'

would run for 15 seconds and then stop. Turn 1.5 hours into seconds and it should work.

Tcpdump - measure for a fixed amount of time

You can use -G (rotating dump file every x seconds) + -W (number of files to rotate)

tcpdump -G 300 -W 1 -w file.dump

Why can't timeout take effect for tcpdump run under sudo?

The problem is that timeout runs with your users privileges. The sudo process escalates privileges to root (or another user), so timeout is not allowed to send SIGTERM to the child process. This can be shown with strace (comments starting with # by me, as well as blank lines for readability):

user$ strace timeout 1 sudo sleep 5
# lots of irrelevant stuff
# here, timeout sets up the timer to get a signal when the child should be terminated
rt_sigprocmask(SIG_UNBLOCK, [ALRM], NULL, 8) = 0
timer_create(CLOCK_REALTIME, {sigev_value={sival_int=1889673072, sival_ptr=0x560c70a21f70}, sigev_signo=SIGALRM, sigev_notify=SIGEV_SIGNAL}, [0]) = 0
timer_settime(0, 0, {it_interval={tv_sec=0, tv_nsec=0}, it_value={tv_sec=1, tv_nsec=0}}, NULL) = 0
wait4(12320, 0x7ffdfeb0ef0c, 0, NULL) = ? ERESTARTSYS (To be restarted if SA_RESTART is set)

# the signal arrives
--- SIGALRM {si_signo=SIGALRM, si_code=SI_TIMER, si_timerid=0, si_overrun=0, si_value={int=1889673072, ptr=0x560c70a21f70}} ---

# timeout tries to kill the child
kill(12320, SIGTERM) = -1 EPERM (Operation not permitted)
# and gets EPERM!

The fix is to run timeout with root privileges also. The following will work as intended:

user$ sudo timeout 1 sleep 5

Of course, if you already are root, it doesn’t matter whether you put timeout 1 before or after the sudo in the command line.

root$ sudo timeout 1 sleep 5
root$ timeout 1 sudo sleep 5

Write to another tcpdump file every minute

From the tcpdump man page:


-G rotate_seconds If specified, rotates the dump file specified with the -w option every rotate_seconds seconds. Savefiles will have the name specified by -w which should include a time format as defined by strftime(3). If no time format is specified, each new file will overwrite the previous. If used in conjunction with the -C option, filenames will take the form of 'file count'.

Looking at the strftime man page, you find all the documented conversion specifiers needed to create files in the format you've indicated.

Using the information from the various man pages, the following command should produce pcap files every minute that are named according to the format you indicated:

tcpdump -i eth0 -G 60 -w 'log_%d-%m_%Y__%H_%M.pcap'

Might I suggest a different naming convention though? The format you've chosen won't sort very well and clocks can drift over time, especially for long-running capture files; therefore, I'd recommend using an ISO 8601 format. For example:

tcpdump -i eth0 -G 60 -w 'log_%Y-%m-%dT%H_%M-04:00.pcap'

... or even simpler:

tcpdump -i eth0 -G 60 -w 'log_%FT%T-04:00.pcap'

NOTE -04:00 happens to be the current offset from UTC for my timezone. If you don't share pcap files with colleagues in different time zones, then you can omit the offset, but it can be useful so you might want to keep it anyway. You never know when you might want to share pcaps with colleagues across time zones in the future, and if they open your pcap file, they will have the information they need to easily time-shift the packet timestamps via Wireshark's Edit -> Time Shift ... feature so packet timestamps are relative to the time zone in which the capture file was taken rather than their own time zone. In this way, everyone is referencing the same time regardless of their own time zone and confusion can be avoided.

Run tcpdump in a loop

The issue is with your range - you have an extra period there. So, you are just looping once with the string {1...4} instead of 1 2 3 4.

You could write your code as:

#!/bin/bash
for i in {1..4}
do
tcpdump host 8.8.8.8 -ttt &
sleep 1
ping -I eth0 8.8.8.8 -c 1
sleep 1
kill "$!" # kill the background process
done

TcpDump: showing the absolute timestamp (date + time) of pcap file

You can use the -tttt option:

$ tcpdump -tttt -nr tmp.pcap 
reading from file tmp.pcap, link-type EN10MB (Ethernet)
2018-01-19 17:50:43.275918 IP 172.24.0.97.45386 > 93.153.221.29.80: Flags [.], ack 3335572340, win 251, options [nop,nop,TS val 98777655 ecr 230462279], length 0
2018-01-19 17:50:43.287273 IP 93.153.221.29.80 > 172.24.0.97.45386: Flags [.], ack 1, win 285, options [nop,nop,TS val 230464839 ecr 98706059], length 0
2018-01-19 17:50:44.138480 ARP, Request who-has 172.24.0.73 tell 172.24.0.78, length 46
2018-01-19 17:50:45.162482 ARP, Request who-has 172.24.0.73 tell 172.24.0.78, length 46


Related Topics



Leave a reply



Submit