10/08/2004
Simple Port Accounting
Say you’ve got a server with various services running on multiple ports and you want to monitor how much traffic each port recieves or sends. I’ve written 2 small scripts to easily accomplish this task.
The whole process is based on iptables rules & MRTG . You have to make some rules first on iptables according to what you want to monitor.
As an example we will monitor web-server traffic on port 80 (HTTP) and port 443 (HTTPS).
First come the iptables rules.
iptables.sh
#!/bin/bash
ME="XXX.YYY.ZZZ.WWW"
IPTABLES=/usr/sbin/iptables
$IPTABLES -A INPUT -p tcp -d $ME --dport 80
$IPTABLES -A INPUT -p tcp -d $ME --dport 443
$IPTABLES -I INPUT -i eth0
$IPTABLES -A OUTPUT -p tcp -s $ME --sport 80
$IPTABLES -A OUTPUT -p tcp -s $ME --sport 443
$IPTABLES -I OUTPUT -o eth0
change the ME variable and add your ip inside the quotes. Then put this script someplace where you put scripts…I use /opt/scripts or /root/scripts, and make an entry to your rc.local (or any other script runs on boot time) to run this script on boot (I hope I won’t get any comments on how to do that…)
Then comes the scripts that will take the stats gathered in iptables rules (you can see them by typing iptables -nvxL).
First script is: port.sh
#!/bin/bash
HOSTNAME="/bin/hostname"
IPTABLES="/usr/sbin/iptables"
UPTIME="/usr/bin/uptime"
$IPTABLES -nvxL | grep -w $1 | awk '{ print $2 }'
$UPTIME | awk '{ print $3, $4, $5 }'
$HOSTNAME
Second script is: inout.sh
#!/bin/bash
HOSTNAME="/bin/hostname"
IPTABLES="/usr/sbin/iptables"
UPTIME="/usr/bin/uptime"
if [ "$1" == "packet" ]; then
$IPTABLES -nvxL | grep -w eth0 | awk '{ print $1 }'
else
$IPTABLES -nvxL | grep -w eth0 | awk '{ print $2}'
fi
$UPTIME | awk '{ print $3, $4, $5 }'
$HOSTNAME
You can give them a try by typing ./port.sh 80:
1963705
19120562
58 days, 22:07,
or ./inout.sh
29086377134
70585824723
58 days, 22:16,
or even: ./inout.sh packet
514425312
549647125
58 days, 22:17,
The inout script can take the word “packet” as a command line parameter to show you total packet information.
What you need to do next is configure your mrtg to read these stats.
mrtg.cfg
WorkDir: /foo/bar/change/me
Target[80]: `/opt/scripts/port.sh 80`
MaxBytes[80]: 200000
Title[80]: Port 80
PageTop[80]: <h1>Port 80 Stats</h1>Target[443]: `/opt/scripts/port.sh 443`
MaxBytes[443]: 200000
Title[443]: Port 443
PageTop[443]: <h1>Port 443 Stats</h1>Target[inout]: `/opt/scripts/inout.sh`
MaxBytes[inout]: 2000000
Title[inout]: Total Traffic
PageTop[inout]: <h1>Total Traffic Stats</h1>Target[inoutp]: `/opt/scripts/inout.sh packet`
MaxBytes[inoutp]: 2000000
Title[inoutp]: Total Packets
PageTop[inoutp]: <h1>Total Packet Stats</h1>
Where workdir is a directory inside your web server served documents. For example…if your DocumentRoot is /var/www/mydomain/ make Workdir: /var/www/mydomain/mrtgstats
Now fire up mrtg to read the specified .cfg file and you are done!
# /foo/bar/mrtg/install/dir/mrtg /cfg/file/dir/mrtg.cfg
and you will see some files being created inside “WorkDir: /foo/bar/change/me”.
Add this line to your crontab
*/5 * * * * /foo/bar/mrtg/install/dir/mrtg /cfg/file/dir/mrtg.cfg
And you will have automated results every five minutes.
If you want to create a nice index.html to have all stats in one dir just do this:
# /foo/bar/mrtg/install/dir/indexmaker –output=/foo/bar/change/me/index.html –title=”MY Port Stats” –enumerate –columns=1 /cfg/file/dir/mrtg.cfg
Now go to http://yourhost/foo/bar/change/me and enjoy
Filed by kargig at 14:07 under General
1 Comment | 7,318 views
Many many thanks. It was very helpful to me.