Problem
I was looking for an alternative to NProbe as a NetFlow Probe/Agent for a CentOS as NProbe is not free and i wanted somehing that i could run as a Probe only and in deamon mode. After looking at various options, I settled on SoftFlowD as an alternative and thought that I would share with the community how exactly I did it. It works like a dream for me so enjoy!!!
Installing SoftFlowD as a TCP Flow Based Probe
The following is a description of how we can install a TCP Flow based probe to capture the data going in and out of a Centos Linux server and to export this in NetFlow Version 5 format to a collector for further analysis.
First of ak, we need to ensure that we have a few utilities installed on the server to satisfy the dependencies.
[root@wbcphpxy01 ~]# yum install libtool automake autoconf python-devel
libpcap-devel
Once these are installed, then let’s get a copy of the softflowd compressed source files:-
[root@wbcphpxy01 ~]# cd /root
[root@wbcphpxy01 ~]#wget http://softflowd.googlecode.com/files/softflowd-0.9.9.tar.gz
--2013-09-30 11:17:13-- http://softflowd.googlecode.com/files/softflowd-0.9.9.tar.gz
Resolving softflowd.googlecode.com... 173.194.70.82, 2a00:1450:4001:c02::52
Connecting to softflowd.googlecode.com|173.194.70.82|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 91939 (90K) [application/x-gzip]
Saving to: âsoftflowd-0.9.9.tar.gzâ
100%[======================================>] 91,939 --.-K/s in 0.1s
2013-09-30 11:17:13 (673 KB/s) - âsoftflowd-0.9.9.tar.gzâ
Now let’s decompress them:-
[root@wbcphpxy01 ~]# tar -zxvf softflowd-0.9.9.tar.gz
softflowd-0.9.9
softflowd-0.9.9/softflowctl.8
softflowd-0.9.9/.hg_archival.txt
softflowd-0.9.9/.cvsignore
softflowd-0.9.9/.hgtags
softflowd-0.9.9/LICENSE
softflowd-0.9.9/Makefile.in
softflowd-0.9.9/README
softflowd-0.9.9/TODO
softflowd-0.9.9/aclocal.m4
softflowd-0.9.9/closefrom.c
softflowd-0.9.9/collector.pl
softflowd-0.9.9/common.h
softflowd-0.9.9/configure.ac
softflowd-0.9.9/convtime.c
softflowd-0.9.9/convtime.h
softflowd-0.9.9/daemon.c
softflowd-0.9.9/freelist.c
softflowd-0.9.9/freelist.h
softflowd-0.9.9/install-sh
softflowd-0.9.9/log.c
softflowd-0.9.9/log.h
softflowd-0.9.9/mkinstalldirs
softflowd-0.9.9/netflow1.c
softflowd-0.9.9/netflow5.c
softflowd-0.9.9/netflow9.c
softflowd-0.9.9/softflowd.sysconfig
softflowd-0.9.9/softflowctl.c
softflowd-0.9.9/softflowd.8
softflowd-0.9.9/softflowd.c
softflowd-0.9.9/softflowd.h
softflowd-0.9.9/softflowd.init
softflowd-0.9.9/softflowd.spec
softflowd-0.9.9/strlcat.c
softflowd-0.9.9/strlcpy.c
softflowd-0.9.9/sys-tree.h
softflowd-0.9.9/treetype.h
softflowd-0.9.9/configure
softflowd-0.9.9/config.h.in
Now that we have uncompressed the files, let’s change to the relevant directory and then run the configuration script that checks whether you have the relevant programs dependencies such as gcc in place and where those binaries are on your system:-
[root@wbcphpxy01 ~]# cd softflowd-0.9.9
[root@wbcphpxy01 softflowd-0.9.9]# ./configure
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for a BSD-compatible install... /usr/bin/install -c
checking how to run the C preprocessor... gcc -E
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking net/bpf.h usability... no
checking net/bpf.h presence... no
checking for net/bpf.h... no
checking pcap.h usability... yes
checking pcap.h presence... yes
checking for pcap.h... yes
checking pcap-bpf.h usability... yes
checking pcap-bpf.h presence... yes
checking for pcap-bpf.h... yes
checking for struct sockaddr.sa_len... no
checking for struct ip6_ext.ip6e_nxt... yes
checking for library containing daemon... none required
checking for library containing gethostbyname... none required
checking for library containing socket... none required
checking for pcap_open_live in -lpcap... yes
checking for closefrom... no
checking for daemon... yes
checking for setresuid... yes
checking for setreuid... yes
checking for setresgid... yes
checking for setgid... yes
checking for strlcpy... no
checking for strlcat... no
checking for u_int64_t... yes
checking for int64_t... yes
checking for uint64_t... yes
checking for u_int32_t... yes
checking for int32_t... yes
checking for uint32_t... yes
checking for u_int16_t... yes
checking for int16_t... yes
checking for uint16_t... yes
checking for u_int8_t... yes
checking for int8_t... yes
checking for uint8_t... yes
checking size of char... 1
checking size of short int... 2
checking size of int... 4
checking size of long int... 4
checking size of long long int... 8
configure: creating ./config.status
- config.status: creating Makefile
- config.status: WARNING: 'Makefile.in' seems to ignore the --datarootdir setting
- config.status: creating config.h
Now we need to run the make utility to build a binary executable ready to install, which is customised to your environment:-
[root@wbcphpxy01 softflowd-0.9.9]# make
gcc -g -O2 -DFLOW_SPLAY -DEXPIRY_RB -I. -c -o softflowd.o softflowd.c
gcc -g -O2 -DFLOW_SPLAY -DEXPIRY_RB -I. -c -o log.o log.c
gcc -g -O2 -DFLOW_SPLAY -DEXPIRY_RB -I. -c -o netflow1.o netflow1.c
gcc -g -O2 -DFLOW_SPLAY -DEXPIRY_RB -I. -c -o netflow5.o netflow5.c
gcc -g -O2 -DFLOW_SPLAY -DEXPIRY_RB -I. -c -o netflow9.o netflow9.c
gcc -g -O2 -DFLOW_SPLAY -DEXPIRY_RB -I. -c -o freelist.o freelist.c
gcc -g -O2 -DFLOW_SPLAY -DEXPIRY_RB -I. -c -o convtime.o convtime.c
gcc -g -O2 -DFLOW_SPLAY -DEXPIRY_RB -I. -c -o strlcpy.o strlcpy.c
gcc -g -O2 -DFLOW_SPLAY -DEXPIRY_RB -I. -c -o strlcat.o strlcat.c
gcc -g -O2 -DFLOW_SPLAY -DEXPIRY_RB -I. -c -o closefrom.o closefrom.c
gcc -g -O2 -DFLOW_SPLAY -DEXPIRY_RB -I. -c -o daemon.o daemon.c
gcc -o softflowd softflowd.o log.o netflow1.o netflow5.o netflow9.o freelist.o convtime.o strlcpy.o strlcat.o closefrom.o daemon.o -lpcap
gcc -g -O2 -DFLOW_SPLAY -DEXPIRY_RB -I. -c -o softflowctl.o softflowctl.c
gcc -o softflowctl softflowctl.o convtime.o strlcpy.o strlcat.o closefrom.o daemon.o -lpcap
Now that we have a binary ready for installing, we just need to install the application on your system:-
[root@wbcphpxy01 softflowd-0.9.9]# make install
[ -d /usr/local/sbin ] || \./mkinstalldirs /usr/local/sbin
[ -d /usr/local/share/man/man8 ] || \./mkinstalldirs /usr/local/share/man/man8
/usr/bin/install -c -m 0755 -s softflowd /usr/local/sbin/softflowd
/usr/bin/install -c -m 0755 -s softflowctl /usr/local/sbin/softflowctl
/usr/bin/install -c -m 0644 softflowd.8 /usr/local/share/man/man8/softflowd.8
/usr/bin/install -c -m 0644 softflowctl.8 /usr/local/share/man/man8/softflowctl.8
[root@wbcphpxy01 softflowd-0.9.9]#
Now that we have a working copy of softflowd on the system, we can review the help file for the application by typing the following:-
[root@wbcphpxy01 ~]# softflowd -h
-i or -r option not specified.
Usage: softflowd [options] [bpf_program]
This is softflowd version 0.9.9. Valid commandline options:
-i [idx:]interface Specify interface to listen on
-r pcap_file Specify packet capture file to read
-t timeout=time Specify named timeout
-m max_flows Specify maximum number of flows to track (default 8192)
-n host:port Send Cisco NetFlow(tm)-compatible packets to host:port
-p pidfile Record pid in specified file
(default: /var/run/softflowd.pid)
-c pidfile Location of control socket
(default: /var/run/softflowd.ctl)
-v 1|5|9 NetFlow export packet version
-L hoplimit Set TTL/hoplimit for export datagrams
-T full|proto|ip Set flow tracking level (default: full)
-6 Track IPv6 flows, regardless of whether selected
NetFlow export protocol supports it
-d Don't daemonise (run in foreground)
-D Debug mode: foreground + verbosity + track v6 flows
-s sampling_rate Specify periodical sampling rate (denominator)
-h Display this help
Now, we should be able to run the software in Debug mode in the foreground using the following command to ensure that we see the relevant messages (especially error messages):-
[root@wbcphpxy01 ~]# softflowd -D -v 5 -i eth0 -n 10.20.30.15:2055 -T full
Using eth0 (idx: 0)
softflowd v0.9.9 starting data collection
Exporting flows to [10.20.30.15]:iop
ADD FLOW seq:1 [10.170.1.201]:1335 <> [10.170.5.251]:22 proto:6
ADD FLOW seq:2 [10.140.42.250]:58374 <> [239.255.255.250]:1900 proto:17
ADD FLOW seq:3 [10.170.5.101]:0 <> [224.0.0.252]:0 proto:2
ADD FLOW seq:4 [10.170.5.101]:0 <> [239.255.255.250]:0 proto:2
...
In the above example, the following explains each of the switches I have used:-
-D Debug mode, which bring this to the foreground
-v 5 Version 5 of Netflow
-i eth0 The Interface number
-n 10.20.30.15:2055 The target host IP address and port number of the collector/analyser
-T full All protocols
Now running this is Debug mode is useful if you want to make sure that is working but it more useful to have this running in the background so the way we do that is to remove the –D statement in the option like such and you will just see the command prompt come back:-
[root@wbcphpxy01 ~]# softflowd -v 5 -i eth0 -n 10.20.30.15:2055 -T full
[root@wbcphpxy01 ~]#
You can still see that the flows are being “recorded” and that they are being exported in NetFlow version 5 and set to in this case 10.20.30.15 using destination port 2055. This is done using a utility such as TCPDUMP:-
[root@wbcphpxy01 ~]# tcpdump -n –v dst port 2055
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
14:14:01.426775 IP 10.170.5.251.35829 > 10.20.30.15.iop: UDP, length 312
14:15:01.185508 IP 10.170.5.251.35829 > 10.20.30.15.iop: UDP, length 408
14:16:01.944233 IP 10.170.5.251.35829 > 10.20.30.15.iop: UDP, length 168
Now all this is fine, but it really only becomes useful if we can stop/start and restart the application like a service and have this enabled after the server has had a reboot. To do this we edit a file called /etc/init.d/softflowd and empty the following contents into the file and save it:-
#! /bin/bash
#
# chkconfig: 2345 80 30
# description: SoftFlow Deamon Service
### BEGIN INIT INFO
# Provides: SOFTFLOWD
# Short-Description: Start/Stop/Restart SOFTFLOWD TCP Flow Probe
### END INIT INFO
#
# SOFTFLOWD This init.d script is used to start SOFTFLOWD.
#
SOFTFLOWD=/usr/local/sbin/softflowd
VERSION="5"
INTERFACE="eth0"
COLLECTOR="10.20.30.15"
CPORT="2055"
PID_FILE="/var/run/softflowd.pid"
OPTIONS="-v ${VERSION} -i ${INTERFACE} -n ${COLLECTOR}:${CPORT} -T full -p ${PID_FILE}"
start_SOFTFLOWD() {
${SOFTFLOWD} ${OPTIONS} > /dev/null &
return 1
}
stop_SOFTFLOWD() {
if [ -f ${PID_FILE} ]; then
kill `cat ${PID_FILE}` 2>1 /dev/null
\rm ${PID_FILE}
fi
}
########
case "$1" in
start)
echo -n "Starting SOFTFLOWD"
start_SOFTFLOWD;
echo " Done."
;;
stop)
echo -n "Stopping SOFTFLOWD"
stop_SOFTFLOWD;
echo " Done."
;;
restart)
echo -n "Restarting SOFTFLOWD"
stop_SOFTFLOWD;
sleep 1
start_SOFTFLOWD;
echo " Done."
;;
*)
echo "Usage: /etc/init.d/SOFTFLOWD {start|stop|restart}"
exit 1
esac
exit 0
After saving the file, we need to change the file permissions to:-
[root@wbcphpxy01 ~]# chmod 755 /etc/init.d/softflowd
Now let’s make the script a loadable initialisation script as part of the “service <application name> start” function by adding this with the chkconfig command:-
[root@wbcphpxy01 ~]# chkconfig --add softflowd
If you need to remove the script from being initiated at boot up as a service, then issue the following:-
[root@wbcphpxy01 ~]# chkconfig --remove softflowd
Finally, let’s start the service:-
[root@wbcphpxy01 ~]# service softflowd start
Start SOFTFLOWD Done.