Dec 102020


For my home network I’m using Docker based TICK stack with Graphana. I was looking for a way of pulling some stats from my OpenWRT based router, injecting them into Influxdb and then using Graphana to plot nice graphs. Here is what I did in order to make it work.

Router – IPtables Rules

Firstly, we need to add iptables rules on OpenWRT router to start counting packets and data going through it. An appropriate lines need to be added to file /etc/firewall.user on OpenWRT router, here is an link to example lines. Or lines can be generated for your subnet with the following command, obviously changing subnet part:

for i in {1..254};do echo iptables -t mangle -A FORWARD -d 192.168.0.$i;done

Yes, as you note we create probably more rules than we have devices on the subnet, it doesn’t really make any harm as far as I’m aware.

Router – Processing Script

Right, so we started counting traffic going through router. Next step is to prepare script that parses data gathered by iptables. Save the following code to file /bin/


# get the data
# get only info for IP where there is some traffic recorded, discard else
iptables -nvx -t mangle -L FORWARD | grep "all" |grep -v "       0        0" > /tmp/datadump.txt
echo {
for host in `awk '{print $7}' $DATAFILE |sort |grep -v ""|uniq` 
    grep $host $DATAFILE | while read line;
        seventhfield=$(echo "${line}" | awk '{print $7}')
        eighthfield=$(echo "${line}" | awk '{print $8}')
        # work out the direction
        if [ $seventhfield != "" ]; then
                #the direction is outbound from the ip in the seventh field
                # directionOut='out'
                #work out the bytes
                bytesOut=$(echo "${line}" | awk '{print $2}')
        if [ $eighthfield != "" ]; then
                #the direction is inbound to the ip in the eighth field
                # directionIn='in'
                # ip=$eighthfield
                #work out the bytes
                bytesIn=$(echo "${line}" | awk '{print $2}')
        statement="\"$host\": { \"in\": $bytesIn, \"out\": $bytesOut }," 
        echo $statement

echo '"": { "in": 0, "out": 0 }'
echo }

and make is executable with

chmod +x /bin/ 

This is simple code to gather stats for IPs on internal network from OpenWRT based router, based on the following post
with minor tweaks to meet my needs. Instead of pushing gathered data to SQL database as per original post I send it in JSON format to web served directory. It is then consumed by Telegraf service which is pulling data into Influxdb. All credit for the idea goes to the original poster nicknamed nexus.

Router – Cron Job

Next step is to execute script every say 5 minutes, we use cron for that. Edit /etc/crontabs/root and paste the following into it:

*/5 * * * * /bin/ | grep -v '\"in\"\: \,' > /www/trafficCounters.json

As you can see we take advantage of web server service that is installed on router to provide it’s web interface. We put trafficCounters.json file in web directory.

Router – Test json File

Your stats file should be now refreshed every 5 minutes and available under:

assuming is your router address.

Telegraph – Consuming Data

I’m using Docker based TICK stack with Graphana. Here is my stack definition:

version: '3.7'
    image: telegraf
    - source: telegraf-conf
      target: /etc/telegraf/telegraf.conf
    - 8186:8186
    - /usr/share/snmp/mibs:/usr/share/snmp/mibs
    - /var/lib/snmp/mibs/ietf:/var/lib/snmp/mibs/ietf
    image: influxdb
    - 8086:8086
    - /tank/appdata/influxdb:/var/lib/influxdb
    image: chronograf
    - 8888:8888
    command: ["chronograf", "--influxdb-url=http://influxdb:8086"]
    image: kapacitor
    - KAPACITOR_INFLUXDB_0_URLS_0=http://influxdb:8086
    - 9092:9092

    name: telegraf.conf-20201107-03
    file: ./telegraf.conf

and here goes telegraf configuration, note inputs.http section

# egrep -v '#|^$' telegraf.conf
  interval = "5s"
  round_interval = true
  metric_batch_size = 1000
  metric_buffer_limit = 10000
  collection_jitter = "0s"
  flush_interval = "5s"
  flush_jitter = "0s"
  precision = ""
  debug = false
  quiet = false
  logfile = ""
  hostname = "$HOSTNAME"
  omit_hostname = false
  urls = ["http://influxdb:8086"]
  database = "test"
  username = ""
  password = ""
  retention_policy = ""
  write_consistency = "any"
  timeout = "5s"
  service_address = ":8186"
  percpu = true
  totalcpu = true
  name_override = "openwrt"
  urls = [
  data_format = "json"

we can now deploy TICK stack with

docker stack deploy tick -c tick.yml

Checking Stack Components

Using Chronograph running on port 8888 we can now explore content hopefully getting into Influxdb. We can also checks logs for any obvious errors if data is not getting through

# list all containers
docker ps

# check influxdb logs
docker logs --tail 50 docker ps|grep influxdb|awk '{print $1}'

# check telegraf logs
docker logs --tail 50 `docker ps|grep telegraf|awk '{print $1}'`

Graphana Dashboard

Last step is to create graphs and then put it on a dashboard in Graphana, using data from Influxdb. Plenty of howtos online for this part so I won’t be repeating this here, will just put screenshot or two to show you what I’m using it for:


That would be really it. It’s very basic and rather rudimentary but it does the job. I keep code for this on GitHub here so please feel free to take a look and contribute with your improvements should you have any. Thanks very much in advance.