Session limitation
The Barefoot server has support
for limiting the number of active TCP or UDP session and the rate at
which new sessions can be established. This page describes how the
session functionality can be configured.
Note that the session syntax and functionality described here
is found only in Barefoot versions 1.4.1 and later,
replaces the similar session limit functionality that is
available as a commercial module for versions
of Barefoot.
Session control functionality
The Barefoot server supports several keywords
that can be used to control the number of
active sessions.
A session is essentially any forwarding mapping corresponding to
two IP-address and port number tuples; one for a client and one
for a server. For TCP this will mean one open TCP connection,
while for UDP it will mean one mapping where traffic has been
forwarded more recently than the UDP timeout.
These keywords can be used in any rule type (client/hostid).
The keywords fall into two groups: those that specify a total
limit for all clients matching the rule the keywords are used in,
and those that specify a limit on any unique client IP-address
matching the rule. Limits can be enforced on both TCP and UDP
sessions.
The session.max and session.throttle keywords
specify total limits for a rule:
- session.max
- The total number of concurrent sessions allowed for clients matching
the rule.
The max value is specified in the following format: LIMIT.
The LIMIT value gives the maximum number of sessions that
can exist concurrently.
When this number is reached, subsequent clients matching the rule
will be blocked, as if the rule was a block rule.
- session.throttle
- The maximum rate at which session can be created.
The rate value is specified in the following format:
LIMIT/SECONDS. The LIMIT value gives the maximum
number of sessions that can be created in an interval of SECONDS
seconds.
For example, 50/1 allows the creation of 50 new sessions
each second. When this number is reached, subsequent clients
matching the rule will be blocked, as if the rule was a block
rule.
The session.state.key, session.state.key.hostindex
and session.state.max, and session.state.throttle
keywords enforce similar limits, but apply control per client
IP-address, rather than simply for all sessions matching
the rule. In other words, each unique client IP-address will
be allowed to create the specified number of sessions, at the
specified rate, and the sessions created by one client IP-address
will not affect other clients.
Per client IP-address limits can be combined with global
limits, in which case both limits will be enforced.
- session.state.key
- This keywords is used to specify which IP-address should be
used when setting the per IP-address limits. It can currently
accept one of two possible values, from
and hostid. The from value will cause
the session.state.max and session.state.throttle
values to be applied based on the source address of clients,
making it possible to limit the maximum number of connections
and maximum connection rate for requests coming from any
single IP-address.
A value of hostid will cause the hostid value to be
used, allowing limits to be placed also on connections that are
forwarded via a proxy supporting the hostid functionality.
- session.state.key.hostindex
- When session.state.key is set to hostid,
this keyword can be used to control which hostid value to
use. Accepted values are 1, and 2. The
default value is 1
- session.state.max
- Same as session.max, but applies to sessions from
a single IP-address, based on the session.state.key
used in the rule.
- session.state.throttle
- Same as session.throttle, but applies to sessions from
a single IP-address, based on the session.state.key
used in the rule.
The session.inheritable keyword found in Dante has no function
in Barefoot and will be ignored if set.
Quick-start example
The following example illustrates how the session keywords can be
used in a typical configuration.
The session keywords in the rule limit the total number of
sessions to 10000 and specify that a maximum of 100 new sessions
can be created each second.
In addition there is a limit on the maximum number of
sessions that can come from a single source IP-address:
at most 100 sessions are allowed from each IP-address, and
at most 10 new sessions every two seconds can be created from
a single IP-address.
#pass all requests but limit the number of sessions and connect rate
client pass {
from: 0.0.0.0/0 to: eth0 port = http
bounce to: www.example.com port = http
log: connect disconnect error
#limit for all clients
session.max: 10000
session.throttle: 100/1
#per-ip limit
session.state.key: from
session.state.max: 100
session.state.throttle: 10/2
}
Each connection that is accepted is checked both against the per
IP-address limits for the client source address
(session.state.max and session.state.throttle) and
against the combined limit for all clients
(session.max and session.throttle).
Session log format
When a connection is blocked due to a session limit this will be
indicated in the log output from Barefoot
(provided the Barefoot configuration specifies
that connections should be logged).
There are four possible descriptions used in the log lines,
one for each of the session.max, session.throttle,
session.state.max, and session.state.throttle
limits. The descriptions have the following format:
- session.max
- session limit reached (LIMIT/LIMIT slots in use)
- session.throttle
- session rate limit reached (already accepted LIMIT new clients during the last SECONDSs. Current client count: LIMIT)
- session.state.max
- per-key session limit reached (LIMIT/LIMIT slots in use)
- session.state.throttle
- per-key session rate limit reached (already accepted LIMIT new clients during the last SECONDSs. Current client count: LIMIT)
The above messages are used in the part of the block log
entries that describe the reason why a request has been
blocked. In a log file, the resulting full log message can look
like the following, which corresponds to a per IP-address
throttle limit of 3 having been reached:
info: block(1): tcp/accept ]: 10.0.0.1.34639 172.16.0.27.7877: per-key session rate limit reached (already accepted 3 new clients during the last 1s. Current client count: 3)
Session limit request processing
The requests processing in Barefoot is
basically performed in these steps:
- The Barefoot server receives a connection
from a client.
- The Barefoot server evaluates
the client-rules to determine if the connection should
be dropped.
- The Barefoot server evaluates
the hostid-rules to determine if the connection should
be dropped.
- Unless the request is blocked, the request is executed on
behalf on the client.
When the client and hostid-rules are evaluated, the following
information is available:
- The IP-address and port number the client is connecting from.
- The IP-address and port number the Barefoot
server received the request on.
- Any hostid address values set on the connection.
- Any usernames obtained via out-of-band mechanisms such as the
rfc931 ident protocol.
Usage example
Below is a fairly complex example that combines the functionality for
handling hostid values with session limits.
The server is assumed to not communicate directly with clients
but receive connections from a trusted proxy, with the IP-address
192.168.1.1. Only connections from this address are accepted, and
the connections are required to have a hostid value set. Additional
restrictions are placed by the hostid-rule, which will only
accept connections with a hostid value from the 172.16/12
network.
In addition to this, there are session limits on both the
maximum number of connections that will be accepted (5000), and
the rate at which new connections will be accepted (50
connections per second). For any given hostid address, there are
also limits on the max number of connections (10) and the rate
of new connections (10 per every 2 seconds).
#always add client IP on outgoing connections, keeping the existing value.
external.tcp.hostid: add-client
#pass client connections from the trusted server 192.168.1.1, but require
#them to have a hostid set.
client pass {
from: 0.0.0.0/0 to: eth0 port = http
bounce to: www.example.com port = http
#require that hostid values are set
hostid: 0.0.0.0/0
#limit for all clients
session.max: 5000
session.throttle: 50/1
#per-IP limit, using hostid IP address
session.state.key: hostid
session.state.key.hostindex: 1 #use first hostid value, default
session.state.max: 10
session.state.throttle: 10/2
}
#only clients with a hostid from the 172.16-net are accepted.
hostid pass {
from: 172.16.0.0/12 to: 0.0.0.0/0
hostindex: 1 #only match first value, default
}
Special notes
Limits are enforced on both TCP and UDP sessions, but they
are not enforced on individual UDP packets.
|