Most analyzers require Bro to capture a particular type of network traffic. These traffic flows can vary immensely in volume, so different analyzers can cost greatly differing amounts in terms of performance.
Bro predefines two redefinable string
variables that have special
interpretations with regard to filtering. (See Refinement for a discussion
of redefinable variables.)
capture_filter
is a tcpdump
filter that tells Bro what traffic it should capture. restrict_filter
limits what traffic Bro captures. The tcpdump
filter Bro
uses is:
(capture_filter) and (restrict_filter)So, for example, if you specify:
redef capture_filter = "port http"; redef restrict_filter = "net 128.3";
then the corresponding tcpdump
filter will be:
(port http) and (net 128.3)
which will capture all TCP port 80 traffic that has either a source
or destination address belonging to the 128.3
network (i.e.,
128.3/16
).
If you do not define capture_filter
, then its value
is set to “tcp or udp
”;
if you do not define restrict_filter
, then no restriction is
in effect.
You may have noticed that other than their default values, the
definitions of capture_filter
and restrict_filter
are symmetric. They differ only in the convention of how they
are used. Usually, you either don't define a value for restrict_filter
at all, or define it just once, using it to specify a restriction
that holds across your environment. For example, either to confine
packet capture to a subset of the traffic (like the "net 128.3"
example above), or to exclude a particular traffic source ("not host syn-flood.magnet.com"
) or both of these
("net 128.3 and not host syn-flood.magnet.com"
).
For capture_filter
, on the other hand,
you usually don't define a single value, but instead refine
it one or more times using the +=
initializer. (See Refinement
for a discussion of refining a variable's initial value.) The way
capture_filter
's refinement is defined, it constructs a filter
that is the “or” of each of its refinements. So, for example, if
at one point in your script you have:
redef capture_filter += "port ftp";
and at another:
redef capture_filter += "udp port 53";
and at a third:
redef capture_filter += "len >= 512 and len <= 1024";
then the resulting capture_filter
will be:
(port ftp) or (udp port 53) or (len >= 512 and len <= 1024)
(except there will be more parentheses, which don't actually affect the interpretation of the filter; see Refinement for the details of how the refinement is done, and why it leads to the extra parentheses).
restrict_filter
has the same refinement mechanism, the “or”ing
together of the different refinement additions, though, as mentioned above,
it is not usually refined.
As you add analyzers, the final tcpdump
filter can become quite
complicated. You can use the predefined print-filter
script
shown below to print out the filter.
This script handles the bro_init
event and exits after printing
the filter. Its intended use is that you can add it to the Bro command
line (“bro
my-own-script print-filter
”) when you want to
see what filter the script my-own-script winds up using.
event bro_init() { if ( restrict_filter == "" && capture_filter == "" ) print "tcp or not tcp"; # Capture everything. else if ( restrict_filter == "" ) print capture_filter; else if ( capture_filter == "" ) print restrict_filter; else print fmt("(%s) and (%s)", capture_filter, restrict_filter); exit(); }
In the example above, print_filter
prints out
the tcpdump
filter your Bro script would use and then exits.
There are two particular uses for print-filter
. The first is to debug
filtering problems. Unfortunately, Bro sometimes
uses sufficiently complicated expressions that they tickle bugs in
tcpdump
's optimizer. You can take the filter printed out for
your script and try running it through tcpdump
by hand, and
then also try using tcpdump
's
-O
option to see if turning
off the optimizer fixes the problem.
The second use is to provide a shadow backup to Bro: that is,
a version of tcpdump
running either on the same machine or a
separate machine that uses the same network filter as Bro. While
tcpdump
can't perform any analysis of the traffic, the shadow
guards against the possibility of Bro crashing, because if it does,
you will still have a record of the subsequent network traffic which
you can run through Bro for post-analysis.