====== Traffic counting on the CCGX ======
There are situation in which it is interesting to know the traffic usage of the color control. This can be done on the GX device using [[http://en.wikipedia.org/wiki/Iptables|iptables]]. To do so requires a number of changes on the GX device, which are described here.
==== The rules ====
The following commands clear the existing rules from iptables and add rules for counting specific traffic.
#Flush all
iptables -F
#Delete all user defined chains
iptables -X
#ACCEPT traffic to local host
iptables -I INPUT -s 127.0.0.0/8 -j ACCEPT
iptables -I OUTPUT -d 127.0.0.0/8 -j ACCEPT
#ACCEPT traffic to the local LAN
iptables -I INPUT -s 10.0.0.0/8 -j ACCEPT
iptables -I OUTPUT -d 10.0.0.0/8 -j ACCEPT
iptables -I INPUT -s 172.16.0.0/12 -j ACCEPT
iptables -I OUTPUT -d 172.16.0.0/12 -j ACCEPT
iptables -I INPUT -s 192.168.0.0/16 -j ACCEPT
iptables -I OUTPUT -d 192.168.0.0/16 -j ACCEPT
#ACCEPT multicast traffic
iptables -I INPUT -d 224.0.0.0/4 -j ACCEPT
iptables -I OUTPUT -d 224.0.0.0/4 -j ACCEPT
#ACCEPT broadcast traffic (dhcp)
iptables -I INPUT -d 255.255.255.255 -j ACCEPT
iptables -I OUTPUT -d 255.255.255.255 -j ACCEPT
#Send all remaining traffic to OTHER_IN/OUT and log
iptables -N OTHER_IN
#The following line can oly be used when the xt_limit kernel module is available
#iptables -A OTHER_IN -j LOG -m limit --limit 10/hour --log-prefix "IPTables-OTHER_IN: " --log-level 7
iptables -A OTHER_IN -j ACCEPT
iptables -N OTHER_OUT
#The following line can oly be used when the xt_limit kernel module is available
#iptables -A OTHER_OUT -j LOG -m limit --limit 10/hour --log-prefix "IPTables-OTHER_IN: " --log-level 7
iptables -A OTHER_OUT -j ACCEPT
iptables -A INPUT -g OTHER_IN
iptables -A OUTPUT -g OTHER_OUT
iptables -N REMOTE_SUPPORT_IN
iptables -I REMOTE_SUPPORT_IN -j ACCEPT
iptables -N REMOTE_SUPPORT_OUT
iptables -I REMOTE_SUPPORT_OUT -j ACCEPT
iptables -I OTHER_IN -s supporthost.victronenergy.com -g REMOTE_SUPPORT_IN
iptables -I OTHER_OUT -d supporthost.victronenergy.com -g REMOTE_SUPPORT_OUT
iptables -N VRM_IN
iptables -I VRM_IN -j ACCEPT
iptables -N VRM_OUT
iptables -I VRM_OUT -j ACCEPT
iptables -I OTHER_IN -s ccgxlogging.victronenergy.com -g VRM_IN
iptables -I OTHER_OUT -d ccgxlogging.victronenergy.com -g VRM_OUT
iptables -N UPDATE_IN
iptables -I UPDATE_IN -j ACCEPT
iptables -N UPDATE_OUT
iptables -I UPDATE_OUT -j ACCEPT
iptables -I OTHER_IN -s updates.victronenergy.com -g UPDATE_IN
iptables -I OTHER_OUT -d updates.victronenergy.com -g UPDATE_OUT
iptables -N PUBNUB_IN
iptables -I PUBNUB_IN -j ACCEPT
iptables -N PUBNUB_OUT
iptables -I PUBNUB_OUT -j ACCEPT
iptables -I OTHER_IN -s 54.246.196.128/26 -g PUBNUB_IN
iptables -I OTHER_OUT -d 54.246.196.128/26 -g PUBNUB_OUT
iptables -I OTHER_IN -s 54.93.127.192/26 -g PUBNUB_IN
iptables -I OTHER_OUT -d 54.93.127.192/26 -g PUBNUB_OUT
iptables -N NTP_IN
iptables -I NTP_IN -j ACCEPT
iptables -N NTP_OUT
iptables -I NTP_OUT -j ACCEPT
iptables -I OTHER_IN -p udp --sport 123 -g NTP_IN
iptables -I OTHER_OUT -p udp --dport 123 -g NTP_OUT
iptables -N DNS_IN
iptables -I DNS_IN -j ACCEPT
iptables -N DNS_OUT
iptables -I DNS_OUT -j ACCEPT
iptables -I OTHER_IN -p tcp --sport domain -g DNS_IN
iptables -I OTHER_IN -p udp --sport domain -g DNS_IN
iptables -I OTHER_OUT -p tcp --dport domain -g DNS_OUT
iptables -I OTHER_OUT -p udp --dport domain -g DNS_OUT
#Connman online check
iptables -N CONNMAN_IN
iptables -I CONNMAN_IN -j ACCEPT
iptables -N CONNMAN_OUT
iptables -I CONNMAN_OUT -j ACCEPT
iptables -I OTHER_IN -s ipv4.connman.net -g CONNMAN_IN
iptables -I OTHER_OUT -d ipv4.connman.net -g CONNMAN_OUT
==== Scripts ====
The configuration of iptables is normally lost between reboots. The following code should be placed in the file /etc/init.d/iptables.sh
#!/bin/sh
### BEGIN INIT INFO
# Provides: iptables
# Required-Start: $syslog
# Required-Stop: $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Set up iptables
### END INIT INFO
PATH=/sbin:/bin:/usr/sbin:/usr/bin
NAME=iptables.sh
DESC="iptables"
case "$1" in
start)
echo -n "Starting $DESC: "
if [ -e /var/run/iptables ]; then
echo "iptables is already started!"
exit 1
else
touch /var/run/iptables
fi
# Load saved rules
if [ -f /etc/iptables/rules ]; then
iptables-restore -c < /etc/iptables/rules
fi
echo "$NAME."
;;
stop)
echo -n "Stopping $DESC: "
if [ ! -e /var/run/iptables ]; then
echo "iptables is already stopped!"
exit 1
else
rm /var/run/iptables
fi
mkdir -p /etc/iptables
# Backup old rules
if [ -f /etc/iptables/rules ]; then
cp /etc/iptables/rules /etc/iptables/rules.bak
fi
# Save new rules
iptables-save -c > /etc/iptables/rules
# Revert to Default Policy
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
# Flush all rules and delete all custom chains
iptables -F
iptables -X
echo "$NAME."
;;
restart|force-reload)
echo -n "Restarting $DESC: "
$0 stop
$0 start
echo "$NAME."
;;
backup)
mkdir -p /etc/iptables
# Backup old rules
if [ -f /etc/iptables/rules ]; then
cp /etc/iptables/rules /etc/iptables/rules.bak
fi
# Save new rules
iptables-save -c > /etc/iptables/rules
;;
log-reset)
mkdir -p /log/iptables/
iptables -L -v -x -n -Z > /log/iptables/iptables-"$2"
;;
*)
N=/etc/init.d/$NAME
echo "Usage: $N {start|stop|restart|force-reload|backup|log-reset}" >&2
exit 1
;;
esac
exit 0
Then also execute the following command to make the script executable:
chmod +x /etc/init.d/iptables.sh
This allows shutting down the traffic counting using /etc/init.d/iptables.sh stop
and start it using /etc/init.d/iptables.sh start
.
When the traffic counting is stopped in this way, the current count values are stored together with the rules, allowing it to continue in the state it was stopped.
When the traffic counting should be started and stopped on startup and reboot of the GX device, the following commands should also be executed:
ln -s /etc/init.d/iptables.sh /etc/rc5.d/S04iptables
ln -s /etc/init.d/iptables.sh /etc/rc6.d/K50iptables
By adding the following line to /etc/crontab, the current rules and counts will be backed up every 10 minutes, protecting them more or less from hard resets:
*/10 * * * * root /etc/init.d/iptables.sh backup
==== Viewing the data ====
After executing these commands, the traffic is counted by iptables. The data can be viewed by giving the command
iptables -L -x -v -n
The following is an example output:
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
78 25590 ACCEPT all -- * * 0.0.0.0/0 255.255.255.255
1033 141226 ACCEPT all -- * * 0.0.0.0/0 224.0.0.0/4
0 0 ACCEPT all -- * * 192.168.0.0/16 0.0.0.0/0
15848 1778034 ACCEPT all -- * * 172.16.0.0/12 0.0.0.0/0
0 0 ACCEPT all -- * * 10.0.0.0/8 0.0.0.0/0
8438 660949 ACCEPT all -- * * 127.0.0.0/8 0.0.0.0/0
13432 2313739 OTHER_IN all -- * * 0.0.0.0/0 0.0.0.0/0 [goto]
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- * * 0.0.0.0/0 255.255.255.255
173 33763 ACCEPT all -- * * 0.0.0.0/0 224.0.0.0/4
0 0 ACCEPT all -- * * 0.0.0.0/0 192.168.0.0/16
16646 4024183 ACCEPT all -- * * 0.0.0.0/0 172.16.0.0/12
0 0 ACCEPT all -- * * 0.0.0.0/0 10.0.0.0/8
8438 660949 ACCEPT all -- * * 0.0.0.0/0 127.0.0.0/8
24853 7624844 OTHER_OUT all -- * * 0.0.0.0/0 0.0.0.0/0 [goto]
Chain CONNMAN_IN (1 references)
pkts bytes target prot opt in out source destination
11 960 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
Chain CONNMAN_OUT (1 references)
pkts bytes target prot opt in out source destination
10 758 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
Chain DNS_IN (2 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
Chain DNS_OUT (2 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
Chain NTP_IN (1 references)
pkts bytes target prot opt in out source destination
3 228 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
Chain NTP_OUT (1 references)
pkts bytes target prot opt in out source destination
39 2964 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
Chain OTHER_IN (1 references)
pkts bytes target prot opt in out source destination
11 960 CONNMAN_IN all -- * * 87.106.208.187 0.0.0.0/0 [goto]
0 0 DNS_IN udp -- * * 0.0.0.0/0 0.0.0.0/0 [goto] udp spt:53
0 0 DNS_IN tcp -- * * 0.0.0.0/0 0.0.0.0/0 [goto] tcp spt:53
3 228 NTP_IN udp -- * * 0.0.0.0/0 0.0.0.0/0 [goto] udp spt:123
0 0 PUBNUB_IN all -- * * 54.93.127.192/26 0.0.0.0/0 [goto]
0 0 PUBNUB_IN all -- * * 54.246.196.128/26 0.0.0.0/0 [goto]
0 0 UPDATE_IN all -- * * 185.24.223.128 0.0.0.0/0 [goto]
11808 2161730 VRM_IN all -- * * 46.19.32.79 0.0.0.0/0 [goto]
1610 150821 REMOTE_SUPPORT_IN all -- * * 77.72.145.194 0.0.0.0/0 [goto]
0 0 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 limit: avg 10/hour burst 5 LOG flags 0 level 7 prefix "IPTables-OTHER_IN: "
0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
Chain OTHER_OUT (1 references)
pkts bytes target prot opt in out source destination
10 758 CONNMAN_OUT all -- * * 0.0.0.0/0 87.106.208.187 [goto]
0 0 DNS_OUT udp -- * * 0.0.0.0/0 0.0.0.0/0 [goto] udp dpt:53
0 0 DNS_OUT tcp -- * * 0.0.0.0/0 0.0.0.0/0 [goto] tcp dpt:53
39 2964 NTP_OUT udp -- * * 0.0.0.0/0 0.0.0.0/0 [goto] udp dpt:123
0 0 PUBNUB_OUT all -- * * 0.0.0.0/0 54.93.127.192/26 [goto]
0 0 PUBNUB_OUT all -- * * 0.0.0.0/0 54.246.196.128/26 [goto]
0 0 UPDATE_OUT all -- * * 0.0.0.0/0 185.24.223.128 [goto]
21431 7309572 VRM_OUT all -- * * 0.0.0.0/0 46.19.32.79 [goto]
3373 311550 REMOTE_SUPPORT_OUT all -- * * 0.0.0.0/0 77.72.145.194 [goto]
0 0 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 limit: avg 10/hour burst 5 LOG flags 0 level 7 prefix "IPTables-OTHER_IN: "
0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
Chain PUBNUB_IN (2 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
Chain PUBNUB_OUT (2 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
Chain REMOTE_SUPPORT_IN (1 references)
pkts bytes target prot opt in out source destination
1610 150821 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
Chain REMOTE_SUPPORT_OUT (1 references)
pkts bytes target prot opt in out source destination
3373 311550 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
Chain UPDATE_IN (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
Chain UPDATE_OUT (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
Chain VRM_IN (1 references)
pkts bytes target prot opt in out source destination
11808 2161730 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
Chain VRM_OUT (1 references)
pkts bytes target prot opt in out source destination
21431 7309572 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
The second column of the lines
13432 2313739 OTHER_IN all -- * * 0.0.0.0/0 0.0.0.0/0 [goto]
and
24853 7624844 OTHER_OUT all -- * * 0.0.0.0/0 0.0.0.0/0 [goto]
show the incoming and outgoing traffic (in bytes) that is not for the local LAN. This is roughly the traffic that would normally be counted by the provider.
The lines under Chain OTHER_IN
and Chain OTHER_OUT
show the amount of traffic used by the different services running on the GX device.
The following line also resets the counters (besides showing the current values):
iptables -L -x -v -n -Z
Warning: The current values are not stored anywhere and thus are lost!
By adding the following line to /etc/crontab, the overview is stored per day in /log/iptables/iptables-YYYY-MM-DD-HH-MM-SS and the counters reset, giving a traffic counting per day:
@daily root /etc/init.d/iptables.sh log-reset $(date +\%F-\%H-\%M-\%S)