[unisog] Re: High speed firewalls - Connections per second not bits per second

Russell Fulton r.fulton at auckland.ac.nz
Mon Feb 21 22:29:31 GMT 2005

I forwarded Jim's query to the pf mailing list and got this response
from Daniel, one of the principle authors of pf.


-------- Forwarded Message --------
From: Daniel Hartmeier <daniel at benzedrine.cx>
To: Russell Fulton <r.fulton at auckland.ac.nz>
Cc: pf at benzedrine.cx
Subject: Re: [Fwd: [unisog] High speed firewalls - Connections per
second not bits per second]
Date: Mon, 21 Feb 2005 21:46:45 +0100
On Tue, Feb 22, 2005 at 09:02:56AM +1300, Russell Fulton wrote:

> Hmmm... what is the 'pf' response to this problem?   I seem to remember
> that 3.6 has per IP limits that can be set that perhaps could mitigate
> this sort of problem.

If I understand Jim correctly, he doesn't actually want those thousands
of connections per second to evaluate the ruleset and create state
entries, as they come from infected boxes scanning randomly.

3.6-current has a new feature that could be useful in this case (it'll
ship with 3.7 which will be released soon). You can track the rate of
TCP connection establishments per second per source IP address. When a
box exceeds a configurable limit, pf adds the IP address to a table. You
can use that table in arbitrary rules, for instance to cheaply block
further connection attempts from those boxes, or block everything except
for HTTP connections, which you redirect to a web server giving out
instructions on how to disinfect a box and get back access.

For instance, you have a ruleset like

  block in quick on $lan_if proto tcp from <infected>

  pass in on $lan_if proto tcp from $lan_if:network \
	keep state (max-src-conn-rate 50/30, overload <infected>)

The table <infected> is initially empty. Whenever a box on the LAN tries
to establish more than 50 new TCP connections within 30 seconds, pf will
add its address to the table. Further connection attempts from the box
will then get blocked by the first rule.

Assuming most infected boxes end up in the table like this, blocking
their connection attempts is rather cheap. Each connection attempt
causes one state table lookup (which fails) and evaluation of the
ruleset up to the block rule. If you put the block rule at the top,
that's one rule evaluation. The address lookup in the table is cheap
(and O(1)). There should be no problem dealing with thousands of such
connection attempts per second.

You can add a

  rdr pass on $lan_if proto tcp from <infected> to any port www \
	-> $lan_if port 8080

and run a small web server on port 8080 which gives them a static page
explaining why they're blocked. You can remove entries from the
<infected> table manually, or from a CGI (called from a HTML form on the
page explaining how a user can get himself unblocked, for instance).

This assumes that infected hosts show a clearly distinguishable pattern
and that you're willing to block them once they show the behaviour.
Also, we assume that most (or at least many) of the connection attempts
complete a TCP handshake.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 2201 bytes
Desc: not available
Url : http://www.dshield.org/pipermail/unisog/attachments/20050222/92aab12c/smime.bin

More information about the unisog mailing list