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 declares two redefinable tables in pcap.bro
that have special interpretations with regard to filtering:
global capture_filters: table[string] of string &redef; global restrict_filters: table[string] of string &redef;
The key strings serve as a user-definable identifier for the filter
strings they are associated with. The entries of the capture_filters
table define what traffic Bro should capture, while restrict_filters
'
entries limit what traffic Bro captures. Bro builds the following tcpdump
filter from both tables:
(OR of capture_filters' entries) and (AND of restrict_filters' entries)
Thus, repeated Refinements of capture_filters
using the +=
initializer
are combined using logical “OR”s, whereas for restrict_filters
“AND”s are
used. This follows from the tables' respective purposes—capture_filters
permits any of its components, while restrict_filters
rejects
everything that does not comply with all of its components.
If you do not define capture_filters
, then its value
is set to “tcp or udp
”;
if you do not define restrict_filters
, then no restriction is
in effect.
Here is an example. If you specify:
redef capture_filters = { ["HTTP"] = "port http" }; redef restrict_filter = { ["mynet"] = "net 128.3" };
then the corresponding tcpdump
filter will be:
(port http) and (net 128.3)
which will capture only the TCP port 80 traffic that has either a source
or destination address belonging to the 128.3
network (i.e.,
128.3/16
). A more complex example:
redef capture_filters += { ["DNS"] = "udp port 53" }; redef capture_filters += { ["FTP"] = "port ftp" }; redef restrict_filters += { ["foonet"] = "net 128.3" }; redef restrict_filters += { ["noflood"] = "not host syn-flood.magnet.com" };
yields this tcpdump
filter:
((udp port 53) or (port ftp)) and ((net 128.3) and (not host syn-flood.magnet.com))
As you add analyzers, the final tcpdump
filter can become quite
complicated. You can load the predefined print-filter
script
to print out the resulting filter.
This script handles the bro_init
event and exits Bro 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.
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.