Sharing a script I wrote for tracking monthly per-IP (technically, per-MAC) WAN traffic statistics. The script reads traffic counters from Kid Control, stores them in a JSON file, and produces an HTML report.
Everything is local on the router. You don’t need any external servers or software to collect the data. You only need a computer to view the report.
Best if used with a USB flash drive to avoid any worries about write cycles. If your device doesn’t support external storage, you could schedule the script to run less frequently at the expense of more statistics loss when unexpected reboots take place.
Detects manual traffic counters resets as long as Rx counters are less than previously stored Rx value. If you intend to reset the counters, just run the script manually right before and after the reset to retain maximum accuracy.
Uses Kid Control functionality in RouterOS, which has a nice bonus—tracking per-IP traffic.
Limitations
Requires RouterOS 7.18.2+. This is important because the script uses some newer scripting features.
Kid Control counts all routed traffic, not just WAN (e.g. inter-VLAN). Potentially you could re-write the script and use something like viewtopic.php?t=168427 instead of Kid Control.
RouterOS doesn’t support floating point, therefore reporting accurracy is +/-1GB. Calculation and saving is done in bytes, so there are no repeated rounding losses. The rounding (or rather truncating) happens only at the last step when the report file is produced.
Detects reboots by placing a marker file in the root directory which is a RAM/tmpfs disk on many devices; for devices with no RAM disk by default, set up your own and specify the path for the marker file.
To retain maximum accuracy, run the script just before a manual reboot to collect the data.
How to use
Configure Kid Control to track traffic. With configuration below it doesn’t limit anything, only enables tracking.
You read the report by downloading it to your computer and removing .txt, so that the resulting file is report-2022may.html (for May). Then you can open it in any browser. It’s a basic HTML with JavaScript leveraging Google Charts.
You are correct, the script doesn’t do any magic and fully relies on kid-control to provide the data. The main point is storing the data persistently without anything external. And also presenting the data in a friendly format. It is especially useful for users who don’t have any servers/Raspberry PI’s/NAS/etc running somewhere to collect the data. It’s very simple to set up, just copy and paste the script.
Ideally, if RouterOS had the ability to serve custom static web pages, then it would be possible. Like I mentioned above, the branding package might do this but I haven’t looked into that.
VERY interesting feature of kid-control. Replacing “IP accounting” ?
TXS for the script!
HOW to get the authenticated user (RADIUS) into this Kid-Control device list ?
(Wifi AP authenticated via WPA2/Enterprise, Username value can be copied into Radius “MT Comment” attribute with User Manager 5, and remains visible in the Registration table, as long as the device is connected. DUDE collects in “RouterOS Info” all registration tables, including the comment field)
The username/password is stored in the client device, and is never entered again for the same SSID. So this should be acting as automated RSSO (Radius single signon).
But how to make Kid-control or Hotspot pick up this signon ?
If you downloaded the script before July 23 2022, please update line 35 from:
:local ip [get $device ip-address]
# To
:local ip [:tostr [get $device ip-address]]
I recently ran into issue with traffic counter overflow on the report, messing up all statistics. It turns out when a device has multiple IP addresses, the script was grabbing wrong fields for traffic counters. The issue is resolved by forcing the whole IP field to a string.
@bpwl I’ve never used RADIUS - wouldn’t that authenticated user device get an IP from DHCP server? I don’t know exactly how kid-control works under the hood, it seems to simply pick up devices by MAC address. Presumably anything that goes through the firewall, which is why it also counts traffic from one local VLAN to another. So as long as that user sends some traffic, it should be on the list. The difficult part is identifying who is who. If the device doesn’t register a name with DHCP server, then only MAC and IP are shown. And with many phones (like Apple) periodically changing their MAC address, it becomes impossible to identify all devices accurately. So kid-control is quite a limited feature, but works well in simple configurations with mostly fixed number of devices.
That’s why I use RADIUS with EAP/PEAP wifi authentication (= username/password).
The data is stored once in the device (until you 'forget" the wifi network in the known wifi network list.)
Limits are then per user. Hotspot login does the same but with many APP as primary use, the browser popup for logging in is sometimes missed. And Hotspot cookies are just a means for avoiding repeated login actions for the same MAC.
Whatever they do with the private MAC addresses, the user identification with EAP/PEAP is dependent on the stored login credentials only.
RADIUS accounting would collect the usage per user, but that is mostly all (wifi) traffic, and the interesting part is the WAN usage only.
RADIUS could give a specific range of IP addresses to one user. But when you have multiple network segments (eg VLAN) then it becomes more difficult.
RADIUS could also force a specific VLAN for a user.
RADIUS can be used for VPN, DHCP, Hotspot, wifi, and other services. But afaik only the wifi is persistent. (The device connects with that user without any interaction of the user, even when not around for more than a year, and when it comes with a different private MAC address.)
RADIUS itself is a bid special in this. Is some device authenticated to what user or IP address? Is not easy to tell.
RADIUS authentication is an event, that in the best case gets logged, username and MAC address of the AP. (not the client), in my case.
De-authentication in de most cases does not involve the RADIUS server. (There is CoA, but mostlly the wifi disconnects, “reason=3” by AP, “reason=8” by roaming client, extensive data loss (client is gone or out of range?)) So the RADIUS authenticator cannot tell if a user is still authenticated or not, and does not have the IP address of the client.
The AP maintains the registration (on MAC address) but does not register the user used for the authentication.
The way RADIUS knows about the disconnect is through the RADIUS accounting. (User name , IP address, MAC address, quota consumed). But RADIUS misses sometimes an accounting record.
Actually I’m using the old MT User Manager for collecting RADIUS accounting, even with another RADIUS server doing the authentication.
Reason is that MT limits the number of accounted sessions to 19, for a L4 license. Accounting updates is set to someting like every 10 minutes.
RADIUS authentication is quite central, for multiple AP, so the number of active sessions is likely above 19. Even L5 only allows for 50 sessions.
I have 10.000 RADIUS authentications per day, caused by 40 named users, 100 client devices on 34 MT AP. There is a lot of roaming in that large 1 km2 area, also between 2.4 and 5GHz on the same AP. (Playing kids, indoor/outdoor swap, …)
Roaming can be every few seconds, and takes a split second. But steady clients their connections remain active for multiple days.
DHCP lease in this does not interfere (roaming does not renew the lease). Lease time is 24h, most client devices keep the same IP for the whole holiday stay period.
All data is there, but not correlated. DUDE collects the logs from (non-MT) RADIUS server, (non-MT) DHCP server, and MT AP’s.
MT User manager only can follow 19 Active sessions with license level L4, via RADIUS accounting.
I encountered another bug with the script. One device that showed up in kid-control didn’t have an IP address. That empty field was screwing up the report. I added the fix to the attached script above. It’s just one new line.
:if ([:len $name] = 0) do={ :set $name "unknown" }
:local ip [:tostr [get $device ip-address]]
:if ([:len $ip] = 0) do={ :set $ip "no-ip" } <== new line
:local down [get $device bytes-down]
:local up [get $device bytes-up]
The script uses the current date to produce the txt filenames, which are then used for generating the report. You can make a copy of the script and edit the line:
:local sysdate [/system/clock/get date]
Change it to a static date for older month. The format is jan/04/2023.
As far as Kid Control goes, that data gets reset every time the script runs. So what you see there is only new data since the last run.
So this works for me out of 3 of 4 Mikrotik(2 x RB3011 and 2 x RB1100AHx4) devices that i currently run them
The 4th one(RB1100AHx4) keeps giving me this error for the last 3 months
The only result generated in the html is below
Does anyone has any idea what is the error? All the boxes were running ROS 7.6 and now ROS 7.7
<html><head>
<script type='text/javascript' src='https://www.gstatic.com/charts/loader.js'></script>
<script type='text/javascript'>
google.charts.load('current', {packages: ['corechart', 'bar']});
google.charts.setOnLoadCallback(drawMultSeries);
function drawMultSeries() {
var data = google.visualization.arrayToDataTable([
['Device', 'Download', 'Upload', 'Total'],
failure: new contents too long