FlowMonitor is a flowscan module designed to let you specify a bandwidth usage policy per IP and obtain lists of IPs whose usage violates that policy. These lists can then be used to do things like rate-limit or black-hole the offending addresses.

FlowMonitor requires a SQL database backend. Initial revisions were written with a filesystem backend, but this proved problematic with the usage our campus was seeing (approximately 10k unique IPs in a 5 minute sample, approx 120k total IPs). We use Oracle, but any DBD module that works with Perl should also work.


   $ flowscan FlowMonitor

or in ReportClasses FlowMonitor

DESCRIPTION creates text file lists of IP addresses, one per line, of IP addresses. Which IP addresses go into which file is determined by your file (detailed below)

CONFIGURATION reads, which should be located in the same directory as your flowscan binary.

Each Subnet entry in the file is an IP/length pair that represents a local subnet. E.g.:

        # Subnet for main campus

Add as many of these as is necessary. FlowMonitor assumes that flows will either have a source address in a one of the declared Subnets, or a destination address there, but not both. (Ie, FlowMonitor should be used on flows collcted from a boundary router whos traffic we are interested in policing). FlowMonitor will keep records on the usage of all IPs it sees in flow records whose source or destination IP is in a Subnet statement.

A Router statement looks like:

        # Only interested in traffic from nyser-gw

You need to put a Router statement in you for every exporter through which you wish to police traffic. Note if you have more than one Router, your Policy statement will refer to total bandwidth through all listed Routers. Per-Router policies and violation files may be in a forthcoming release, but for now, FlowMonitor enforces a single policy over one or more exporters.

A Policy statement looks like:

        # Policy is limit upload to 100Kb/sec
        Policy Outbound 8640000000 86400

The first argument determines which bytes we count for an individual IP. Allowed values for this argument are Inbound, Outbound, or Both. The Inbound policy only counts flows whose destination address is contained in a range defined in a Subnet statement. The Outbound policy only counts flows whose source address is defined in a Subnet statement. The Both policy totals bytes when either the source or the destination address is in a Subnet statement.

The second argument is the number of bytes allowed per IP. The third is the number of seconds over which they are allowed to use those bytes. The above policy says that over 86400 seconds (1 day), an individual IP address is allowed to use 8,640,000,000 bytes (8.6Gb/day, roughly 100Kb/second).

DBName specifies the name and type of a database used to store per-IP usage information in. That database should have a table in it created as

create table iplogs ( ipaddr varchar(16), bytes number(16), starttime date, constraint iplogs_ct unique(ipaddr) );

making sure that the user FlowMonitor will be running as has permissions to insert, delete and modify from this table.

        # Store records in oracle database acisora1
        DBName Oracle acisora1

The first parameter should be the name of the DBI module perl should use to contact the database whose name is the second parameter. Currently, we do not support a username and password to bind with.

Violators statements are used to log violators of the policy. The syntax of a Violators statement looks like

        # People at 50% over policy get logged to 50percenters
        Violators 50 /var/log/50percenters
        # People at 100% over policy get logged to 100percenters
        Violators 100 /var/log/100percenters
        # People at 200% or more over policy go to losers
        Violaters 200 /var/log/losers

Each IP will only appear in 1 file, so someone at 100% over the policy (in the above example) will *not* appear in the 50percenters file, only the 100percenters file. Anyone whose percentage of usage is higher than the highest percentage in a Violators statement gets logged in the highest percentage file.

Carry-Forward is a directive designed to help smooth out hosts going into and out of violation every time their quota interval expires. If Carry-Forward is set, an IPs usage is not eliminated every time their quota interval passes, it is reduced by a Quotas worth of bytes. Ie, if your Quota is 100 megabytes every hour, and IP has 120 megabytes worth of usage at the end of its hour, instead of starting the next hour with 0 usage, it will start with 20 megabytes worth. If it ended its hour with 200 megabytes used, it would start the next hour with 100 megabytes used, and be in violation immediately.

Note that Carry-Forward will only carry one intervals worth of quota ahead, so an IP will never start a new interval with more than 1 intervals quota. To continue the above example, if finished an hour with 300 megabytes of usage, it will still only begin the next hour with 100 megabytes of usage, as that is one intervals quota. This way of implementing Carry-Forward was chosen because in an environment where IPs are assigned dynamically, or more than one person can use a given IP (ie, a computer lab), we did not want to unduly penalize a given IP for more than 2 quota intervals. Note that if a given host is continually using more than 2 times its quota every interval, it will always be in violation.

An Ignore statement is a netblock that you do not wish to have listed in the Violators files (because it is a known source of traffic, it is legitimate, or whatever). These statements take the form

        # Ignore our webserver
        # Ignore machine room hosts

You may have as many Ignore statements as you wish.

This statement just makes FlowMonitor write out a list of its currently Ignored hosts to a text file once per flow. It looks like

        # Ignores to ignorelist.txt
        IgnoreList /var/www/html/ignorelist.txt

This file is truncated before writing; it is not a log file, it is a list of the current ignores. If you do not include this statement, no list will be produced.

A Logfile statement provides a way to track who was in what file at what time. It takes the form

        # Log bad people to /var/log/mon-history
        Logfile /var/log/mon-history

If you have no Logfile statement, FlowMonitor will not log when people enter Violator groups.


It would be nice to have a file that contained the blocks to ignore. Then we wouldn't need a separate IgnoreList directive.

Database handling is pretty messy.

Carry-Forward should be more configurable.


Johan Andersen


Please contact to get help with FlowMonitor.