IPA.CONF(5) IPA.CONF(5)
NAME
ipa.conf -- ipa(8) configuration file
DESCRIPTION
The ipa.conf file is a configuration file for ipa(8). This file or any
other one, specified in the -f option in the ipa(8) command line, is
read when ipa(8) starts working or receives a SIGHUP signal.
FILE FORMAT
The ipa.conf file can be quite simple and can be complex enough. The
main idea is to place as much as possible into configuration file(s)
instead of writing external programs to do accounting related tasks.
This manual page contains complete file format description and complete
documentation about all features of ipa(8).
Almost after each paragraph there is an example. Since IPA distribution
does not have any module, ipa_ipfw, ipa_ip6fw, ipa_atest and ipa_db_sdb
modules are used in examples, just because they were the first modules
designed for IPA.
General syntax.
Any logical line in the configuration file can be written in several
text lines for indenting purpose. There is not any rule in which line
to place reserved words, arguments and special symbols. If some format
allows one space character (a space character and a tab character),
then as much as needed space characters can be written there for
indenting. All elements in a configuration file are case sensitive. A
configuration file consists of sections, parameters and comments.
Comments.
There are shell-like and C-like comments. If you use a C-like comment
in a shell-like comment, then a C-like comment is ignored.
Example:
# Shell-like comment.
/* C-like comment. */
/*
* Another C-like comment.
*/
Sections and parameters.
A section consists of its name, optional arguments and its body. A sec-
tion's body should be placed in curly braces:
section [[=] argument] {
/* Parameters and sections. */
}
A parameter consists of its name and optional arguments. Every parame-
ter should have the `;' character at the end of its arguments list:
parameter [[=] argument];
The `=' character after the section's or parameter's name is optional.
Some parameters look like variables (it is naturally to use the `='
character for such parameters), another ones look like instructions. In
any case, you can choose a syntax you like more.
An argument can contain strings:
"string"
It is possible to use ``\t'', ``\n'', ``\\'' and ``\"'' sequences to
represent tab, newline, back-slash and double quote characters inside a
string. If it is needed to split a string to several lines, then use
one `\' character at the end of the current line (do not put extra
space characters after the back-slash character). If a string is writ-
ten in several lines without `\' characters, then each newline charac-
ter is added to a string.
Macro variables.
It is possible to define macro variables and then use them almost any-
where in the configuration file:
${variable} = "string";
A name of any macro variable can consist of characters, digits and dol-
lar signs. What is a character is checked with isalpha(3) function,
which uses locale.
A value of any macro variable should be a string, when a macro variable
is expanded then first and last double quotes of its value are removed.
Macro variables can be local or global. A macro variable is global if
it is defined outside any section, else a macro variable is local. A
local macro variables are local for all nested sections and for all
external sections. Local macro variables can hide global ones.
There are some predefined macro variables:
${$} - expands to a `$' character;
${rule} - expands to the name of current rule section;
${limit} - expands to the name of current limit section;
${sublimit} - expands to the name of current sublimit section;
${threshold} - expands to the name of current threshold section;
${autorule} - expands to the name of current autorule section.
Any macro variable (including predefined ones) except ${$} can be rede-
fined if needed. It is not recommended to redefine or delete prede-
fined macro variables in modules.
Macro variable ${$} cannot be used for constructing macro variables
names (see an example).
Macro variables are expanded at the moment of their usage and not at
the moment of their definition. Macro variables are expanded also in
strings. Macro variables is a feature of the internal configuration
file parser, so ${rule} macro variable cannot be used in autorules and
in rules patterns (see information about substitutions in command
strings).
Example:
${a} = "${b}"; # Definition of ${a}.
${b} = "1"; # Definition of ${b}.
param = ${a}; # Expands to 1.
${b} = "2"; # Redefine ${b}.
param = ${a}; # Expands to 2.
param = "${$}{b}"; # Expands to "${b}" (sequence of characters
# inside string).
section {
${a} = "1"; # Definition of local ${a}, which hides
# global ${a}.
${c} = "4"; # Definition of local ${c}.
param = ${a}; # Expands to 1.
subsection {
${a} = "2";# Redefine local ${a}.
${b} = "3";# Redefine global ${b}.
}
param = ${a}; # Expands to 2.
param = ${b}; # Expands to 3.
}
# param = ${c}; <-- Error: ${c} is not defined as global.
Including files.
It is possible to keep configuration information in several configura-
tion files. Files are included with the help of following parameters:
include "/path/file";
include_files "/directory/pattern";
The include parameter includes one file. The include_files parameter
includes some files from the specified directory, names of which match
the given shell pattern.
These parameters can be used anywhere in the configuration file, except
inside modules' sections, and included files will be included at once.
It is possible to include files from included files, and so on. Each
included file should have correctly specified parameters with argu-
ments, comments and sections with arguments, but it can have not closed
sections.
It is possible to use POSIX extended regular expressions as patterns in
include_files parameters, for this set the posix_re_pattern parameter
to ``yes'' before parameters, which include files with POSIX regular
expression patterns, by default the value of this parameter is ``no'':
posix_re_pattern = <boolean>;
This parameter should not be placed in any section.
Included files must be owned by the user, who run ipa(8) and must not
be writable for group and other users. If files are included with the
help of the include_files parameter, then a directory in this parameter
also should have the same properties.
Examples:
posix_re_pattern = yes;
include "/usr/local/etc/ipa.local.conf";
include_files "/usr/local/etc/ipa/LAN/.";
First parameter includes one file, second parameter includes each file
in the given directory, the ``.'' POSIX regular expression means any
character.
/* posix_re_pattern = no; */
include_files "/usr/local/etc/ipa/LAN/*";
Here a shell pattern is used. First string should be uncommented if
previously POSIX regular expressions were used.
Using accounting modules.
There are special accounting modules, which are used for gathering sta-
tistics. ipa(8) uses such external accounting modules with the help
from the special ipa_ac_mod API, described in the ipa_mod(3) manual
page.
The ac_mod parameter tells ipa(8) to load the given IPA accounting mod-
ule:
ac_mod "file_name";
This parameter should not be placed in any section. It is possible to
use several accounting modules at once.
Example:
ac_mod "ipa_ipfw.so";
ac_mod "ipa_ip6fw.so";
These parameters load two accounting modules.
Using database modules.
There are special database modules, which are used for storing statis-
tics to databases. ipa(8) uses such external database modules with the
help from the special ipa_db_mod API, described in the ipa_mod(3) man-
ual page.
The db_mod parameter tells ipa(8) to load the given IPA database mod-
ule:
db_mod "file_name";
This parameter should not be placed in any section. It is possible to
use several database modules at once.
Example:
db_mod "ipa_db_sdb.so";
This parameter loads one database module.
Configuring modules.
Documentations for some IPA module should give all information how to
configure it, but usually configuration of some IPA module is inte-
grated to the configuration file ipa.conf(5).
Each module has a configuration prefix, which is used for distinguish-
ing module's sections and parameters. If there is a parameter like this
one:
prefix:parameter [[=] argument];
then ipa(8) will try to find a loaded module with configuration prefix
``prefix'', then ipa(8) will give this parameter for parsing to the
found module.
Sections also can have prefixes:
prefix:section [[=] argument] {
/* Module's parameters and sections. */
}
In this case parameters and sections inside such section should be
written without a prefix and this section and all its internal sections
and parameters will be passed to the appropriate module for parsing.
Documentation for some module should describe a module itself, module's
configuration prefix, database or accounting system name and all mod-
ule's parameters and sections.
Example:
sdb: {
allow_symlinks = yes;
}
ipfw:debug_ipfw = 1;
Given section's name can confuse one, but everything is correct. A
module can have empty section's and parameter's name.
Accounting rules.
ipa(8) performs accounting based on rules. There are two types of
rules: static and dynamic. A static rule is described in the rule sec-
tion. A dynamic rule does not have description in the configuration
file, but any dynamic rule is generated on-the-fly from some autorule
described in the autorule section.
Several rules (static, dynamic) can share the same settings. There are
several ways to do this. First way is to use the global section. Sec-
ond way is to use rulepat (rules patterns) sections. And the third way
is specifying common settings for dynamic rules in autorule sections.
If some rule (static, dynamic) does not have settings for some section
or parameter (dynamic rules also inherit settings from their autorule),
then it inherits settings from matched rulepat section, then it inher-
its settings from the global section, if there are still some unspeci-
fied sections or parameters, then default settings are used. Run ipa(8)
with -tt switches to see real values of all parameters.
Following parameters can be used in global, rulepat, rule and autorule
sections: ac_list, db_list, append_time, update_time, worktime,
ctl_rule_acl, debug_exec, debug_limit, debug_limit_init, debug_thresh-
old, debug_threshold_init.
Using accounting systems.
Above the ac_mod parameter was introduced, which tells to load a module
and allows it to parse its configuration. The ac_list parameter speci-
fies a list of used accounting systems:
ac_list = <list>;
<List> is a set of names separated by space characters. To get names of
accounting systems read documentations for modules you specified in
ac_mod parameters.
If some rule has the ac_list parameter, then accounting systems listed
in its value will be asked for statistics for this rule. This parame-
ter allows to create per rule accounting systems list.
There is one built-in accounting system null in ipa(8): this accounting
system always returns 0 as statistics. If the ac_list parameter is not
specified, then the null accounting system is used.
Example:
ac_mod "ipa_ipfw.so";
ac_mod "ipa_ip6fw.so";
global {
ac_list = ipfw ip6fw;
}
Here two accounting systems are specified.
Using databases.
Above the db_mod parameter was introduced, which tells to load a module
and allows it to parse its configuration. The db_list parameter speci-
fies a list of used databases:
db_list = <list>;
<List> is a set of names separated by space characters. To get names of
databases read documentations for modules you specified in db_mod
parameters.
If some rule (limit, threshold) has the db_list parameter, then data-
bases listed in its value will be used for storing statistics for this
rule (limit, threshold). This parameter allows to create per rule
(limit, threshold) databases list.
There is one built-in database null in ipa(8): data sent to this data-
base is not kept anywhere. If the db_list parameter is not specified,
then the null database is used.
Example:
db_mod "ipa_db_sdb.so";
global {
db_list = sdb;
}
Here one database is specified.
Accounting per period of a week.
By default ipa(8) performs accounting for all days in a week, but it is
possible to perform accounting only for some time intervals in a week.
The worktime parameter specifies time intervals when ipa(8) should per-
form accounting:
worktime = <X> h1:m1-h2:m2 [h1:m1-h2:m2];
worktime = <X> *;
<X> means a day of a week. Valid values for <X> are: `S' Sunday, `M'
Monday, `T' Tuesday, `W' Wednesday, `H' Thursday, `F' Friday, `A' Sat-
urday. There can be only one record for each day. Time intervals can-
not be overlapped or be placed not in the order.
00:00-24:00 interval or the `*' character means a whole day.
When worktime allows to perform accounting, the section where it is
placed is called ``active'', else it is called ``inactive''.
What exactly this parameter defines for autorules, rules, limits and
thresholds read in appropriate paragraphs.
Note that time intervals given in the worktime parameter do not guaran-
tee that exactly the same time intervals will appear in the database,
because the running copy of ipa(8) can have low priority or the system
can be to busy.
The end of one time interval can be the start of the next time inter-
val, this feature is only useful for rules (see below).
Example:
Perform accounting only at Monday, Tuesday and Wednesday:
worktime = M * T * W *;
Perform accounting at Thursday from 8:00 till 14:30 and from 18:20 till
21:00, at Sunday from midnight till 10:35 (the value is written in sev-
eral lines, just for indenting):
worktime = H 08:00-14:30 18:20-21:00
S 00:00-10:35;
Database time intervals.
The update_time parameter determines time interval when ipa(8) should
update statistics for some rule:
update_time = <time>;
If this parameter is omitted, then default value is 1 minute.
The append_time parameter determines time interval when ipa(8) should
append a new record to the database for some rule:
append_time = <time>;
This parameter has not default value. A new statistics record for each
rule is added to the database at the end of each day in any case.
Usually a value of the append_time parameter is greater than a value of
the update_time parameter.
ipa(8) tries to combine several time events into one to reduce resource
usage, this feature has another interesting moment, for example if
update_time is 5 minutes, then ipa(8) always schedules time events for
this parameter at 00:00, 00:05, 00:10 and so on.
There are some programs such as date(1) or ntpdate(8), which can change
UTC and local time, also the time zone can change itself. Such events
can cause an ``some time related problems occurred'' non fatal errors
in ipa(8). Parameters update_time and append_time can cause more such
errors. For example, if you call ntpdate(8) very often and the value of
the update_time parameter is nearly equal to the time interval of ntp-
date(8) invocations, then you can receive a lot of warning messages
from ipa(8).
It is possible to set how time events are sensitive to time changes in
the sensitive_time parameter:
sensitive_time = <time>;
By default the value of this parameter is equal to 30 seconds. This
parameter should not be placed in any section.
The wakeup_time parameter specifies maximum number of seconds ipa(8)
can sleep. This parameter tells ipa(8) when to wakeup and check if
everything is correct with time, time zone, etc.:
wakeup_time = <time>;
By default the value of this parameter is equal to 10 minutes. This
parameter should not be placed in any section.
Example:
global {
update_time = 30s;
append_time = 1h 30m;
}
The `s' character means seconds, `m' minutes, `h' hours (spaces are
optional). If <time> is specified as a complex value, then hours should
be placed before minutes and seconds, minutes should be placed before
seconds.
Descriptions of rules, limits and thresholds.
rule, limit and threshold sections can have the info parameter, which
is passed to the database and is used for describing a section:
info = "string";
The value of this parameter should not contain `\n' and `\t' charac-
ters. Usually this value should help to recall what this rule, limit
or threshold is used for. For example, this value is output by the ipa-
stat(8) program.
Dynamic rules get their descriptions from an accounting module, which
generates them, so you cannot specify descriptions for dynamic rules in
the configuration file.
Example:
rule 10.1.2.3-in {
info = "My traffic from ISP";
/* ... */
}
Sometimes rule's name is not very informative, so describing a rule is
a good idea.
Static rules.
Static rules are called ``static'', because they exist in the configu-
ration file and any accounting module cannot delete them (dynamic rules
can be deleted).
The rule section describes settings for one static rule:
rule <rule-name> {
/* Rule's parameters and sections. */
}
You should give such names for rules, which are also valid rules names
for databases you use.
The rule section does not have any mandatory settings. If some rule
does not have any sections and parameters, then it is called an empty
rule. It is obvious, that empty rules are senseless, so any rule usu-
ally has some parameters (own or inherited).
If a rule has the worktime parameter, then a new accounting record is
appended to the database when a new time interval begins. If a rule is
inactive then all its limits and thresholds are inactive as well.
Example:
ac_mod "ipa_ipfw.so";
ac_mod "ipa_ip6fw.so";
db_mod "ipa_db_sdb.so";
rule local.traf {
ac_list = ipfw ip6fw;
db_list = sdb;
info = "Traffic to my LAN";
sdb:db_group = staff;
ipfw:rules = 100 200 300;
ip6fw:rules = 1.10;
}
Here a rule uses two accounting systems and one database. It also has a
description and several modules' specific parameters.
Running commands.
There are several sections which allow to specify a list of commands
which should be run if some event occurred.
The exec parameter is used for running commands:
exec [<user>] "/path/command";
The exec parameter without <user> runs a command with privileges of the
user who run ipa(8), that is no actions in changing user or groups are
performed for running command.
The exec parameter with <user> runs a command with privileges of the
given user. A user can be given only by its name. ipa(8), at the moment
of running a command, will get UID and GIDs of the user. This parameter
can be used if ipa(8) is run by the super-user only.
It is possible to use macro variable (including predefined ones) in
commands strings (actually in any string). If you need to use name of
the rule in some command string in rulepat or autorule section then you
should use substitutions. Two substitutions are defined:
%rule% The name of the rule.
%% The `%' character.
These substitutions do not work in command strings placed in rule sec-
tions, use macro variable ${rule} there instead.
By default commands should be given with absolute pathname, but it is
possible to specify commands with relative pathnames, just set the
only_abs_paths parameter to ``no'', by default the value of this param-
eter is ``yes'':
only_abs_paths = <boolean>;
All commands are run with the help from the shell, so any shell-spe-
cific command line constructions can be used:
<shell_path> <shell_arg1> /path/command
Note that standard input (stdin), standard output (stdout) and standard
error (stderr) are handled in the same way as in ipa(8).
<Shell_path> is determined when IPA is built, usually it is /bin/sh
(see output of the ``ipa -v'' command for the real path), but it is
possible to exactly specify the shell in the configuration file with
the help of the shell_path parameter:
shell_path = "/path/shell";
<Shell_arg1> by default is equal to ``-c'', but it can be redefined in
the shell_arg1 parameter:
shell_arg1 = "<arg1>";
If there are not enough resources and ipa(8) is not able, for example,
to fork(2) a child to run commands list, then ipa(8) will exit with an
error code. But if some error occurred in a child which runs a command,
then ipa(8) will ignore this error, and a child simply will log a warn-
ing message.
Parameters only_abs_paths, shell_path and shell_arg1 should not be
placed in any section.
Example:
startup {
exec "/bin/echo \"ipa started\" | mail me";
exec nobody "/usr/local/bin/something";
}
only_abs_path = no;
shutdown {
exec "echo \"ipa stopped\" | mail me";
}
rulepat "^client" {
startup {
exec "command %rule%";
}
}
rule 1 {
shutdown {
exec "echo rule off >> /tmp/${rule}.log";
}
}
In the first section the ``mail'' command is given without an absolute
pathname. This is correct because only the first command is checked for
an absolute pathname, ipa(8) does not interpret shell-specific command
line constructions.
In the rulepat section substitution %rule% is used and in the rule sec-
tion macro variable ${rule} is used for inserting the name of the rule
to the command string.
Running commands at startup and shutdown.
In startup (shutdown) section you can specify which commands should be
run when ipa(8) starts (finishes) working. These sections can be placed
alone (global commands) and in autorule, rulepat, rule, limit, sublimit
and threshold sections.
If these sections are placed alone (see below usage of these sections
in other sections), then they can contain only exec and sync_exec
parameters.
The algorithm of running commands in startup (shutdown) sections is the
following:
1. run global commands;
2. run commands from rule sections;
2a. in each rule section run commands for limits and thresholds;
2b. in each limit section run commands for its sublimits.
When ipa(8) rereads the configuration file (when it receives a SIGHUP
signal), then commands in startup sections are ignored, but new com-
mands for shutdown sections will be used. If you need to run some com-
mands from startup sections after reconfiguration, then it is possible
to run them by ipa(8) with the -x option.
Example:
startup {
exec "command1";
}
rule 1 {
startup {
exec "command2";
}
limit 1 {
/* ... */
startup {
exec "command3";
}
}
}
rule 2 {
startup {
exec "command4";
}
}
Here commands are run in the following order on startup: command1, com-
mand2, command3 and command4.
Running commands synchronously and asynchronously.
There are two regimes of running commands: synchronous and asynchro-
nous. In synchronous regime ipa(8) is waiting for the exit of running
commands. In asynchronous regime ipa(8) having run commands, is not
waiting for the exit of running commands and continues its work.
By default commands in all startup and shutdown sections are run syn-
chronously, in all other sections commands are run asynchronously.
The sync_exec parameter allows to specify synchronous or asynchronous
regime for any section:
sync_exec = <boolean>;
This parameter can be used in any section, which accepts exec parame-
ters.
Example:
startup {
sync_exec = no;
exec "/path/something";
}
In this example default synchronous regime of the startup section is
changed to asynchronous.
About statistics.
ipa(8) interprets statistics as 64-bit unsigned integers, statistics
can be whatever (for example time, bytes or numbers). If some rule uses
several accounting systems, then ipa(8) summarizes statistics got from
each accounting module. Usually an accounting module returns positive
statistics, but it can return negative statistics.
ipa(8) internally for rules stores statistics in two 64-bit unsigned
integer counters: one counter for positive statistics and another one
for negative statistics. In any time one of these counters is equal to
zero. If the negative statistics counter is overflowed, then ipa(8)
reports about occurred problem and exits, since such overflow means
wrong configuration. If the positive statistics counter is overflowed,
then ipa(8) asks the database to append a new record for a rule to
store statistics which does not fit the size of its internal counter.
Any limit or threshold has the same two counters, but if limit's or
threshold's positive or negative counter is overflowed, then ipa(8)
reports about occurred problem and exits, since such overflow means
wrong configuration. Also each threshold has several counters for each
time slice (negative or positive sign is kept in a bitmap).
Statistics is given to the database as 64-bit unsigned integers with
the value of the current local time.
Usually positive statistics is greater than negative statistics, but
this is not required. Only positive statistics is stored in the data-
base and while ipa(8) is running, negative statistics is kept in its
memory, but when ipa(8) exits and some rule, limit or threshold has
negative statistics, then this negative statistics is lost (a log mes-
sage will be sent). In other words, ipa(8) is able to subtract statis-
tics from the current value of its positive statistics counter and
there is not any way to subtract statistics from old statistics in the
database.
Limits: introduction.
A limit should be considered with the context of some rule. Sometimes
limits in IPA are called triggers. If there is a need to do some
actions when statistics for some rule reaches some value during some
time period, then the limit section should be used. This section can
have several sections and must have at least one parameter named limit:
limit <limit-name> {
limit = <limit-value>;
/* Limit's parameters and sections. */
}
You should give such names for limits, which are also valid limits
names for databases you use.
Any limit has 64-bit unsigned counter for positive statistics which is
changed by ipa(8) and which is compared with the value of the limit
parameter. If the counter's value becomes equal to or greater than the
value of the limit parameter then a limit is treated as reached and
ipa(8) will not changed the limit's counter any more. A limit's counter
is updated synchronously with a rule's counter.
Limits have names, hence it is possible to use several limits in one
rule and they are distinguished by names.
ipa(8) knows nothing about units of statistics, so it is possible to
use different formats of <limit-value>: bytes, time and unsigned 64-bit
integer (see examples below). <Limit-value> always is converted to
unsigned 64-bit integer.
A limit can pass several states: a limit is not reached, a limit is
reached (plus optionally running commands), a reached limit is expired
(plus optionally running commands) and pseudo state when a not reached
limit should be restarted. The limit section can have some parameters
and some sections, which determine a limit's states (described below).
If a limit is not reached, then its statistics is checked each time
when its rule is updated (this time interval is not bigger than the
value of the update_time parameter).
Example:
rule my-account {
/* Rule's parameters and sections. */
limit 1 {
limit = 1M 500K;
info = "Bytes limit";
}
limit 2 {
limit = 2h 30m;
info = "Time limit";
}
limit 3 {
limit = 1234567890;
info = "Numerical limit";
}
}
There are three independent limits in one rule in this example.
When the value of the limit parameter is given as bytes, then the `T'
character means TBytes, `G' Gbytes, `M' Mbytes, `K' Kbytes, `B' bytes
(spaces are optional). If a value is specified as a complex value, then
Tbytes should be placed before Gbytes and Mbytes and so on.
Active and inactive limits.
If a limit does not have own worktime parameter, then it is active when
its rule is active, that is, if the rule's worktime parameter allows
accounting, then a limit works as usually, if accounting is not allowed
for its rule, then ipa(8) ignores a limit and will start to work with
it when the rule's worktime parameter allows to perform accounting
again.
Any limit can have own worktime parameter. In this case if a rule is
active, then ipa(8) checks the limit's worktime parameter.
When a limit is inactive, then times specified by the restart and
expire parameters are not checked.
So, it is possible to have active rule and inactive limit. But it is
impossible to have inactive rule and active limit. All time intervals
in the limit's worktime parameter must be subsets of time intervals in
the rule's worktime.
Example:
rule my-account {
/* ... */
worktime = A * S *;
limit 1 {
limit = 10M;
worktime = A 08:00-21:00 S 08:00-21:00;
}
}
Here the rule is active only at Saturday and Sunday and the limit is
active only from 08:00 till 21:00 at the same days. Since 08:00-21:00
time interval is a subset of 00:00-24:00 time interval, then everything
is correct in these two parameters.
Restarting a not reached limit.
The time when a new limit was created (or reached limit was restarted
again) is known as ``start time''. ipa(8) changes a limit's counter
only while a limit is not reached. It is possible to specify time when
a not reached limit should be restarted with zeroed (flushed) counter.
The restart section allows to specify time when to restart a not
reached limit:
limit <limit-name> {
/* Limit's parameters and sections. */
restart {
restart = <restart-time>;
/* Commands. */
}
}
The restart section must have at least the restart parameter. There
are three methods for specifying this time. Let's see them in following
examples.
It is possible to specify optional commands which will be run, when not
reached limit is restarted.
ipa(8) also informs accounting systems used by limit's rule when a not
reached limit is restarted, so if you do not specify commands in the
restart section, then some actions still can be performed by accounting
systems.
If a limit does not have the restart section, then this limit (if it is
not reached) cannot be automatically restarted, but it can be restarted
by the ipactl(8) utility.
Example 1:
rule my.traf {
ac_list = ipfw;
ipfw:rules = 100 200;
limit 1 {
limit = 1G;
restart {
restart = 20h 30m;
}
}
}
Here the value of the restart parameter is added to limit's start time
and calculated value is time when a limit should be restarted. Here we
can consider restart time as simply number of seconds from limit's
start time.
The `s' character means seconds, `m' minutes, `h' hours, `D' days and
`W' weeks.
Example 2:
rule my.traf {
ac_list = ipfw;
ipfw:rules = 100 200;
limit 1 {
limit = 1G;
restart {
restart = +W;
}
}
}
Here the limit will be restarted at the end of a week after limit's
start time. A character after the `+' sign means: `m' a minute, `h' a
hour, `D' a day, `W' a week, `M' a month.
Example 3:
rule my.traf {
ac_list = ipfw;
ipfw:rules = 100 200;
limit 1 {
limit = 1G;
restart {
restart = +M 2D;
}
}
}
In this example the limit will be restarted on the third day of the
next month after limit's start time: the restart time for ``+M'' (start
of the next month) is calculated and then ``2D'' (two days) are added
to the calculated value.
Note that ``2D +M'' is not the same: here ``2D'' is added to limit's
start time and then the restart time for ``+M'' is calculated (and we
always will get first day of some next month here).
Actions when a limit is reached.
When a limit is reached, ipa(8) runs commands listed in the reach sec-
tion:
limit <limit-name> {
/* Limit's parameters and sections. */
reach {
/* Commands. */
}
}
The reach section can be absent or empty and no commands will be run
when a limit is reached.
ipa(8) also informs accounting systems used by limit's rule when a
limit becomes reached, so if you do not specify commands in the reach
section, then some actions still can be performed by accounting sys-
tems.
Example:
rule my.traf {
ac_list = ipfw;
ipfw:rules = 100;
limit 1 {
limit = 1G;
restart {
restart = +W;
}
reach {
exec "/somewhere/stop_traffic";
}
}
}
Here there is 1 Gbyte limit, which is restarted at the end of the week
if it is not reached, but if it becomes reached, then the given command
is run.
Restarting a reached limit.
It is possible to restart a reached limit. To do this you should use
the expire section:
limit <limit-name> {
/* Limit's parameters and sections. */
expire {
expire = <restart-time>;
/* Commands. */
}
}
The expire section must have at least the expire parameter.
It is possible to specify optional commands which will be run, when
reached limit is restarted.
ipa(8) also informs accounting systems used by limit's rule when a
reached limit is restarted, so if you do not specify commands in the
expire section, then some actions still can be performed by accounting
systems.
If a limit does not have the expire section, then this limit (if it is
reached) cannot be automatically restarted, but it can be restarted by
the ipactl(8) utility.
The value of the expire parameter can be 0s, this means that reached
limit will be restarted immediately.
Example:
rule my.traf {
ac_list = ipfw;
ipfw:rules = 100;
limit 1 {
limit = 1G;
restart {
restart = +W;
}
reach {
exec "/somewhere/stop_traffic";
}
expire {
expire = +W;
exec "/somewhere/start_traffic";
}
}
}
Here there is 1 Gbyte per week limit. If the limit is reached, then at
the begin of the week it will be restarted. If this limit is not
reached, then it is also restarted at the begin of the week.
Startup and shutdown sections for a rule.
Two sections were described above for running commands at startup and
shutdown. A rule can have these sections as well, but startup and shut-
down section placed in the rule section can have extra subsections:
if_any_reached - if any of rule's limits is reached;
if_any_not_reached - if any of rule's limits is not reached;
if_all_reached - if all rule's limits are reached;
if_all_not_reached - if all of rule's limits are not reached.
These subsections determine commands, which should be run if limits fit
a subsection condition.
Any rule can have empty startup or shutdown section, in this case this
section is not inherited from the matched rulepat section.
Example:
rule my.traf {
ac_list = ipfw;
ipfw:rules = 100;
startup {
exec "/somewhere/count_traffic";
if_any_reached {
/* ... */
exec "/bin/echo \"Some limit in rule ${rule} was \
reached\" | mail admin";
}
}
limit 1 {
limit = 1G;
restart {
restart = +M;
}
info = "1G per month";
/* ... */
}
limit 2 {
limit = 500M;
restart {
restart = +W;
}
info = "500M per week";
/* ... */
}
}
Here there are two limits: 1 Gbyte per month and 500 Mbytes per week,
the if_any_reached section will be used if any of these two limits is
reached at the moment of the start of ipa(8). Also rule's startup sec-
tion has one command that is always run at startup. Here we use one
back-slash character for splitting a command string.
Startup and shutdown sections for a limit.
A limit section also can have own startup and shutdown sections with
following extra subsections:
if_reached - if a limit is reached;
if_not_reached - if a limit is not reached.
These subsections determine commands, which should be run if a limit
fits a subsection condition.
ipa(8) also informs accounting systems used by limit's rule at startup
and shutdown if a limit is reached or is not reached, so if you do not
specify startup and/or shutdown commands for a limit, then some actions
still can be performed by accounting systems.
Using separate databases for limits.
There is the db_list parameter, which determines a list of databases
used by a rule. By default a limit uses the same list of databases as
its rule (it inherits this list). But it is possible to use the db_list
parameter in the limit section:
rule <rule-name> {
/* Rule's parameters and sections. */
db_list <list1>;
limit <limit-name> {
/* Limit's parameters and sections. */
db_list <list2>;
}
}
<List1> and <list2> can contain common elements, in any case <list1> is
used only for a rule and <list2> is used only for a limit.
Why to use separate database lists for a rule and its limit? Not all
databases work with limits and even if some database works with limits,
it can support not all functions (methods) for limits. See implementa-
tion details in the ipa_mod(3) manual page.
Suppose some limit uses several databases. From which database will
ipa(8) get current limit state? The first database, which is able to
return a limit's state, will be asked for the current limit's state,
even if some other database has another limit's state, it will not be
asked for it and its limit's state will be lost, then ipa(8) will
update the current limit's state in each database.
Note that the order of databases for a limit is important.
Read in the database module's documentation you use information, if it
can work with limits and what exactly a module supports when it works
with limits.
Using the value of the limit parameter from the database.
Sometimes it is necessary to keep the value of the limit parameter in
the database and change this value in the database, so there should be
a way to tell ipa(8) to use the value of the limit parameter from the
database. The load_limit parameter was implemented for this purpose:
limit <limit-name> {
/* Limit's parameters and sections. */
load_limit = <boolean>;
}
If you want to load the value of the limit parameters from the data-
base, then set the value of the load_limit parameter to ``yes''. If
the database does not have current state of a limit (for example if a
limit is new), then the value of the limit parameter from the configu-
ration file will be used, that's why the limit parameter always must be
specified.
By default the value of the load_limit parameter is ``no''.
One of possible cases why one wants to set this parameter to ``yes'' is
the usage of the ipactl(8) utility for changing the value of the limit
parameter on-the-fly.
This parameter can be specified in the global section, if some limit
section does not have this parameter, then its value will be set from
the global section.
Limits initialization.
When ipa(8) starts, rereads the configuration file or does reinitial-
ization when some time related problems occurred, it performs following
steps for an arbitrary limit:
1. The current limit's state is read from the database, if the
database does not have the limit's state, then a new limit's
state is registered with the value of the limit parameter from
the configuration file and with zero counter, and initialization
of the limit is complete, else ipa(8) does second step (2a or
2b).
2a. If the limit is not reached with the current state from the
database, then if the value of the load_limit parameter is
``no'', then ipa(8) updates the value of the limit parameter
from the configuration file; if the value of the load_limit
parameter is ``yes'', then ipa(8) ignores the value of the limit
parameter from the configuration file and gets this value from
the database. In any case the limit is marked as not reached,
even if with new settings it becomes reached. Then ipa(8)
updates date when the limit should be restarted accordingly to
the value of the restart parameter from the configuration file,
ignoring this date from the database.
2b. If the limit is reached, then ipa(8) marks this limit as reached
and does not update the value of the limit parameter in the
database (that is it does not honor the value of the load_limit
parameter at this moment and this can be seen in the output for
the ipactl(8)'s command status for this limit). Then ipa(8)
updates date when the limit will expire accordingly to the value
of the expire parameter from the configuration file, ignoring
this date from the database.
Limits: about limit's events again.
To help understand how exactly an arbitrary limit works, let's write
the time diagram of its states:
+--------------+--> Restart (Tstart)
| |
Trestart_exec Treach_exec Texpire_exec
--|------>------||------>------||------>------||------------->
Tstart Trestart Treach Texpire time
Sublimits.
A sublimit is a part of some limit. The main purpose of a sublimit is
to register an event when some part of the limit parameter's value is
reached. Since a sublimit is a part of some limit section, then the
value of a sublimit must be given in the same units as the value of the
limit parameter. To simplify specifying of sublimits it is possible to
give the value of any sublimit in per cent, that is some per cent of
the limit parameter's value:
limit <limit-name> {
limit = <limit-value>;
/* Limit's parameters and sections. */
sublimit <sublimit-value> {
/* Sublimit's sections. */
}
}
Sublimits can contain only reach, startup and shutdown sections. All
these sections has the same format and mean the same as for limits.
ipa(8) does not inform accounting systems about sublimits' events, just
because sublimits are invisible for modules.
A limit can have several not duplicated (different <sublimit-values>)
sublimits.
Since sublimits states are not kept in the database, then it is always
better to use sublimits than adding extra limits to some rule if possi-
ble.
Example:
rule my.traf {
/* ... */
limit l1 {
limit = 1G;
load_limit = yes;
restart {
restart = +M;
}
info = "${rule}, ${limit} per month";
/* ... */
sublimit 50% {
reach {
exec "/bin/echo \"half of ${rule}'s limit \
${limit} reached\" | mail me";
}
}
}
}
Here there is the sublimit which will send an email when half of the l1
limit is reached. Even if the value of the limit parameter will be
changed by the ipactl(8) utility, sublimit's value will be adjusted,
because it is given in per cent.
Thresholds: introduction.
Thresholds allow to monitor rule's statistics for some time period
before current time and do some actions when statistics for this time
period is less than, equal to or greater than the given value. This
time period also can be called ``sliding time window''. A threshold is
described by the threshold section with following format:
threshold <threshold-name> {
threshold = <threshold-value>;
threshold_time_width = <time>;
threshold_time_slice = <time>;
/* Other threshold's parameters and sections. */
}
You should give such names for thresholds, which are also valid thresh-
olds names for databases you use.
Any threshold has 64-bit unsigned counter which is changed by ipa(8)
and which is compared with the value of the threshold parameter. If
the counter's value becomes less than, equal to or greater than the
value of the threshold parameter, then commands from the optional
below_threshold, equal_threshold or above_threshold section are run. A
threshold's counter is changed synchronously with a rule's counter each
threshold_time_slice time interval.
ipa(8) knows nothing about units of statistics, so it is possible to
use different formats of <threshold-value>: bytes, time and unsigned
64-bit integer. <Threshold-value> always is converted to unsigned
64-bit integer.
It is possible to specify a deviation of <threshold-value> with the
help of the threshold_deviation parameter. The value of the thresh-
old_deviation parameter must be given in the same units as the value of
the threshold parameter. To simplify specifying of a threshold devia-
tion it is possible to give its value in per cent, that is some per
cent of the threshold parameter's value.
The value of the threshold_time_width parameter determines the width of
sliding time window. The value of the threshold_time_slice parameter
determines time intervals of sliding time window movement. The thresh-
old_time_width parameter's value must be greater than the thresh-
old_time_slice parameter's value, and must be divisible on this value.
In other words, a threshold's counter represents a snapshot of rule's
statistics for last threshold_time_width seconds. Unlike limits thresh-
olds do not have ``start time'', because their statistics is sliding in
time in discrete time intervals equal to threshold_time_slice seconds.
These two parameters can be specified in the global section and they
will be used if some threshold section does not have them.
Thresholds have names, hence it is possible to use several thresholds
in one rule and they are distinguished by names.
Accounting systems used by threshold's rule are notified about thresh-
old's events, so accounting systems also can do some actions when the
value of a threshold's counter is less, equal or greater than the
threshold parameter's value.
It is possible to limit number of times commands are run and accounting
systems are informed from below_threshold (X), equal_threshold (Y) and
above_threshold (Z) sections in the threshold_balance parameter:
threshold_balance = X:Y:Z;
This parameter can be specified in the global section and if some
threshold section does not have it, then its value will be inherited
from the global section.
There are three internal counters x, y and z, which count how many
times commands were run and accounting systems were informed from
below_threshold, equal_threshold and above_threshold sections consecu-
tively. These counters initially are equal to X, Y and Z respectively.
When threshold's counter is below than the value of the threshold
parameter and x is not equal to zero, then it is decremented, y is set
to Y and z is set to Z, then commands from the below_threshold section
are run and accounting systems are informed about threshold's event.
The same for y and z counters.
To unlimit value of X, Y or Z, specify it as `-'. In implementation
infinitive value really is equal to UINT_MAX. By default the value of
this parameter is -:-:-.
Example:
rule lan {
ac_list = ipfw;
ipfw:rules = 100 200 -300;
update_time = 1m;
limit l1 {
limit = 1G;
info = "Control each 1G of bandwidth usage";
reach {
exec "/bin/echo \"1G of ${rule} reached\" | mail me";
}
expire {
expire = 0s;
}
}
threshold t1 {
threshold = 500M;
threshold_balance = 1:-:1;
threshold_deviation = 50M;
threshold_time_width = 24h;
threshold_time_slice = 15m;
info = "500M plus-minus 50M threshold per 24h";
below_threshold {
exec "/somewhere/increase_bandwidth ${rule}";
}
above_threshold {
exec "/somewhere/decrease_bandwidth ${rule}";
}
}
}
Here the rule has one threshold and one limit.
The threshold allows to dynamically control bandwidth in 500 Mbytes
plus-minus 50 Mbytes (we increase speed by some increase_bandwidth pro-
gram and decrease speed by some decrease_bandwidth program) per 24
hours (this is one day, but not a week day, here 24 hours mean time
interval). Time slice is 15 minutes, note that the threshold will not
be checked every minute here (the value of the update_time parameter
for this rule).
Statistics for the rule and the limit will be updated every minute. The
limit allows to send an email when next 1 Gbyte of bandwidth has been
used.
Active and inactive thresholds.
Thresholds like limits can be active and inactive and can have own
worktime parameter. So, for more information read appropriate paragraph
for limits.
What is the value of the threshold's counter when a threshold was inac-
tive and becomes active due to the worktime parameter's value? One
solution is to allow a threshold's time window to slide during time
interval of inactivity, another solution is to ``move'' a threshold's
time window over time interval of inactivity. In the first solution
statistics for the threshold's counter during time interval of inactiv-
ity is 0 and the value of the threshold's counter is decreased. In the
second solution statistics during time interval of inactivity is
ignored (it is skipped) and the value of the threshold's counter is not
changed.
What is the value of the threshold's counter when ipa(8) starts working
and there is a state of a threshold in the database? There are also two
solutions for this situation as for previous question.
It is possible to select solutions for above described situations with
the help of the threshold_type parameter, its value is equal to ORed
bits (given as hexadecimal values):
0x1 jump over time interval, when ipa(8) did not run (was stopped);
0x2 jump over time interval, when a threshold was inactive.
By default the threshold_type parameter's value is equal to 0. Possi-
ble values of this parameter are: 0, 1, 2 and 3 (0x1|0x2). Normal val-
ues for this parameter are 0 or 3, values with only one bit set should
be used with care, since when a threshold is initialized, it is treated
as active (read the paragraph about thresholds initialization).
This parameter can be specified in the global section and if some
threshold section does not have it, then its value will be inherited
from the global section.
Example:
rule client {
ac_list = ipfw;
ipfw:rules = 100 200 300;
update_time = 1m;
threshold t {
threshold = 100M;
threshold_deviation = 10%;
threshold_time_width = 5h;
threshold_time_slice = 15m;
threshold_type = 3;
worktime = M 08:00-21:00 T 08:00-21:00 W 08:00-21:00
H 08:00-21:00 F 08:00-21:00;
info = "100M plus-minus 10% threshold per 5h (type 3)";
below_threshold {
exec "/somewhere/increase_bandwidth ${rule}";
}
above_threshold {
exec "/somewhere/decrease_bandwidth ${rule}";
}
}
}
Suppose that the given rule is for one client which has access to
Internet each work day from 08:00 to 21:00. We allow him 100 Mbytes
plus-minus 10% per 5 hours speed (we increase speed by some
increase_bandwidth program and decrease speed by some decrease_band-
width program).
Suppose that current counter's value of the threshold is 90 Mbytes at
21:00. When 08:00 of the next day comes, by default current counter's
value of the threshold becomes 0 Mbyte, because there is at least one
time interval in 5 hours between 21:00 and 08:00 of the next day. Here
we use threshold type 3 and time window will ``jump'' from 21:00 to
08:00 and current counter's value of the threshold will be unchanged,
that is 90 Mbytes at 08:00 of the next day. We also can stop ipa(8) at
21:00 and run it again at 08:00 and a threshold's time window will also
``jump'' from 21:00 to 08:00.
If there are several clients with the same settings, then at 08:00 non
of them will be able to intensively start to use own part of common
bandwidth.
Using the value of the threshold parameter from the database.
A threshold likes a limit can have load_threshold parameter, which
means the same and is used for the same purpose. So, read appropriate
paragraph for limits for more information.
Startup and shutdown sections for a threshold.
An arbitrary threshold can have own startup and shutdown sections,
which can contain only lists of commands.
Using separate databases for thresholds.
Like limits, it is possible to use the db_list parameter in the thresh-
old section and have different lists of databases for a rule and its
threshold.
Thresholds initialization.
Unlike limits, initialization of thresholds is very simple, since
thresholds cannot be reached or not reached: ipa(8) gets current state
of a threshold from the first database, which is able to return a
threshold's state, if this database does not have a threshold's state,
then a new state is registered with the value of the threshold parame-
ter from the configuration file, else ipa(8) honors values of
load_threshold and threshold_type parameters and updates threshold's
state. Note that when a threshold is initialized it is assumed as
active, even if its worktime parameter marks this threshold as inac-
tive. Since threshold's statistics slices are not saved in the data-
base, valid statistics slices are initialized approximately, according
to the current local time, threshold's timestamps and its counter
value.
Thresholds: about thresholds again.
To help understand how exactly an arbitrary threshold works, let's
write the time diagram:
<-------------- time_width ------------->
(t1) |---c1--|---c2--|---c3--|---c4--|---c5--| --> sliding
(t2) |---c2--|---c3--|---c4--|---c5--|---c6--| --> sliding
<-slice->
-----|-------|-------|-------|-------|-------|-------|-------|-->
t1 t2 time
On this diagram we see threshold's statistics at time t1 and at t2. All
statistics is represented as a sum of ci, each ci of statistics is
equal to statistics of a rule during one time slice t2 - t1. A thresh-
old slides in time discretely and its statistics is a snapshot of
rule's statistics for last time_width seconds.
Dynamic rules and autorules.
Dynamic rules are generated from autorules by specially designed
accounting modules on-the-fly. Internally in ipa(8) static and dynamic
rules are almost indistinguishable and any parameter (except the
ac_gather_* parameters) and section (including limit and threshold sec-
tions) in static rules can be used in dynamic rules.
An autorule is described by the autorule section:
autorule <autorule-name> {
/* Parameters and sections. */
}
<Autorule-name> it is not stored in the database, but an accounting
module can use this name for generating names of dynamic rules, so use
the same restrictions as for <rule-name> for the database you use.
A dynamic rule is looks like a static rule. There are only two restric-
tions for autorules (hence for dynamic rules): an autorule can have
only one accounting system in the ac_list parameter's value and an
autorule cannot have ac_gather_* parameters.
The configuration file can have several autorules at once. Any autorule
usually have at least the ac_list parameter with one element in its
value. (It is possible to implement support for several accounting sys-
tems for one autorule, but it is senseless.) This one element in the
ac_list parameter's value determines accounting system, which can cre-
ate and delete dynamic rules. Every time when this accounting system is
asked for new statistics (the ac_get_stat function in ipa_mod(3)), it
has a chance to create and/or delete (previously created) dynamic
rules. The value of the update_time parameter determines the time
interval of ac_get_stat function invocations (this function can be
called more often).
If you want to use some database for dynamic rules, then this database
should support dynamic rules.
If an autorule has the worktime parameter, then this parameter is used
by an autorule. Dynamic rules generated from this autorule inherit
autorule's worktime_rule parameter as their worktime parameter. If an
autorule does not have the worktime parameter, then it inherits this
parameter from the global section.
Since an autorule and its dynamic rules can use different worktime
parameters, it is possible to have inactive autorule and active dynamic
rules and vice versa.
A dynamic rule inherits parameters and sections from its autorule, if
some parameters and sections are still undefined, then they are inher-
ited from the matched rulepat section, then from the global section and
then default settings are used.
If an autorule has startup and shutdown sections, then these sections
are for dynamic rules, not for an autorule itself. If you wish to use
the name of some dynamic rule in some command line, then you cannot use
the ${rule} macro variable, because it is expanded by the internal con-
figuration file parser, instead use command line substitutions (see
above).
Any autorule can have empty startup or shutdown section, in this case
this section is not inherited from matched rulepat section for its
dynamic rules.
If you need different limits or thresholds for dynamic rules created
from the same autorule, then specify these limits and thresholds in
different rulepat sections.
Example:
ac_mod "ipa_atest.so";
db_mod "ipa_db_sdb.so";
global {
db_list = sdb;
append_time = 1h;
}
autorule a {
ac_list = atest;
update_time = 1m;
limit 1 {
limit = 100M;
restart {
restart = +W;
}
reach {
exec "/somewhere/stop_traffic.sh %rule%";
exec "/bin/echo \"%rule%'s limit ${limit} reached\" |
mail admin";
}
expire {
expire = +M;
exec "/somewhere/start_traffic.sh %rule%";
}
}
}
Here each dynamic rule generated from the autorule will inherit
autorule's update_time parameter and like static rules each dynamic
rule will inherit db_list and append_time parameters from the global
section. Each dynamic rule will have one limit, since we cannot use the
${rule} macro variable in dynamic rules (actually in autorules), then
%rule% substitution is used. Using the ${limit} macro variable in a
limit in an autorule is correct, since limit's name is know for the
configuration file parser.
Rules patterns.
Using rules patterns is an effective method for sharing common settings
for rules. As it was said above, the global section allows to specify
some common settings for any rules, dynamic rules can inherit common
settings from their autorules. Rules patterns allow to specify common
settings for classes of static and dynamic rules.
If some static or dynamic rule does not have some parameter or section,
then it can inherit this parameter or section from the matched rule
pattern. Rules patterns are defined in the rulepat sections:
rulepat "<regexp>" {
/* Parameters and sections. */
}
Each rule pattern is named by POSIX extended regular expression. Having
parsed the configuration file, ipa(8) finds a matched rule pattern for
each static rule and applies unspecified settings from a rule pattern
to a static rule. Similarly, having created a dynamic rule, ipa(8)
finds a matched rule pattern and applies unspecified settings from a
rule pattern to a dynamic rule. By default when a matched rule pattern
is found the search terminates. To continue search for other rule pat-
ters, set the value of the check_next_rulepat parameter to ``yes'':
check_next_rulepat = <boolean>;
This parameter can be used only in the rulepat section, and its default
value is ``no''.
Any parameter (except ac_gather_* parameters) and any section (includ-
ing limit and threshold sections), which is allowed to use in the rule
section, can be used in the rulepat section.
Rules patterns can be placed anywhere in the configuration file, but
their order is important, because theirs regular expressions are
checked in the same order as rules patters are placed in the configura-
tion file.
Modules also can expect their parameters and sections in rulepat sec-
tions.
Example:
ac_mod "ipa_ipfw.so";
db_mod "ipa_db_sdb.so";
global {
ac_list = ipfw;
db_list = sdb;
update_time = 1m;
load_limit = yes;
sdb:db_group = staff;
}
rulepat "0${$}" {
check_next_rulepat = yes;
update_time = 30s;
threshold 1 {
threshold = 1G;
threshold_deviation = 10%;
threshold_time_width = 10h;
threshold_time_slice = 5m;
below_threshold {
exec "/somewhere/increase-bandwidth.sh %rule%";
}
above_threshold {
exec "/somewhere/decrease-bandwidth.sh %rule%";
}
}
}
rulepat "^client" {
worktime = M 08:00-20:00 T 08:00-20:00 W 08:00-20:00
H 08:00-20:00 F 08:00-20:00 A 08:00-17:00;
}
Here first rulepat section ``catches'' all rules with zero at the end
of their names (macro variable ${$} is expanded to single character
`$', and `$' at the end of POSIX regular expression means the end of
the string). Since the value of its check_next_rulepat is ``yes'' then
next rule pattern is checked. Second rulepat section ``catches'' all
rules with ``client'' substring at the beginning of their names.
Gathering statistics from several rules.
Usually each rule gets statistics from accounting modules, but some-
times it is necessary to summarize statistics from several rules and it
is impossible or too expensive give this task to accounting modules.
The ac_gather_add and ac_gather_sub parameter allow to get statistics
for one rule from several rules and add or subtract this statistics:
rule <rule-name> {
/* Rule's parameters and sections. */
ac_gather_add = "<regexp>";
ac_gahter_sub = "<regexp>";
}
Here <regexp> is a POSIX extended regular expression, if some rule's
name matches this regular expression, then its statistics is gathered
by a rule in which the ac_gather_* parameters are specified. Note that
this parameter also works with dynamic rules. It is also possible to
make complex dependencies in this parameter (see an example).
This parameter should be placed in the rule section, that is it can be
used only with static rules, but can gather statistics from static and
dynamic rules.
The ac_list is a synchronous parameter in respect to the rule section:
when some rule is updated, statistics is fetched from each accounting
system a rule uses. ac_gather_* are asynchronous parameters in respect
to the rule section: current rule gets statistics from a rule matched
ac_gather_* parameters' regular expressions when this matched rule is
updated.
A rule which has ac_gather_* parameters can also have the ac_list
parameter.
Example:
ac_mod "ipa_ipfw.so";
global {
ac_list = ipfw;
}
rule client1 {
ipfw:rules = 100 102 104;
info = "Statistics for first client";
}
rule client2 {
ipfw:rules = 200 202 204;
info = "Statistics for second client";
/* ac_gather_add = "^clients${$}"; <-- WRONG! */
}
rule clients {
ac_gather_add = "^client[[:digit:]]+${$}";
info = "Statistics for all clients";
}
rule server {
ipfw:rules = 1000 1002;
info = "Statistics for server";
}
rule all_stat {
ac_gather_add = "^(server|clients)${$}";
info = "Statistics for all in my LAN";
}
rule all_except_client2_stat {
ac_gather_add = "^all_stat${$}";
ac_gather_sub = "^client2${$}";
info = "Statistics for all in my LAN except client2";
}
Here we have six static rules: client1, client2, clients, server,
all_stat and all_except_client2_stat. The rule clients gets statistics
from client1 and client2 rules. The rule all_stat gets statistics from
clients and server rules. And the rule all_except_client2_stat gets
statistics from rules clients and server not including statistics from
rule client2.
The client2 rule has incorrectly used the ac_gather_add parameter in a
comment, if this parameter exists in this rule, then we will get a
cycle in rules dependencies: client2->clients->client2... ipa(8) does
not check cycles in rules dependencies.
Using ipactl(8) program.
The ipactl(8) program allows to send control commands to ipa(8) via an
Unix domain socket. Before using this program you should allow to use
it by setting the value of the ctl_enable parameter to ``yes'', by
default the value of this parameter value is ``no'':
ctl_enable = <boolean>;
If the value of this parameter is ``yes'', then ipa(8) creates an Unix
domain socket and listens for commands on it. The created Unix domain
socket is owned by the user who run ipa(8), access permissions for the
socket are defined by the value of the ctl_socket_perm parameter.
There is the default path to this Unix domain socket (see the output of
the ``ipactl -h'' command), but you can define the Unix domain socket
pathname in the ctl_socket_path parameter:
ctl_socket_path = "/path/to/socket";
By default ipa(8) waits for data from the socket during 10 seconds, you
can change this timeout in the ctl_timeout parameter:
ctl_timeout = <time>;
You can define access permissions to the socket in the ctl_socket_perm
parameter:
ctl_socket_perm = <permissions>;
<Permissions> is a sequence of characters `u', `g' and `o'. These
characters determine who (user, group or others) is allowed to write to
the socket. You can allow other users to write to the socket only if
ipa(8) understands following parameters. If this parameter is not
given, then its default value is ``u''.
ipa(8) run under FreeBSD is able to check ipactl(8)'s messages creden-
tials (check this in the output of the ``ipa -v'' command), so on this
system you also have to define ctl_acl_class, ctl_dump_acl,
ctl_freeze_acl, ctl_stat_acl and ctl_rule_acl parameters.
The ctl_acl_class parameter defines class of ACL (access control list):
the name of ACL followed by ACL definition. This parameter should not
be placed in any section:
ctl_acl_class <class> [<ACL>];
ACL consists of elements separated by space characters, each its ele-
ment has following format:
[!]<user>|%<group>
The `!' character means that access is denied. The `%' character means
that the following name is a group name. <User> and <group> must be
given as symbolic names (UID and GID do not work here). Elements in
ACL are checked from the left to the right. Here ``access denied''
means that the user is not allowed to use some control command. When a
control message arrives, ipa(8) translates user name or groups name of
each ACL to UID or GID and compares it with a message's sender creden-
tials.
The ctl_dump_acl parameter applies ACL for ipactl(8)'s command dump:
ctl_dump_acl <class>;
The ctl_freeze_acl parameter applies ACL for ipactl(8)'s command
freeze:
ctl_freeze_acl <class>;
The ctl_stat_acl parameter applies ACL for ipactl(8)'s commands status
and memory:
ctl_stat_acl <class>;
The ctl_rule_acl parameter applies ACL to a rule for ipactl(8)'s
expire, restart, set and status commands:
ctl_rule_acl <class>;
If ACL is not defined and it is not inherited, then it is considered as
empty ACL, and means that access is denied for anybody.
Let's show how to use all these parameters in examples.
Example 1:
ctl_enable = yes;
ctl_socket_perm = ug;
In this example ipa(8) does not know how to get ipactl(8)'s control
messages credentials. We allow user and group to write commands to the
socket (this is controlled by access permissions of the socket). It is
impossible to allow other users to write to the socket for security
reasons.
Example 2:
ctl_enable = yes;
ctl_socket_path = "/var/tmp/ipactl.sock";
ctl_timeout = 10s;
Here we change Unix domain socket path and timeout. The ctl_socket_perm
parameter is not used, so its default value ``u'' will be used.
Example 3:
ctl_enable = yes;
ctl_socket_perm = ugo;
ctl_acl_class empty;
ctl_acl_class root root;
ctl_acl_class admins root !john %wheel;
ctl_dump_acl root;
global {
ctl_rule_acl admins;
/* ... */
}
rulepat "^vip" {
ctl_rule_acl root;
/* ... */
}
rulepat "^staff" {
ctl_rule_acl admins;
/* ... */
}
rule lan-all {
ctl_rule_acl empty;
/* ... */
}
In this example ipa(8) knows how to get ipactl(8)'s control messages
credentials, so we have to use ctl_acl_class, ctl_dump_acl and
ctl_rule_acl parameters, also we are able to allow to write to the
socket others users in the ctl_socket_perm parameter. Three ACL
classes are defined: empty, root, admins.
Freezing work of ipa(8).
It is sometime necessary to be sure that ipa(8) does nothing during
some period of time. There are two parameters which allow to freeze
work of ipa(8).
First parameter sleep_after_dump allows to specify period of time dur-
ing which ipa(8) should sleep and ignore any signals after execution of
the dump command from ipactl(8).
Second parameter freeze_time allows to specify period of time during
which ipa(8) should sleep and ignore any signals after receiving the
freeze command from ipactl(8).
freeze_time = <time>;
sleep_after_dump = <time>;
Values of these parameter should not be relatively big, because there
is a chance that some time event can be checked too late.
The sleep_after_dump and freeze_time parameters do not have default
values.
These parameters should not be placed in any section.
Example:
freeze_time = 30s;
sleep_after_dump = 5s;
Here we say ipa(8) to sleep 5 seconds after the dump command, and sleep
30 seconds after the freeze command. This is a very common case: we
send the dump command, for example, if we want to fetch current statis-
tics later, and we send the freeze command to freeze work of ipa(8) and
change something in the system. Here we assume that 30 seconds will be
enough to make all necessary changes in the system.
Order of active rules.
ipa(8) checks rules starting from the head of the active rules queue.
If all rules are independent, then you should not worry about their
order, but if, for example rule r1 should be checked before rule r2,
then read following several paragraphs.
If there is not any ac_gather_* parameters and there is not any work-
time parameters, then the order of active rules is the same as the
order of rules in the configuration file.
If there is at least one ac_gather_* parameter, then the order of rules
is changed to follow dependencies specified in ac_gather_* parameters,
but if some rules do not match regular expressions given in ac_gather_*
parameters, then their relative order is the same as their relative
order in the configuration file.
If there is not any ac_gather_* parameters and there are rules with
worktime parameters, then the order of these rules can be changed.
Dynamic rules always are added to the head of the active rules queue,
because dynamic rules cannot have ac_gather_* parameters, but some
static rule can get statistics from dynamic rules.
If you wish to keep the order of active rules the same as the order of
rules in the configuration file, then set the keep_rules_order parame-
ter to ``yes'', by default the value of this parameter is ``no'':
keep_rules_order = <boolean>;
Be careful with the order of rules in the configuration file if you
have at least one ac_gather_* parameter and the keep_rules_order param-
eter is set to ``yes'': place rules which give statistics below rules,
which get statistics.
Limits and thresholds in one rule are checked in the same order, as
they are written in the configuration and this order is not changed.
Note that some modules are sensitive to the order of active rules.
This parameter should not be placed in any section.
Example:
keep_rules_order = yes;
Now ipa(8) will not change the order of active rules.
Debugging.
Sometime it is necessary to find out why something goes wrong. There
are some parameters, which should be used for debugging ipa(8):
debug_ac_null - report about usage of null accounting system (alone,
1);
debug_db_null - report about usage of null database (alone, 1);
debug_time - debug various time related events (alone, 2);
debug_worktime - debug worktime parameters (alone, 1);
debug_exec - debug exec parameters (rule, 1);
debug_autorule - debug autorules (alone, 1);
debug_limit - debug limit related events (rule, 1);
debug_limit_init - give more information about limits initialization
(rule, 1);
debug_threshold - debug threshold related events (rule, 1);
debug_threshold_init - give more information about thresholds initial-
ization (rule, 1).
Each debugging parameter accepts a debug level as an argument, maximum
debug level for each debug parameter is specified as a number in paren-
thesis. If there is a word ``alone'' in parenthesis, then a parameter
should be placed alone, if there is a word ``rule'' in parenthesis,
then a parameter can be placed in global, rule, rulepat and autorule
sections.
By default debugging is off for everything.
Example:
debug_worktime = 1;
global {
debug_limit_init = 1;
}
In this example detail information will be sent to the log file about
worktime's time intervals and about limits initialization for all
rules.
FILES
ipa.conf
(run ipa(8) with the -h switch and check default configuration file
pathname)
SEE ALSO
ipa(8), ipactl(8), ipastat(8), ipastat.conf(5), ipa_mod(3)
AUTHOR
Andrey Simonenko <simon@comsys.ntu-kpi.kiev.ua>
BUGS
If you find any, please send email me.
April 16, 2005 IPA.CONF(5)