Changes

Jump to: navigation, search

Traffic accounting with iptables

783 bytes added, 09:28, 15 December 2011
m
Reverted edits by TermPaperServices (talk) to last revision by Kir
Suppose you need to know how much traffic your [[VEcontainer]]s eat. It can be easily done
using iptables.
== Situation description ==
Let's consider the very simple situation: one VE container with one IP address on the [[Hardware Node]]with only one network interface. To be more exact, assume that [[VEcontainer]] ID is <tt>200</tt>, the IP address of the [[HN]]is <tt>192.168.0.56</tt>, the network interface name is <tt>eth0</tt>, and the IP address of the [[VEcontainer]] is <tt>192.168.0.117</tt>.
You wish to know how much many bytes VE container 200 eats. One more assumption is that there are no iptables rules
on HN now. All these assumption are only for clarity!
== Solution ==
Almost any traffic that goes to and from a VE container can be catched by FORWARD chain of iptables module in [[VE0container0]],
thus we add such rules:
<pre>
</pre>
It means that all traffic forwarded to IP 192.168.0.117 and from IP 192.168.0.117 will be accounted.
To obtain current traffic usage of VE container you can issue the command:
<pre>
# iptables -nv -L FORWARD
15 1052 all -- * * 0.0.0.0/0 192.168.0.117
</pre>
'''Bytes''' column is the column we need. It's worth to saysaying, that restarting a VE container doesn't affect accounting,
it remains right. But if you restart your [[hardware node]], all the rules and consequently statistics are dropped.
So it is recommended to
* add init script that creates iptables rules on [[HN]] start.
If you want to process the results with a script it is useful to use the "-x" or "--exact" option of iptables<pre># iptables -nvx -L FORWARD</pre>You will get the exact value of the packet and byte counters, instead of only the rounded number in K’s (multiples of 1000) M’s (multiples of 1000K) or G’s (multiples of 1000M). As is easy to see, it's not per-VE container statistic, but rather per-IP statistic. Thus you must be carefulthen changing VE container IP addresses, otherwise you'll get mess of results.
By saying ''almost any traffic'' I mean that traffic between a [[VEcontainer]] and [[VE0container0]] is not accounted by rules above.
Not sure if it can be useful for anybody, but to account such traffic these rules are needed:
<pre>
To observe results:
<pre>
# iptables -nv nvx -L INPUT
Chain INPUT (policy ACCEPT 542 packets, 63745 bytes)
pkts bytes target prot opt in out source destination
35 4533 all -- venet0 * 0.0.0.0/0 192.168.0.117
# iptables -nv nvx -L OUTPUT
Chain OUTPUT (policy ACCEPT 247 packets, 27847 bytes)
pkts bytes target prot opt in out source destination
# iptables -Z
</pre>
The disadvantage is that doing by doingit this way you zero all counters in all rules. If it is not what you need,
you can just replace the rule with the same rule:
<pre>
# iptables -nv nvx -L FORWARD
Chain FORWARD (policy ACCEPT 101 packets, 10715 bytes)
pkts bytes target prot opt in out source destination
57 5564 all -- * * 0.0.0.0/0 192.168.0.117
# iptables -R FORWARD 1 -s 192.168.0.117
# iptables -nv nvx -L FORWARD
Chain FORWARD (policy ACCEPT 101 packets, 10715 bytes)
pkts bytes target prot opt in out source destination
more complicated situations.
; More than one VE container on the node: Just add the rules like above for each VE container IP.
; More than one IP per VEcontainer.: For each IP add the rules like above. When counting the complete traffic of a VE container you have to summarize over all IPs that this VE container owns.
; More interfaces on the HN.
Here are some scripting ideas
=== Get VEIDs CTIDs of all running VEs containers ===
<pre>
host2:~/bin# cat vz-all-running
</pre>
=== Get all IPs of running VEs containers ===
<pre>
host2:~/bin# cat vz-all-running-ip
=== Generate a traffic.log ===
Please use crontab to run this script once per hour or day to collect your traffic statistics.
 
(Warning, the counters can overflow if there is too much traffic within that period. Would recommend 15 minute intervals if you expect a lot of traffic)
<pre>
host2:~/bin# cat vz-generate-traffic-log
echo -n `date "+%Y-%m-%d %H:%M:%S"` >> $trafficlog
echo -n " $i " >> $trafficlog
echo `iptables -nv nvx -L FORWARD | grep " $i " | tr -s [:blank:] |cut -d' ' -f3| awk '{sum+=$1} END {print sum;}'` >> $trafficlog
done
# reset the counter
iptables -Z
# update the iptables rules if there is a any change in VEscontainers
./vz-iptables-create-rules
# start a php script to store the traffic in a MySQL Database on the HOST-TO-SHOW-THE-TRAFFIC-TO-THE-USERS
# please mind to use .htaccess to secure this
wget -q http://HOST-TO-SHOW-THE-TRAFFIC-TO-THE-USERS/login/traffic-read.php?HN=$HOSTNAME -O /dev/null
</pre>
Below script will process traffic.log and store the data into a MySQL Database on the HOST-TO-SHOW-THE-TRAFFIC-TO-THE-USERS
<presource lang="text">
HOST-TO-SHOW-THE-TRAFFIC-TO-THE-USERS:/var/www/OPENVZ-CONTROL-WEB-SITE# cat traffic-read.php
</source>
<source lang="php">
<?
$MySQL_Host="INSERT-YOUR-MYSQL-HOST-HERE";
$MySQL_Passw="INSERT-YOUR-MYSQL-PASSWORD-HERE";
mysql_connect("$MySQL_Host","$MySQL_User","$MySQL_Passw");
$HN=trim(addslashes($_GET["HN"])); // Hardware Node
$handle = fopen ("tmp/{$HN}-traffic","r");
while (!feof($handle)) {
$line = fgets($handle, 4096);
list($date,$time,$ip,$traffic)=explode(" ",$line);
if($traffic>0) {mysql($db,"insert into Traffic (ip,measuringtime,bytes) values('{$ip}','{$date } {$time}','{$traffic}')");}
}
fclose($handle);
?>
</presource>
=== A SQL query to get the traffic for the last 30 days ===
<presource lang="mysql">
SELECT sum(bytes)
FROM Traffic
AND measuringtime > ( now() - INTERVAL 1 MONTH)
GROUP BY ip
</presource>
=== Notes ===
As you see this way can be time-consuming in case of a big number of VEscontainers.
So if anybody has scripts that automate all the process — you are welcome!
== See also ==* [[Category: HOWTOTraffic accounting through proc]] 
[[Category: Networking]]
[[Category: Monitoring]]

Navigation menu