rlm_backcounter
About
rlm_backcounter manages various counters which count back and are periodically resetted to some value. These counters can be defined eg. for whole user group, but with values and reset intervals specific for each individual user.
There is also additional "prepaid" counter, which can be set to any value from outside of rlm_backcounter - the module only decreases it.
This module can be used to eg.
- limit monthly bandwidth usage, with uniform distribution of counter resets during month (ie. to overcome excessive network usage when all users have their counters resetted on the same day),
- implement prepaid accounts,
- put your clients' network traffic into various QoS/SLA classes depending on their network usage.
How it works
- authorization
- note: why this section? because it's far more easier in FreeRADIUS to react as soon as possible, and to do this basing on attributes in request instead of reply packets
- if the counter of the user we're handling request for should be resetted:
- set the counter to the value defined in user's reply attributes (fetched from database), or if these don't exist, in group's reply attributes
- set reset time to current value + period defined in module instance-wide configuration, making sure it's greater than current time moment
- fetch current counter values and check if their sum is greater than zero:
- if user is under limit, set session "guard VAP" to the counter value (if configured to do so)
- otherwise, add a new VAP to the request packet or simply send back an access rejection
- accounting of Accounting-Stop packets
- decrease counters in configurable manner:
- use sum of values in given VAPs as decrement
- let the administrator choose whether to decrement the prepaid or the "monthly" counter first
- decrease counters in configurable manner:
Configuration
For instance, this is how to create a monthly transfer limit.
In radiusd.conf, create module configuration:
modules {
# (...)
backcounter transfer-limit {
# name of rlm_sql module instance to connect to
sqlinst_name = "sql"
# what to count in accounting packets
count_names = "Acct-Input-Octets, Acct-Output-Octets"
# VAP in which to send the amount which is left
guardvap = "Session-Octets-Limit"
# reset counters each 30 days
period = 2592000
# monthly transfer limit, in bytes
limitvap = "Monthly-Transfer-Limit"
# time of next reset for this particular user
resetvap = "Monthly-Transfer-Reset"
# VAP to set in *request* to 1 if the user has reached his limits
overvap = "Monthly-Transfer-Exceeded"
# transfer left - monthly, prepaid
leftvap = "Monthly-Transfer-Left"
prepaidvap = "Monthly-Transfer-Prepaid"
# which counter to decrease first
prepaidfirst = yes
}
}
Then, instantiate it after rlm_sql:
instantiate {
# (...)
sql
transfer-limit
# (...)
}
Put it in the authorize section:
authorize {
# (...)
sql
transfer-limit
# some module to restrict bandwidth if overvap is set, eg.:
# users
# (...)
}
And anywhere in the accounting section:
accounting {
# (...)
transfer-limit
}
Add new attributes in the dictionary file:
# (...) # string, because integer's 2^32 may not be sufficient ATTRIBUTE Monthly-Transfer-Limit 3100 string ATTRIBUTE Monthly-Transfer-Reset 3101 integer ATTRIBUTE Monthly-Transfer-Exceeded 3102 integer ATTRIBUTE Monthly-Transfer-Left 3103 string ATTRIBUTE Monthly-Transfer-Prepaid 3104 string # strange, but it's not in official FreeRADIUS dictionary ATTRIBUTE Session-Octets-Limit 227 integer
If you wish to limit bandwidth usage on eg. a Lintrack router, add this to your users file (some modifications depending on local configuration may be required):
DEFAULT Monthly-Transfer-Exceeded == 1 Reply-Message = "You have reached your monthly bandwidth limit", ASN-Kbps-Down := 64, ASN-Kbps-Up := 64
Current limitations (maybe-to-be-done list)
- probably works only with MySQL
- a bit too "hardcoded"
- queries and tables names not configurable
- low-level access to database
- handles only at most 32-bit counters for single sessions (but using counters of "any" size in database is possible)
