Traffic accounting with iptables
Suppose you need to know how much traffic VPS eats. It can be easily done using iptables.
Situation description
Lets consider the very simple situation: one VPS with one IP address on Hardware Node (HN) with only one interface. To be more exact assume that VPS id is 200, ip address of the HN is 192.168.0.56, interface name is eth0, ip address of VPS is 192.168.0.117. And you wish to know how much bytes 200th VPS eats. One more assumption that ther is no iptables rules on HN now. All these assumption are only for clarity!
Solution
Almost any trafic that goes to and from vps can be catched from FORWARD chain of iptables module in VE0, thus we add such rules:
# iptables -A FORWARD -s 192.168.0.117 # iptables -A FORWARD -d 192.168.0.117
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 VPS you can give the command:
# iptables -nv -L FORWARD Chain FORWARD (policy ACCEPT 243 packets, 28089 bytes) pkts bytes target prot opt in out source destination 8 832 all -- * * 192.168.0.117 0.0.0.0/0 15 1052 all -- * * 0.0.0.0/0 192.168.0.117
"Bytes" column is the column we need. It's worth to say, that restarting VPS doesn't affect accounting, it remains right. But if you restart your node all rules and consequently statistics are droped. So it's recomended to run some cron job that dumps statistic on hard drive and also add init script that creates iptables rules on HN start.
As is easy to see, it's not per VPS statistic, but rather per IP statistic. Thus you must be carefull then changing IPs of VPSs, otherwise you'll get mess of results.
Saing "almost any trafic", I mean, that traffic between VE and and VE0 isn't accounted by rules above. Don't know can it be useful for anybody, but to account such traffic these rules pass:
iptables -I INPUT 1 -i venet0 -d 192.168.0.117 iptables -I OUTPUT 1 -o venet0 -s 192.168.0.117
To observe results:
[root@dhcp0-56 traffic_accounting]# iptables -nv -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 [root@dhcp0-56 traffic_accounting]# iptables -nv -L OUTPUT Chain OUTPUT (policy ACCEPT 247 packets, 27847 bytes) pkts bytes target prot opt in out source destination 48 4724 all -- * venet0 192.168.0.117 0.0.0.0/0
If you need to zero counters this command works:
# iptables -Z
The disadvantage is that doing this way you zero all counters in all rules. If it's undesrable for you, you can just replace the rule with the same rule:
[root@dhcp0-56 traffic_accounting]# iptables -nv -L FORWARD Chain FORWARD (policy ACCEPT 101 packets, 10715 bytes) pkts bytes target prot opt in out source destination 44 5151 all -- * * 192.168.0.117 0.0.0.0/0 57 5564 all -- * * 0.0.0.0/0 192.168.0.117 [root@dhcp0-56 traffic_accounting]# iptables -R FORWARD 1 -s 192.168.0.117 [root@dhcp0-56 traffic_accounting]# iptables -nv -L FORWARD Chain FORWARD (policy ACCEPT 101 packets, 10715 bytes) pkts bytes target prot opt in out source destination 0 0 all -- * * 192.168.0.117 0.0.0.0/0 57 5564 all -- * * 0.0.0.0/0 192.168.0.117
More complicated cases
Well, now, when we know how to work in the easiest case, we'll try to understand what to do in more complicated situations.
- More than one VPS on the node
Just add the rules like above for each VPS's IP.
- More than one IP per VPS.
For each IP add the rules like above. When counting the complete traffic of VPS you have to summarize over all IPs that this VPS owns.
- More interfaces on the HN.
Nothing to do! :)
Scripting
As you see this way can be time-consuming in case of big amount of VPSs. So if anybody has scripts that automate all the process - you are welcome!