Tcpdump with special filters

Tcpdump and some useful filters


Description

In this post I would like to share a small solution that is using tcpdump to track only external connections that are new.

This script can be very useful especially when you want to migrate some Internet facing servers and after a very long usage you don’t who is accessing the server externally.
You want to be sure before migrating, that services will not be affected or missed.

Explanation

– In this script we have a tcpdump instance that is running for a few days/a week to detect all traffic that is hitting our server.
We want to have only syn and ack packets filtered.
Tcpdump is expansive in terms of used disk space so we have to be very careful because in a medium/average network the whole disk space can be fulfill in a meter of hours/days if we are running a whole packet capture.

– In the script we are keeping track of the existing disk space when we are starting it. If we have less than 6Gb on / than the script does not start. Everything we’ll be stored on /TCPDUMP direcory under /.

– Our server can be located in DMZ, behind a load balancer or can be exposed through a firewall.  We assume that our server is located on DC1 data-center, that’s why we have that shape for the filter.

– We consider that our internal address space is located on 4 data-centers dc1, dc2, dc3,dc4 and the internal IP space is 10.1.0.0/16,10.2.0.0/16,10.3.0.0/16,10.4.0./16. You can adjust the script to satisfy your needs, this being only an example.

– We what to capture everything that hists our server and we want to exclude from the capture internal traffic (in our data-centers).
For that we collect everything else than our internal source and internal destination.

 

Implementation

tcpdump_collect.sh

#!/bin/bash
if [ -e /TCPDUMP/Dump.pid ]
then
 pid=`cat /TCPDUMP/Dump.pid`
 kill $pid 
 rm /TCPDUMP/Dump.pid
 # Another verification layer #
 while [ -e /proc/$pid ]
 do
     echo "killing the $pid" 
     kill $pid
     sleep 2
 done
fi

### check disk space ##
dff=`df -k /`
arr=$(echo $dff|cut -f 11 -d " ")
echo "Free space is: $arr"
if [ $arr -le 6000000 ] # less then 6 G
then
      echo -e "Space is critical\n"
      echo "tcpdump will not start again"
else
      echo -e "starting tcpdump again\n"
      interface="eth0"
      dat=`date +"%Y-%m-%d_%H-%M-%S"`
 
      ##filter the sources and addresses###
      dc1_internal="10.1.0.0/16"
      dc2_internal="10.2.0.0/16"
      dc3_external="10.3.0.0/16"
      dc4_external="10.4.0.0/16"

     filter1='tcp[tcpflags] & (tcp-syn) != 0'
     filter2='tcp[tcpflags] & (tcp-ack) != 0'
     filter3="src net($dc1_internal) and not(dst net($dc3_external or $dc4_external or $dc1_internal or $dc2_internal))"

 /usr/sbin/tcpdump -pni $interface -ttt $filter1 and $filter2 and $filter3 -w /TCPDUMP/"trace_$dat.pcap" -Z root &
 echo $! > /TCPDUMP/Dump.pid
fi

It is useful to run the script from cron because you want to avoid having very big files. Also  sometimes tcpdump process crushes so you can restart it from cron.

cd /etc/cron.d
touch tcpdump

cat tcpdump
0    *     *    *    *  root /TCPDUMP/tcpdump_collect.sh

After you’ll collect all relevant information, all captures are located in /TCPDUMP directory in files with timestamps.
You can read the content of the files by using tcpdump with -r flag and you can filter/sort the IP addresses.

Author: techwritter