From 194c9c21d1ad7c84a581d70dbd5de996e658d55a Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Fri, 14 Oct 2011 22:12:05 -0700 Subject: [PATCH] Distribution cleanup and documentation setupt tweaks. --- COPYING | 28 +--- aux/binpac | 2 +- aux/bro-aux | 2 +- aux/broccoli | 2 +- aux/broctl | 2 +- aux/btest | 2 +- doc/.gitignore | 1 + doc/Makefile | 7 + doc/README | 39 +++++- doc/bin/rst2html.py | 62 +++++++++ doc/cluster.rst | 16 ++- doc/deployment.png | Bin 0 -> 36081 bytes doc/geoip.rst | 102 ++++++++++++++ doc/index.rst | 50 +++++++ doc/notice.rst | 5 + doc/quickstart.rst | 191 ++++++++++++++------------ doc/scripts/example.rst | 291 ++++++++++++++++++++++++++++++++++++++++ doc/upgrade.rst | 142 +++++++++++--------- pkg/make-src-packages | 8 +- 19 files changed, 767 insertions(+), 185 deletions(-) create mode 100644 doc/.gitignore create mode 100644 doc/Makefile create mode 100755 doc/bin/rst2html.py create mode 100644 doc/deployment.png create mode 100644 doc/geoip.rst create mode 100644 doc/index.rst create mode 100644 doc/notice.rst create mode 100644 doc/scripts/example.rst diff --git a/COPYING b/COPYING index f9bba2b90e..5ae3c62e7a 100644 --- a/COPYING +++ b/COPYING @@ -1,11 +1,12 @@ -Copyright (c) 1995-2010, The Regents of the University of California, -through Lawrence Berkeley National Laboratory. All rights reserved. +Copyright (c) 1995-2011, The Regents of the University of California +through the Lawrence Berkeley National Laboratory and the +International Computer Science Institute. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -(1) Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. +(1) Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the @@ -29,20 +30,5 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -Note that some files in the Bro distribution carry their own copyright -notices. The above applies to the Bro scripts in policy/ (other than as -noted below) and the source files in src/, other than: - - policy/sigs/p0fsyn.osf - src/H3.h - src/OSFinger.cc - src/OSFinger.h - src/bsd-getopt-long.c - src/bsd-getopt-long.h - src/md5.c - src/md5.h - src/patricia.c - src/patricia.h - -In addition, other components, such as the build system, may have -separate copyrights. +Note that some files in the distribution may carry their own copyright +notices. diff --git a/aux/binpac b/aux/binpac index 952724eb35..479f10b9d9 160000 --- a/aux/binpac +++ b/aux/binpac @@ -1 +1 @@ -Subproject commit 952724eb355aa7d4ba50623e97a666dd7d1173a8 +Subproject commit 479f10b9d9abeb3024d358935691ed8bf9bb8038 diff --git a/aux/bro-aux b/aux/bro-aux index 86c6041935..94401ea11f 160000 --- a/aux/bro-aux +++ b/aux/bro-aux @@ -1 +1 @@ -Subproject commit 86c604193543e0fa85f7edeb132436f3d1b33ac7 +Subproject commit 94401ea11f78665973bcf833c2dd28c165d02bc6 diff --git a/aux/broccoli b/aux/broccoli index 042ce05428..31c3d1d9ef 160000 --- a/aux/broccoli +++ b/aux/broccoli @@ -1 +1 @@ -Subproject commit 042ce05428035b6bdd4863b9d316b7fd4bb5252e +Subproject commit 31c3d1d9efa706969f0cd98223444c5f064a6fa7 diff --git a/aux/broctl b/aux/broctl index 807a54fb26..8434c3f577 160000 --- a/aux/broctl +++ b/aux/broctl @@ -1 +1 @@ -Subproject commit 807a54fb264e0e2d00aa2267efd39738658ef320 +Subproject commit 8434c3f57772dab896f8c7c9c205a523dddf3f75 diff --git a/aux/btest b/aux/btest index 3c0b0e9a91..87c95911be 160000 --- a/aux/btest +++ b/aux/btest @@ -1 +1 @@ -Subproject commit 3c0b0e9a91060a7a453a5d6fb72ed1fd9071fda9 +Subproject commit 87c95911be41b36ca85f6d15dd86e127e9048c63 diff --git a/doc/.gitignore b/doc/.gitignore new file mode 100644 index 0000000000..1936cc1d44 --- /dev/null +++ b/doc/.gitignore @@ -0,0 +1 @@ +html diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 0000000000..2756093a27 --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,7 @@ + +all: + test -d html || mkdir html + for i in *.rst; do echo "$$i ..."; ./bin/rst2html.py $$i >html/`echo $$i | sed 's/rst$$/html/g'`; done + +clean: + rm -rf html diff --git a/doc/README b/doc/README index 1333ed77b7..1e30d5ccc9 100644 --- a/doc/README +++ b/doc/README @@ -1 +1,38 @@ -TODO + +Documentation +============= + +This directory contains Bro documentation in reStructured text format +(see http://docutils.sourceforge.net/rst.html). + +Please note that for now these files are primarily intended for use on +http://www.bro-ids.org. While the Bro build process will render local +versions into ``build/doc/`` (if docutils is found), the resulting +HTML is very minimalistic and some features are not supported. In +particular, some links will be broken. + + +Notes for Writing Documentation +------------------------------- + +* If you want to refer to a Bro script that's part of the + distribution, use {{'`foo.bro + <{{autodoc_bro_scripts}}/path/to/foo.html>`_'}}. For example, + ``{{'{{autodoc_bro_scripts}}/scripts/base/frameworks/notice/main.html}}'}}``. + +* If you want to refer to a page on the Bro web site, use the + ``docroot`` macro (e.g., + ``{{'href="{{docroot}}/download/index.html"'}}). Make sure to + include the ``index.html`` for the main pages, just as in the + example. + +* If you want to refer to page inside this directory, use a relative + path with HTML extension. (e.g., ``href="quickstart.html``). + +Guidelines +---------- + +TODO. + + + diff --git a/doc/bin/rst2html.py b/doc/bin/rst2html.py new file mode 100755 index 0000000000..79c835d6c4 --- /dev/null +++ b/doc/bin/rst2html.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python +# +# Derived from docutils standard rst2html.py. +# +# $Id: rst2html.py 4564 2006-05-21 20:44:42Z wiemann $ +# Author: David Goodger +# Copyright: This module has been placed in the public domain. +# +# +# Extension: we add to dummy directorives "code" and "console" to be +# compatible with Bro's web site setup. + +try: + import locale + locale.setlocale(locale.LC_ALL, '') +except: + pass + +import textwrap + +from docutils.core import publish_cmdline, default_description + +from docutils import nodes +from docutils.parsers.rst import directives, Directive +from docutils.parsers.rst.directives.body import LineBlock + +class Literal(Directive): + #max_line_length = 68 + max_line_length = 0 + + required_arguments = 0 + optional_arguments = 1 + final_argument_whitespace = True + has_content = True + + def wrapped_content(self): + content = [] + + if Literal.max_line_length: + for line in self.content: + content += textwrap.wrap(line, Literal.max_line_length, subsequent_indent=" ") + else: + content = self.content + + return u'\n'.join(content) + + def run(self): + self.assert_has_content() + content = self.wrapped_content() + literal = nodes.literal_block(content, content) + return [literal] + +directives.register_directive('code', Literal) +directives.register_directive('console', Literal) + +description = ('Generates (X)HTML documents from standalone reStructuredText ' + 'sources. ' + default_description) + +publish_cmdline(writer_name='html', description=description) + + + diff --git a/doc/cluster.rst b/doc/cluster.rst index 7fd0298b11..bf6f00b625 100644 --- a/doc/cluster.rst +++ b/doc/cluster.rst @@ -9,11 +9,21 @@ Bro is not multithreaded, so once the limitations of a single processor core are Architecture --------------- -There are 4 main components to a Bro cluster which are described in detail below. +The figure below illustrates the main components of a Bro cluster. + +.. {{git_pull('bro:doc/deployment.png')}} + +.. image:: deployment.png + +Tap +*** +This is a mechanism that splits the packet stream in order to make a copy +available for inspection. Examples include the monitoring port on a switch and +an optical splitter for fiber networks. Frontend ******** -This is a discrete hardware device or on-host technique that will split your traffic into many streams or flows. The Bro binary does not do this job. There are numerous ways to accomplish this task, some of which are described below in the Frontend section. +This is a discrete hardware device or on-host technique that will split your traffic into many streams or flows. The Bro binary does not do this job. There are numerous ways to accomplish this task, some of which are described below in `Frontend Options`_. Manager ******* @@ -50,7 +60,7 @@ Discrete hardware flow balancers cPacket ^^^^^^^ -If you are monitoring one or more 10G physical interfaces, the recommended solution is to use either a cFlow or cVu device from cPacket (is this too much? i don’t want to recommend gigamon with all of the problems we’ve had various places and i don’t know enough about VSS monitoring’s offerings to make a judgement. i don’t want to recommend netoptics director hardware either, from what i understand it doesn’t fit the use case very well). These devices will perform layer-2 load balancing by rewriting the destination ethernet MAC address to cause each packet associated with a particular flow to have the same destination MAC. The packets can then be passed directly to a monitoring host or onward to a commodity switch to split the traffic out to multiple 1G interfaces for the workers. This can ultimately greatly reduce costs since workers can use relatively inexpensive 1G interfaces. +If you are monitoring one or more 10G physical interfaces, the recommended solution is to use either a cFlow or cVu device from cPacket because they are currently being used very successfully at a number of sites. These devices will perform layer-2 load balancing by rewriting the destination ethernet MAC address to cause each packet associated with a particular flow to have the same destination MAC. The packets can then be passed directly to a monitoring host where each worker has a BPF filter to limit it's visibility to only that stream of flows or onward to a commodity switch to split the traffic out to multiple 1G interfaces for the workers. This can ultimately greatly reduce costs since workers can use relatively inexpensive 1G interfaces. OpenFlow Switches ^^^^^^^^^^^^^^^^^ diff --git a/doc/deployment.png b/doc/deployment.png new file mode 100644 index 0000000000000000000000000000000000000000..abd9b927225e7041724fcfc22a393d49dd284a22 GIT binary patch literal 36081 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

P>7{V)OoUAhv2p?Lt?N3PA69sA7fck?xtce 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 ODTAl0pUXO@geCx1bEKL8 literal 0 HcmV?d00001 diff --git a/doc/geoip.rst b/doc/geoip.rst new file mode 100644 index 0000000000..53413b5bee --- /dev/null +++ b/doc/geoip.rst @@ -0,0 +1,102 @@ + +=========== +GeoLocation +=========== + +.. class:: opening + + During the process of creating policy scripts the need may arise + to find the geographic location for an IP address. Bro has support + for the `GeoIP library `__ at the + policy script level beginning with release 1.3 to account for this + need. + +.. contents:: + +GeoIPLite Database Installation +------------------------------------ + +A country database for GeoIPLite is included when you do the C API +install, but for Bro, we are using the city database which includes +cities and regions in addition to countries. + +`Download `__ the geolitecity +binary database and follow the directions to install it. + +FreeBSD Quick Install +--------------------- + +.. console:: + + pkg_add -r GeoIP + wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz + gunzip GeoLiteCity.dat.gz + mv GeoLiteCity.dat /usr/local/share/GeoIP/GeoIPCity.dat + + # Set your environment correctly before running Bro's configure script + export CFLAGS=-I/usr/local/include + export LDFLAGS=-L/usr/local/lib + + +CentOS Quick Install +-------------------- + +.. console:: + + yum install GeoIP-devel + + wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz + gunzip GeoLiteCity.dat.gz + mkdir -p /var/lib/GeoIP/ + mv GeoLiteCity.dat /var/lib/GeoIP/GeoIPCity.dat + + # Set your environment correctly before running Bro's configure script + export CFLAGS=-I/usr/local/include + export LDFLAGS=-L/usr/local/lib + + +Usage +----- + +There is a single built in function that provides the GeoIP +functionality: + +.. code:: bro + + function lookup_location(a:addr): geo_location + +There is also the ``geo_location`` data structure that is returned +from the ``lookup_location`` function: + +.. code:: bro + + type geo_location: record { + country_code: string; + region: string; + city: string; + latitude: double; + longitude: double; + }; + + +Example +------- + +To write a line in a log file for every ftp connection from hosts in +Ohio, this is now very easy: + +.. code:: bro + + global ftp_location_log: file = open_log_file("ftp-location"); + + event ftp_reply(c: connection, code: count, msg: string, cont_resp: bool) + { + local client = c$id$orig_h; + local loc = lookup_location(client); + if (loc$region == "OH" && loc$country_code == "US") + { + print ftp_location_log, fmt("FTP Connection from:%s (%s,%s,%s)", client, loc$city, loc$region, loc$country_code); + } + } + + diff --git a/doc/index.rst b/doc/index.rst new file mode 100644 index 0000000000..5cbe82eec6 --- /dev/null +++ b/doc/index.rst @@ -0,0 +1,50 @@ + + +Bro Documentation +================= + +`Getting Started <{{git('bro:doc/quickstart.rst')}}>`_ + A quick introduction into using Bro 2.x. + +`Bro 1.5 to 2.0 Upgrade Guide <{{git('bro:doc/upgrade.rst')}}>`_ + Guidelines and notes about upgrading from Bro 1.5 to 2.x. Lots of + things have changed, so make sure to read this when upgrading. + +`BroControl <{{git('broctl:doc/broctl.rst')}}>`_ + An interactive console for managing Bro installations. + +`Script Reference <{{autodoc_bro_scripts}}/index.html>`_ + A complete reference of all policy scripts shipped with Bro. + +`FAQ <{{docroot}}/documentation/faq.html>`_ + A list with frequently asked questions. + +`How to Report a Problem <{{docroot}}/reporting-problems.html>`_ + Some advice for when you see Bro doing something you believe it + shouldn't. + +Frameworks +---------- + +Bro comes with a number of frameworks, some of which are described in +more detail here: + +`Reporting <{{git('bro:doc/notice.rst')}}>`_ + The notice/alarm framework. + +`Logging <{{git('bro:doc/logging.rst')}}>`_ + Customizing and extensing Bro's logging. + +`Cluster <{{git('bro:doc/cluster.rst')}}>`_ + Setting up a Bro Cluster when a single box can't handle the traffic anymore. + +`Signatures <{{git('bro:doc/signatures.rst')}}>`_ + Bro has support for traditional NIDS signatures as well. + +How-Tos +------- + +We also collect more specific How-Tos on specific topics: + +`Using GeoIP in Bro scripts <{{git('bro:doc/geoip.rst')}}>`_ + Installation and usage of the the GeoIP library. diff --git a/doc/notice.rst b/doc/notice.rst new file mode 100644 index 0000000000..672d5acec7 --- /dev/null +++ b/doc/notice.rst @@ -0,0 +1,5 @@ + +The Notice Framework +==================== + +TODO. diff --git a/doc/quickstart.rst b/doc/quickstart.rst index 96a02c8b78..8f2a43b675 100644 --- a/doc/quickstart.rst +++ b/doc/quickstart.rst @@ -26,14 +26,9 @@ source code forms. Pre-Built Binary Release Packages --------------------------------- -See the `downloads page `_ for currently +See the `downloads page <{{docroot}}/download/index.html>`_ for currently supported/targeted platforms. -The primary install prefix for binary packages is ``/opt/bro``. - -Non-MacOS packages that include BroControl also put variable/runtime data -(e.g. bro logs) in ``/var/opt/bro``. - * RPM .. console:: @@ -51,9 +46,9 @@ Non-MacOS packages that include BroControl also put variable/runtime data Just open the ``Bro-all-*.dmg`` and then run the ``.pkg`` installer. Everything installed by the package will go into ``/opt/bro``. -* FreeBSD - - TODO: ports will eventually be available. +The primary install prefix for binary packages is ``/opt/bro``. +Non-MacOS packages that include BroControl also put variable/runtime +data (e.g. Bro logs) in ``/var/opt/bro``. Building From Source -------------------- @@ -113,12 +108,12 @@ and sendmail for sending emails. * Ports-based FreeBSD - (libz, libmagic, and sendmail are typically already available) - .. console:: > sudo pkg_add -r GeoIP + libz, libmagic, and sendmail are typically already available. + * Mac OS X Vanilla OS X installations don't ship with libmagic or libGeoIP, but @@ -127,17 +122,17 @@ and sendmail for sending emails. against them. Additional steps may be needed to `get the right GeoIP database -`_. +`_. Compiling Bro Source Code ~~~~~~~~~~~~~~~~~~~~~~~~~ Bro releases are bundled into source packages for convenience and -available from the `downloads page `_. +available from the `downloads page <{{docroot}}/download/index.html>`_. The latest Bro development versions are obtainable through git repositories -hosted at `{{cfg_git_url}} <{{cfg_git_url}}>`_. See our `git development -documentation `_ for comprehensive +hosted at `git.bro-ids.org `_. See our `git development +documentation <{{docroot}}/development/process.html>`_ for comprehensive information on Bro's use of git revision control, but the short story for downloading the full source code experience for Bro via git is: @@ -195,15 +190,15 @@ traffic-monitoring cluster. .. note:: Below, ``$PREFIX``, is used to reference the Bro installation root directory. -Minimal Starting Config ------------------------ +A Minimal Starting Configuration +-------------------------------- -The basic configuration changes to make for a minimal BroControl installation +These are the basic configuration changes to make for a minimal BroControl installation that will manage a single Bro instance on the ``localhost``: 1) In ``$PREFIX/etc/node.cfg``, set the right interface to monitor. 2) In ``$PREFIX/etc/networks.cfg``, comment out the default settings and add - the networking that Bro will consider local to the monitored environment. + the networks that Bro will consider local to the monitored environment. 3) In ``$PREFIX/etc/broctl.cfg``, change the ``MailTo`` email address to a desired recipient and the ``LogRotationInterval`` to a desired log archival frequency. @@ -232,9 +227,12 @@ can view the details with the ``diag`` command. If started successfully, the Bro instance will begin analyzing traffic according to a default policy and output the results in ``$PREFIX/logs``. -.. note:: The `FAQ `_ entries about - capturing as an unprivileged user and checksum offloading are particularly - relevant at this point. +.. note:: The user starting BroControl needs permission to capture + network traffic. If you are not root, you may need to grant further + privileges to the account you're using; see the `FAQ + <{{docroot}}/documentation/faq.html>`_. Also, if it + looks like Bro is not seeing any traffic, check out the FAQ entry + checksum offloading. You can leave it running for now, but to stop this Bro instance you would do: @@ -242,26 +240,32 @@ You can leave it running for now, but to stop this Bro instance you would do: [BroControl] > stop +We also recommend to insert the following entry into `crontab`: + +.. console:: + + 0-59/5 * * * * $PREFIX/bin/broctl cron + +This will perform a number of regular housekeeping tasks, including +verifying that the process is still running (and restarting if not in +case of any abnormal termination). + Browsing Log Files ------------------ -By default, logs are written in human-readable (ASCII) format and data -is organized into columns (tab-delimited). Logs that are part of the -current rotation interval are accumulated in ``$PREFIX/logs/current/`` -(if Bro is not running, then there will not be any log files in this -directory). For example, the ``http.log`` contains the results of -analysis performed by scripts in ``$PREFIX/share/bro/``\ **base**\ -``/protocols/http/`` or ``$PREFIX/share/bro/``\ **policy**\ -``/protocols/http/`` (both contain code that may contribute to what ends -up in the log). - -Here's the first few columns of ``http.log``:: +By default, logs are written out in human-readable (ASCII) format and +data is organized into columns (tab-delimited). Logs that are part of +the current rotation interval are accumulated in +``$PREFIX/logs/current/`` (if Bro is not running, the directory will +be empty). For example, the ``http.log`` contains the results of Bro +HTTP protocol analysis. Here are the first few columns of +``http.log``:: # ts uid orig_h orig_p resp_h resp_p 1311627961.8 HSH4uV8KVJg 192.168.1.100 52303 192.150.187.43 80 Logs that deal with analysis of a network protocol will often start like this: -a timestamp, a connection identifier (UID), and a connection 4-tuple +a timestamp, a unique connection identifier (UID), and a connection 4-tuple (originator host/port and responder host/port). The UID can be used to identify all logged activity (possibly across multiple log files) associated with a given connection 4-tuple over its lifetime. @@ -275,24 +279,24 @@ columns (shortened for brevity) show a request to the root of Bro website:: Some logs are worth explicit mention: -``weird.log`` contains unusual/exceptional activity that can indicate -malformed connections, traffic that doesn't conform to a particular -protocol, malfunctioning/misconfigured hardware, or even an attacker -attempting to avoid/confuse a sensor. Without context, it's hard to judge -whether this category of activity is interesting and so that is left up to -the user to configure. + ``weird.log`` + Contains unusual/exceptional activity that can indicate + malformed connections, traffic that doesn't conform to a particular + protocol, malfunctioning/misconfigured hardware, or even an attacker + attempting to avoid/confuse a sensor. Without context, it's hard to + judge whether this category of activity is interesting and so that is + left up to the user to configure. -``notice.log`` identifies specific activity that Bro recognizes as -potentially interesting, odd, or bad. + ``notice.log`` + Identifies specific activity that Bro recognizes as + potentially interesting, odd, or bad. In Bro-speak, such + activity is called a "notice". -``alarm.log`` is just a filtered version of ``notice.log``, containing -only notices for which the user has taught Bro to recognize as -interesting/bad. By default, ``BroControl`` regularly takes all the logs from -``$PREFIX/logs/current``, and archives/compresses them to a directory -named by date, e.g. ``$PREFIX/logs/2011-10-06``. The frequency -at which this is done can be configured via the ``LogRotationInterval`` +``$PREFIX/logs/current`` and archives/compresses them to a directory +named by date, e.g. ``$PREFIX/logs/2011-10-06``. The frequency at +which this is done can be configured via the ``LogRotationInterval`` option in ``$PREFIX/etc/broctl.cfg``. Deployment Customization @@ -329,23 +333,22 @@ let's do a quick intro to Bro scripting. Bro Scripts ~~~~~~~~~~~ -Bro ships with many pre-written scripts that are highly customizable to -support traffic analysis for your specific environment. By default, -these will be installed into ``$PREFIX/share/bro`` and can be identified -by the use of a ``.bro`` file name extension. These files should -**never** be edited directly as changes will be lost when upgrading to -newer versions of Bro. The exception to this rule is that any ``.bro`` -file in ``$PREFIX/share/bro/site`` can be modified without fear of being -clobbered later. If desired, the ``site`` directory can also be used to -store new scripts. The other main script directories under -``$PREFIX/share/bro`` are ``base`` and ``policy``. By default, Bro -automatically loads all scripts under ``base`` (unless the ``-b`` -command line option is supplied), which deal either with collecting -basic/useful state about network activities or providing -frameworks/utilities that extend Bro's functionality without any -performance cost. Scripts under the ``policy`` directory may be more -situational or costly, and so users must explicitly choose if -they want to load them. +Bro ships with many pre-written scripts that are highly customizable +to support traffic analysis for your specific environment. By +default, these will be installed into ``$PREFIX/share/bro`` and can be +identified by the use of a ``.bro`` file name extension. These files +should **never** be edited directly as changes will be lost when +upgrading to newer versions of Bro. The exception to this rule is the +directory ``$PREFIX/share/bro/site`` where local site-specific files +can be put without fear of being clobbered later. The other main +script directories under ``$PREFIX/share/bro`` are ``base`` and +``policy``. By default, Bro automatically loads all scripts under +``base`` (unless the ``-b`` command line option is supplied), which +deal either with collecting basic/useful state about network +activities or providing frameworks/utilities that extend Bro's +functionality without any performance cost. Scripts under the +``policy`` directory may be more situational or costly, and so users +must explicitly choose if they want to load them. The main entry point for the default analysis configuration of a standalone Bro instance managed by BroControl is the ``$PREFIX/share/bro/site/local.bro`` @@ -355,8 +358,9 @@ we have to figure out what to add. Redefining Script Option Variables ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Many simple customizations just require you to redefine (using the ``redef`` -operator) a variable from a standard Bro script with your own value. +Many simple customizations just require you to redefine a variable +from a standard Bro script with your own value, using Bro's ``redef`` +operator. The typical way a standard Bro script advertises tweak-able options to users is by defining variables with the ``&redef`` attribute and ``const`` qualifier. @@ -364,9 +368,10 @@ A redefineable constant might seem strange, but what that really means is that the variable's value may not change at run-time, but whose initial value can be modified via the ``redef`` operator at parse-time. -So let's continue on our path to modify the behavior for the two SSL and SSH -notices. Looking at -`$PREFIX/share/bro/base/frameworks/notice/main.bro <{{ git('base.frameworks.notice.main.bro.txt', 'master:bro/scripts/base/frameworks/notice/main.bro') }}>`_, +So let's continue on our path to modify the behavior for the two SSL +and SSH notices. Looking at +`$PREFIX/share/bro/base/frameworks/notice/main.bro +<{{autodoc_bro_scripts}}/scripts/base/frameworks/notice/main.html>`_, we see that it advertises: .. code:: bro @@ -441,15 +446,16 @@ that only takes the email action for SSH logins to a defined set of servers: }; You'll just have to trust the syntax for now, but what we've done is first -first declare our own variable to hold a set watched addresses, -``watched_servers``, then added a record to the policy that will generate +first declare our own variable to hold a set of watched addresses, +``watched_servers``; then added a record to the policy that will generate an email on the condition that the predicate function evaluates to true, which is whenever the notice type is an SSH login and the responding host stored inside the ``Info`` record's connection field is in the set of watched servers. -.. note:: record field member access is done with the '$' character instead - of a '.' as might be expected in order to avoid ambiguity with the builtin - address type's use of '.' in IPv4 dotted decimal representations. +.. note:: record field member access is done with the '$' character + instead of a '.' as might be expected from other languages, in + order to avoid ambiguity with the builtin address type's use of '.' + in IPv4 dotted decimal representations. Remember, to finalize that configuration change perform the ``check``, ``install``, ``restart`` commands in that order inside the BroControl shell. @@ -462,11 +468,13 @@ tweak the most basic options. Here's some suggestions on what to explore next: * We only looked at how to change options declared in the notice framework, there's many more options to look at in other script packages. +* Look at the scripts in ``$PREFIX/share/bro/policy`` for further ones + you may want to load. * Reading the code of scripts that ship with Bro is also a great way to gain understanding of the language and how you can start writing your own custom analysis. -* Review the `FAQ `_. -* Check out more `documentation `_. +* Review the `FAQ <{{docroot}}/documentation/faq.html>`_. +* Check out more `documentation <{{docroot}}/documentation/index.html>`_. * Continue reading below for another mini-tutorial on using Bro as a standalone command-line utility. @@ -492,10 +500,27 @@ that's available. Bro will output log files into the working directory. -.. note:: The `FAQ `_ entries about +.. note:: The `FAQ <{{docroot}}/documentation/faq.html>`_ entries about capturing as an unprivileged user and checksum offloading are particularly relevant at this point. +To use the site-specific ``local.bro`` script, just add it to the +command-line: + +.. console:: + + > bro -i en0 local + +This will cause Bro to print a warning about lacking the +``Site::local_nets`` variable being configured. You can supply this +information at the command line like this (supply your "local" subnets +in place of the example subnets): + +.. console:: + + > bro -r mypackets.trace local "Site::local_nets += { 1.2.3.0/24, 5.6.7.0/24 }" + + Reading Packet Capture (pcap) Files ----------------------------------- @@ -519,21 +544,13 @@ and tell Bro to perform all the default analysis on the capture which primarily Bro will output log files into the working directory. -If you are interested in more detection, you can load the ``local`` +If you are interested in more detection, you can again load the ``local`` script that we include as a suggested configuration: .. console:: > bro -r mypackets.trace local -This will cause Bro to print a warning about lacking the -``Site::local_nets`` variable being configured. You can supply this -information at the command line like this (supply your "local" subnets -in place of the example subnets): - -.. console:: - - > bro -r mypackets.trace local "Site::local_nets += { 1.2.3.0/24, 5.6.7.0/24 }" Telling Bro Which Scripts to Load --------------------------------- diff --git a/doc/scripts/example.rst b/doc/scripts/example.rst new file mode 100644 index 0000000000..b76b9af59b --- /dev/null +++ b/doc/scripts/example.rst @@ -0,0 +1,291 @@ +.. Automatically generated. Do not edit. + +example.bro +=========== + +:download:`Original Source File ` + +Overview +-------- +This is an example script that demonstrates how to document. Comments +of the form ``##!`` are for the script summary. The contents of +these comments are transferred directly into the auto-generated +`reStructuredText `_ +(reST) document's summary section. + +.. tip:: You can embed directives and roles within ``##``-stylized comments. + +:Imports: :doc:`policy/frameworks/software/vulnerable ` + +Summary +~~~~~~~ +Options +####### +============================================================================ ====================================== +:bro:id:`Example::an_option`: :bro:type:`set` :bro:attr:`&redef` add documentation for "an_option" here + +:bro:id:`Example::option_with_init`: :bro:type:`interval` :bro:attr:`&redef` +============================================================================ ====================================== + +State Variables +############### +=========================================================================== ======================================= +:bro:id:`Example::a_var`: :bro:type:`bool` put some documentation for "a_var" here + +:bro:id:`Example::var_with_attr`: :bro:type:`count` :bro:attr:`&persistent` + +:bro:id:`Example::var_without_explicit_type`: :bro:type:`string` +=========================================================================== ======================================= + +Types +##### +====================================================== ========================================================== +:bro:type:`Example::SimpleEnum`: :bro:type:`enum` documentation for "SimpleEnum" + goes here. + +:bro:type:`Example::SimpleRecord`: :bro:type:`record` general documentation for a type "SimpleRecord" + goes here. + +:bro:type:`Example::ComplexRecord`: :bro:type:`record` general documentation for a type "ComplexRecord" goes here + +:bro:type:`Example::Info`: :bro:type:`record` An example record to be used with a logging stream. +====================================================== ========================================================== + +Events +###### +================================================= ============================================================= +:bro:id:`Example::an_event`: :bro:type:`event` Summarize "an_event" here. + +:bro:id:`Example::log_example`: :bro:type:`event` This is a declaration of an example event that can be used in + logging streams and is raised once for each log entry. +================================================= ============================================================= + +Functions +######### +=============================================== ======================================= +:bro:id:`Example::a_function`: :bro:type:`func` Summarize purpose of "a_function" here. +=============================================== ======================================= + +Redefinitions +############# +===================================================== ======================================== +:bro:type:`Log::ID`: :bro:type:`enum` + +:bro:type:`Example::SimpleEnum`: :bro:type:`enum` document the "SimpleEnum" redef here + +:bro:type:`Example::SimpleRecord`: :bro:type:`record` document the record extension redef here +===================================================== ======================================== + +Namespaces +~~~~~~~~~~ +.. bro:namespace:: Example + +Notices +~~~~~~~ +:bro:type:`Notice::Type` + + :Type: :bro:type:`enum` + + .. bro:enum:: Example::Notice_One Notice::Type + + any number of this type of comment + will document "Notice_One" + + .. bro:enum:: Example::Notice_Two Notice::Type + + any number of this type of comment + will document "Notice_Two" + + .. bro:enum:: Example::Notice_Three Notice::Type + + .. bro:enum:: Example::Notice_Four Notice::Type + +Public Interface +---------------- +Options +~~~~~~~ +.. bro:id:: Example::an_option + + :Type: :bro:type:`set` [:bro:type:`addr`, :bro:type:`addr`, :bro:type:`string`] + :Attributes: :bro:attr:`&redef` + :Default: ``{}`` + + add documentation for "an_option" here + +.. bro:id:: Example::option_with_init + + :Type: :bro:type:`interval` + :Attributes: :bro:attr:`&redef` + :Default: ``10.0 msecs`` + +State Variables +~~~~~~~~~~~~~~~ +.. bro:id:: Example::a_var + + :Type: :bro:type:`bool` + + put some documentation for "a_var" here + +.. bro:id:: Example::var_with_attr + + :Type: :bro:type:`count` + :Attributes: :bro:attr:`&persistent` + +.. bro:id:: Example::var_without_explicit_type + + :Type: :bro:type:`string` + :Default: ``"this works"`` + +Types +~~~~~ +.. bro:type:: Example::SimpleEnum + + :Type: :bro:type:`enum` + + .. bro:enum:: Example::ONE Example::SimpleEnum + + and more specific info for "ONE" + can span multiple lines + + .. bro:enum:: Example::TWO Example::SimpleEnum + + or more info like this for "TWO" + can span multiple lines + + .. bro:enum:: Example::THREE Example::SimpleEnum + + documentation for "SimpleEnum" + goes here. + +.. bro:type:: Example::SimpleRecord + + :Type: :bro:type:`record` + + field1: :bro:type:`count` + counts something + + field2: :bro:type:`bool` + toggles something + + general documentation for a type "SimpleRecord" + goes here. + +.. bro:type:: Example::ComplexRecord + + :Type: :bro:type:`record` + + field1: :bro:type:`count` + counts something + + field2: :bro:type:`bool` + toggles something + + field3: :bro:type:`Example::SimpleRecord` + + msg: :bro:type:`string` :bro:attr:`&default` = ``"blah"`` :bro:attr:`&optional` + attributes are self-documenting + + general documentation for a type "ComplexRecord" goes here + +.. bro:type:: Example::Info + + :Type: :bro:type:`record` + + ts: :bro:type:`time` :bro:attr:`&log` + + uid: :bro:type:`string` :bro:attr:`&log` + + status: :bro:type:`count` :bro:attr:`&log` :bro:attr:`&optional` + + An example record to be used with a logging stream. + +Events +~~~~~~ +.. bro:id:: Example::an_event + + :Type: :bro:type:`event` (name: :bro:type:`string`) + + Summarize "an_event" here. + Give more details about "an_event" here. + + :param name: describe the argument here + +.. bro:id:: Example::log_example + + :Type: :bro:type:`event` (rec: :bro:type:`Example::Info`) + + This is a declaration of an example event that can be used in + logging streams and is raised once for each log entry. + +Functions +~~~~~~~~~ +.. bro:id:: Example::a_function + + :Type: :bro:type:`function` (tag: :bro:type:`string`, msg: :bro:type:`string`) : :bro:type:`string` + + Summarize purpose of "a_function" here. + Give more details about "a_function" here. + Separating the documentation of the params/return values with + empty comments is optional, but improves readability of script. + + + :param tag: function arguments can be described + like this + + :param msg: another param + + + :returns: describe the return type here + +Redefinitions +~~~~~~~~~~~~~ +:bro:type:`Log::ID` + + :Type: :bro:type:`enum` + + .. bro:enum:: Example::LOG Log::ID + +:bro:type:`Example::SimpleEnum` + + :Type: :bro:type:`enum` + + .. bro:enum:: Example::FOUR Example::SimpleEnum + + and some documentation for "FOUR" + + .. bro:enum:: Example::FIVE Example::SimpleEnum + + also "FIVE" for good measure + + document the "SimpleEnum" redef here + +:bro:type:`Example::SimpleRecord` + + :Type: :bro:type:`record` + + field_ext: :bro:type:`string` :bro:attr:`&optional` + document the extending field here + (or here) + + document the record extension redef here + +Port Analysis +------------- +:ref:`More Information ` + +SSL:: + + [ports={ + 443/tcp, + 562/tcp + }] + +Packet Filter +------------- +:ref:`More Information ` + +Filters added:: + + [ssl] = tcp port 443, + [nntps] = tcp port 562 + diff --git a/doc/upgrade.rst b/doc/upgrade.rst index 6410a769db..2960aa80e3 100644 --- a/doc/upgrade.rst +++ b/doc/upgrade.rst @@ -5,22 +5,12 @@ Upgrading From Bro 1.5 to 2.0 .. class:: opening - This guide details differences between Bro version 1.5 and 2.0 that - may be important for users to know as they work on updating their - Bro deployment/configuration to the later version. + This guide details differences between Bro versions 1.5 and 2.0 + that may be important for users to know as they work on updating + their Bro deployment/configuration to the later version. .. contents:: -New Development Process -======================= - -Bro development has moved from using SVN to Git for revision control. -Users that like to use the latest Bro developments by checking it out -from the source repositories should see the `development process -`_ - -Bro now uses `CMake `_ for its build system so -that is a new required dependency when building from source. New Script Organization/Hierarchy ================================= @@ -28,22 +18,29 @@ New Script Organization/Hierarchy In versions before 2.0, Bro scripts were all maintained in a flat directory called ``policy/`` in the source tree. This directory is now renamed to ``scripts/`` and contains major subdirectories ``base/``, -``policy/``, and ``site/``, each of which may also be subdivided further +``policy/``, and ``site/``, each of which may also be subdivided +further. The contents of the new ``scripts/`` directory, like the old/flat ``policy/`` still gets installed under under the ``share/bro`` subdirectory of the installation prefix path just like previous versions. For example, if Bro was compiled like ``./configure --prefix=/usr/local/bro && make && make install``, then the script -hierarchy can be found in ``/usr/local/bro/share/bro``. And main +hierarchy can be found in ``/usr/local/bro/share/bro``. + +THe main subdirectories of that hierarchy are as follows: - ``base/`` contains all scripts that are loaded by Bro by default - (unless the ``-b`` command line option is used to run Bro in a minimal - configuration). Scripts under this directory generally either provide - extra Bro scripting-layer functionality that has no performance cost, - configure a default/recommended mode of operation, or accumulate/log - useful state/protocol information for monitored traffic. + (unless the ``-b`` command line option is used to run Bro in a + minimal configuration). Note that is a major conceptual change: + rather than not loading anything by default, Bro now uses an + extensive set of default scripts out of the box. + + The scripts under this directory generally either accumulate/log + useful state/protocol information for monitored traffic, configure a + default/recommended mode of operation, or provide extra Bro + scripting-layer functionality that has no significant performance cost. - ``policy/`` contains all scripts that a user will need to explicitly tell Bro to load. These are scripts that implement @@ -51,24 +48,24 @@ subdirectories of that hierarchy are as follows: more significant performance costs. - ``site/`` remains a directory that can be used to store locally - developed scripts, but now contains some extra scripts that may - contain some recommended default configurations. E.g. ``local.bro`` - is loads extra scripts from ``policy/`` and does extra tuning. - These files can also be customized in place without being overwritten - by upgrades/reinstalls, unlike scripts in other directories. + developed scripts, but now contains some extra scripts that contain + some recommended default configurations. E.g. ``local.bro`` loads + extra scripts from ``policy/`` and does extra tuning. These files + can also be customized in place without being overwritten by + upgrades/reinstalls, unlike scripts in other directories. -Now, with version 2.0, the default/builtin ``BROPATH`` automatically -will search for scripts in only ``policy/``, ``site/`` and their parent -directory, but **not** ``base/``. Generally, everything under ``base/`` -is loaded automatically, but for users of the ``-b``, option, scripts -it's important to know that loading a script in that directory requires -the extra ``base/`` path qualification. For example, the following two -scripts: +Now, with version 2.0, the default ``BROPATH`` automatically will +search for scripts in ``policy/``, ``site/`` and their parent +directory, but **not** ``base/``. Generally, everything under +``base/`` is loaded automatically, but for users of the ``-b`` option +(which prevents this), it's important to know that loading a +script in that directory requires the extra ``base/`` path +qualification. For example, the following two scripts: * ``$PREFIX/share/bro/base/protocols/ssl/main.bro`` * ``$PREFIX/share/bro/policy/protocols/ssl/validate-certs.bro`` -Are referenced from another Bro script like: +are referenced from another Bro script like: .. code:: bro @@ -78,6 +75,34 @@ Are referenced from another Bro script like: Notice how ``policy/`` can be omitted as a convenience in the second case. +Logging Framework +----------------- + +- The logs generated by scripts that ship with Bro are entirely redone + to use a standardized format via the new logging framework and + generally the content has changed towards making the logs even more + useful. + + * A particular format change that may be useful to note is that the + ``conn.log`` ``service`` field is derived from DPD instead of + well-known ports (while that was already possible in 1.5, it was + not the default). + +- A common pattern found in the new scripts is to store logging stream + records for protocols inside the ``connection`` records so that + state can be collected until enough is seen to log a coherent unit + of information regarding the activity of that connection. This + state is now frequently seen/accessible in event handlers, for + example, like ``c$`` where ```` is replaced by + the name of the protocol. This field is added to the ``connection`` + record by ``redef``'ing it in a + ``base/protocols//main.bro`` script. + +- The new logging framework also makes it possible to extend and + filter logs. See `the logging framework + <{{git('bro:doc/logging.rst')}}>`_ more information on usage. + + Scripting-Layer API Changes =========================== @@ -94,7 +119,7 @@ Scripting-Layer API Changes - The ``make_addr`` BIF now returns a ``subnet`` versus an ``addr`` -- The ``net`` type has been removed +- The ``net`` type has been removed. New Default Settings @@ -117,33 +142,9 @@ Variable Naming ``site.bro`` exports the ``local_nets`` identifier (among other things) into the ``Site`` module. -- Identifiers may have been renamed to conform to `scripting +- Identifiers may have been renamed to conform to new `scripting conventions - `_ - -Logging Framework ------------------ - -- The logs generated by scripts that ship with Bro are entirely redone - to use a standardized format via the new logging framework and - generally the content has changed towards making the logs even more - useful. - - * a particular format change that may be useful to note is that the - ``conn.log`` ``service`` field is derived from DPD instead of - well-known ports - -- A common pattern found in the new scripts is to store logging - stream records for protocols inside ``connection`` records so that - state can be collected until enough is seen to log a coherent unit - of information regarding the activity of that connection. This state - is now frequently seen/accessible in event handlers, for example, like - ``c$`` where ```` is replaced by the name of the - protocol. This field is added to the ``connection`` record by - ``redef``'ing it in a ``base/protocols//main.bro`` script. - -- The new logging framework also makes it possible to extend and - filter logs. See ``_. + <{{docroot}}/development/script-conventions.html>`_ Communication Framework ----------------------- @@ -161,10 +162,19 @@ Communication Framework Notice Framework ---------------- -The way users interact with "notices" has changed significantly in order -to make it easier to define a site policy and more extensible for adding -customized actions. +The way users interact with "notices" has changed significantly in +order to make it easier to define a site policy and more extensible +for adding customized actions. See the `the notice framework +<{{git('bro:doc/notice.rst')}}>`_. -TODO: we need new notice documentation with examples to link from -here. The `old notice documentation `_ can be used as a -starting point. + +New Development Infrastructure +============================== + +Bro development has moved from using SVN to Git for revision control. +Users that like to use the latest Bro developments by checking it out +from the source repositories should see the `development process +<{{docroot}}/development/process.html>`_ + +Bro now uses `CMake `_ for its build system so +that is a new required dependency when building from source. diff --git a/pkg/make-src-packages b/pkg/make-src-packages index 996b546659..1d8bd94e62 100755 --- a/pkg/make-src-packages +++ b/pkg/make-src-packages @@ -12,12 +12,16 @@ cp -R ${SOURCE} ${TMP}/Bro-${BRO_V} ( cd ${TMP} && find . -name .git\* | xargs rm -rf ) ( cd ${TMP} && find . -name \*.swp | xargs rm -rf ) ( cd ${TMP} && find . -type d -name build | xargs rm -rf ) -( cd ${TMP} && tar -czf ${BUILD}/Bro-all-${BRO_V}.tar.gz Bro-${BRO_V} ) +( cd ${TMP} && tar -czf ${BUILD}/Bro-all-${BRO_V}.tar.gz Bro-${BRO_V} && echo "Package: ${BUILD}/Bro-all-${BRO_V}.tar.gz" ) + +# TODO: Remove? -Robin ( cd ${TMP}/Bro-${BRO_V}/aux && mv broccoli Broccoli-${BROCCOLI_V} && \ tar -czf ${BUILD}/Broccoli-${BROCCOLI_V}.tar.gz Broccoli-${BROCCOLI_V} ) ( cd ${TMP}/Bro-${BRO_V}/aux && mv broctl Broctl-${BROCTL_V} && \ tar -czf ${BUILD}/Broctl-${BROCTL_V}.tar.gz Broctl-${BROCTL_V} ) ( cd ${TMP}/Bro-${BRO_V}/aux && rm -rf Broctl* Broccoli* ) -( cd ${TMP} && tar -czf ${BUILD}/Bro-${BRO_V}.tar.gz Bro-${BRO_V} ) + +( cd ${TMP} && tar -czf ${BUILD}/Bro-${BRO_V}.tar.gz Bro-${BRO_V} && echo "Package: ${BUILD}/Bro-${BRO_V}.tar.gz" ) + rm -rf ${TMP} echo "Distribution source tarballs have been compiled in ${BUILD}"