How to limit a user to a given amount of traffic?

To put a firewall rule before another one, add place-before=[/ip firewall filter find comment=“aaa”] parameter. (Of course, there should be a rule with
comment=aaa already added to the firewall filter).

To stop the scheduler:

/system scheduler disable [find]

:sunglasses:

I resolve stop scheduler , but for position of rule … I put rule in chain of accounting (one chain for one user , easy to reset when reach limit), because rule in accounting chain is passthrough , new rule stop traffic even on the end of the chain , (work for me)

now I put, place-before=[/ip firewall rule user1 find comment=“aaa”] , works, thanks

script:

:local sum; :local traf;
:set sum 0
/ip firewall rule user1 {
:foreach i in [find] do={:incr sum}
:for i from=1 to=$sum do={
:set traf [get [find comment=(“user” . $i)] bytes]
:set traf ($traf/1073741824)
:if ($traf>0) do={ /ip firewall rule user1 add action=reject place-before=[/ip firewall rule user1 find comment=“aaa”]
/tool e-mail send to=user1@example.com subject=“Limit-exceeded”}
}
}


this is the script for reach limit , but … can you tell me, how make script for send mail on every 24h to user with amount of traffic at this moment, … something like ,

scheduler with sorce: /tool e-mail send to=user1@example.com subject=“You spend ([get [find comment=(“user” . $i)] bytes]/1024) KB till now.”

But, in accounting chain user1, I have 2 rule comment=user1(for Upload) and comment=user2 (for Download) , main script start whatever rule reach 1gb , and stop traffic and send mail , that is ok for reach limit…

Now I want make script to send info about traffic on both rule (upload and download) (comment=user1 and comment=user2) to user on every 24h

can you help ?

Thanks again.

:local sum; :local traf;
:local limit
:set sum 0
:set traf 0
:set limit 5
/ip firewall rule user1 {
:foreach i in [find] do={:incr sum}
:for i from=1 to=$sum do={
:set traf ([get [find comment=("user" . $i)] bytes] + $traf)
}
:set traf ($traf/1073741824)
:set limit ($limit-$traf)
/tool e-mail send to=user1@example.com subject="You spend $traf GB. Beware! only $limit GB left :)"
}

message from log : script error: invalid expression

:local sum; :local traf;
:local limit
:set sum 0
:set traf 0
:set limit 5
/ip firewall rule user1 {
:foreach i in [find] do={:incr sum}
:for i from=1 to=$sum do={
:set traf ([get [find comment=("user" . $i)] bytes] + $traf)
}}
:set traf ($traf/1073741824)
:set limit ($limit - $traf)
/tool e-mail send to=user1@example.com subject="You spend $traf GB. Beware! only $limit GB left :)"
  1. There should be spaces surrounding minus sign.
  2. Outer loop closed before sending e-mail (to avoid duplicates).

I recived in log: invalid argument name , somethin about $traf and $limit in …

/tool e-mail send to=user1@example.com subject=“You spend $traf GB. Beware! only $limit GB left :)”

when I delete all in subject except $traf ,
/tool e-mail send to=user1@example.com subject=$traf , …

mail recived with 0 in subject , all same with only $limit mail recived with 5 , every time. when send mail,

probably from here:

:set traf 0
:set limit 5

This one tested and works:

:local sum; :local traf; :local limit; 
:set sum 0; :set traf 0; :set limit 5; 
/ip firewall rule user1 {:foreach i in [find] do={:incr sum}; :for i from=1 to=$sum do={:set traf ([get [find comment=("user" . $i)] bytes] + $traf)};}; :set traf ($traf/1073741824); :set limit ($limit - $traf); /tool e-mail send to=psi@mikrotik.com subject=("You spend " . $traf . " GB. Beware! only " . $limit . "GB left :)");

Yes work,

but send message only for GB , maybe I make some mistake with rule,

never mind , it’s help me to make my script , and the script do exactly what I want , thanks

but , there is another problem, and it’s seems big , … when mikrotik is off or restart or corrupt … , rule reset to 0 … and accounting start from 0, :frowning:

till now I have no that problem , to reset ruter, because some error, but … life is long , :slight_smile:

is there some solution for that ?

Thanks again

Only remote accounting. Or you can restart router only on the 1st day of month :slight_smile:

BTW, the router is pretty stable so having a good UPS should give you loooong uptime :smiley:

Or make a script to save/restore values do disk.

that’s will be good, but, can script, save (ie.) all data in some rule (ie.) user1 , and restore when ruter startup, I think hotspot do that … ?

I prefer script opposite hotspot , if is posible to script do that ?

One way to save variable values is to create /ppp secret entries with comments. But IMHO you need to switch ro remote accounting/management like RADIUS.

solution is ups , for now , …

do you have idea how do this: …

Can script, (make or disable) rule in MT through 2 or 3 or X … MT (mikrotik)?

internet <—> MT1 <—> MT2 <----> MT3 <— client

script for internet traffic accouting are on MT1 ,
I wish , make new deny or disable present allowe rule in firewall on MT3 to stop all traffic through network for client who connect on MT3 , but from information of traffic on MT1 for that client.

do this on MT1 is done for internet traffic , but is there any solution to do this on MT3 , when client reach limit accounting on MT1 ?

something like this :/ip firewall rule forward disable (ie.) 10 … , but , script on MT1 to make this on MT3 , or script on Mt3 read data of traffic on MT1.

any idea ?

I know some bizarre ways to achieve this with mt scripting, but you should really think about a dedicated server or a complete network redesign if you need such things.

Eugene

Why do we count bytes on the firewall , when every queue has the statistics of rx and tx bytes, and total-bytes???

Can this be achieved in an simplier way by reading the total-bytes of the queues???

Let’s say I give my clients 256k/128k connections, but if they make 200Mb of transfer during the day they speed will be limited at 64k/64k.

The counters should be reseted every day at lets say 00:00 oclock via the scheduler. (/que simple reset-counters)

And there should be one script which will run every 5 minutes or so to check the bytes of every queue and set max-limit=64000/64000 if the total-bytes of the queue are >= 200MB

Is this possible or am i missing something??

Yes, it’s possible. Although I’d recommend using queues with bursts for this task. Just imagine: no scripting needed at all :wink:

The burts will give another meaning, sure it will help them not using the maximum of the allowed speed for a long time but what I need is limited amount of download until they speed cuts down.
Let them feel thay have a high speed connection, but prevent them downloding too much.

Since this is doable, and i never done scripts , i tried it a little but i cant make it work for this job, can someone help me with a simple script that scans all the simple queues for a ‘total-bytes’ amount, and if the total-bytes is equal or biger than 200MB then max-limit the queue at 64k/64k.
I would appriciate that,
Thanks

Urim.

Well, bursts do exactly that. They will prevent users from downloading big amounts of data in the same time permitting high speed low volume traffic.

Well,ok since you insist.
But still im interested doing that with reading total-bytes of the queues.
Any help would be appreciated.


P.S
This is like a FAP(Fair Access Policy) like some satelite providers give. They give you 512kb speed, but if you dowload 500 mb during the day, your speed will be capped to 128kb, and countinuing to lower your speed as your transfer amount increases.

Queue:

/queue simple add target-addresses=<address of host you want to limit> name="user1"

Script:

:local sum; :local traf;
:set sum 0
/queue simple{
  :foreach i in [find] do={:incr sum}
  :for i from=1 to=$sum do={
    :set traf [get [find name=("user" . $i)] total-bytes]
    :set traf ($traf/1073741824)
    :if ($traf>1) do={
      :log facility=System-Info message=("user" . $i . " exceeded 1Gb limit!");
      set [find name=("user" . $i)] max-limit=64000
    }
  }
}

problem with reset accouting , after reboot , power lost … is resolve in 2.9.8 … or not ?