1 Setup

1.1 Package

First, you need to install the snort package.

# apt-get install snort

This will not only install it, but it will start it running with a Debian configuration. You need to stop it and prevent it from starting on next boot.

# service snort stop
# update-rc.d snort disable

1.2 Monitor interface

You need to configure PF with at least one "monitor" interface which is where snort will listen. This is done by editing /usr/local/pf/conf/pf.conf

For the purposes of testing, or when using inline enforcement, you can make an existing interface be a monitor in addition to its normal function:

[interface eth0]
ip=10.10.0.249
type=management,monitor
mask=255.255.255.0

In a production environment with VLAN enforcement, you would have a dedicated interface on the PF box connected to a mirror (span) port on a switch, like this:

[interface eth1]
type=monitor

And also bring the interface up in /etc/network/interfaces

auto eth1
iface eth1 inet manual

1.3 Enable snort

You can do this in the web admin interface:

or by directly editing pf.conf:

[trapping]
#
# trapping.range
#
# Comma-delimited list of address ranges/CIDR blocks that PacketFence will monitor/detect/trap on.  Gateway, network, and
# broadcast addresses are ignored.
range=10.0.0.0/8
#
# trapping.detection
#
# Enables snort-based worm detection.  If you don't have a span interface available, don't bother enabling it.  If you do,
# you'll most definately want this on.
detection=enabled

1.4 Start service

# bin/pfcmd service snort status
service|shouldBeStarted|pid
snort|1|0

If you see snort|0|0 then see "Known bugs" below.

You can then start the service like this:

# bin/pfcmd service snort start

Check for a process like this:

# ps auxwww | grep snort
pf        1955  0.0  0.6  54096 20696 ?        Ssl  09:08   0:00 /usr/sbin/snort -u pf -m 0137
  -c /usr/local/pf/var/conf/snort.conf -i eth0 -N -D -l /usr/local/pf/var --pid-path /usr/local/pf/var/run

1.5 Check logs

# cd /usr/local/pf
# grep snort logs/packetfence.log

Snort is given one minute to start. If it fails, you may see a message like this:

Mar 26 07:42:31 pfcmd.pl(1719) INFO: generating /usr/local/pf/conf/snort.conf (pf::services::snort::generate_snort_conf)
Mar 26 07:42:31 pfcmd.pl(1719) INFO: Daemon snort took 0.079 seconds to start. (pf::services::manager::launchService)
Mar 26 07:43:31 pfcmd.pl(1719) WARN: snort timed out trying to start (pf::services::manager::postStartCleanup)

This means that there was some fundamental problem starting snort (e.g. you told it to listen on an interface that doesn't exist)

1.6 Oinkmaster

You are likely to see warnings like this:

Mar 26 07:42:31 pfcmd.pl(1719) WARN: Snort rules definition file emerging-attack_response.rules was not found. (pf::services::snort::generate_snort_conf)
Mar 26 07:42:31 pfcmd.pl(1719) WARN: Snort rules definition file emerging-botcc.rules was not found. (pf::services::snort::generate_snort_conf)
Mar 26 07:42:31 pfcmd.pl(1719) WARN: Snort rules definition file emerging-exploit.rules was not found. (pf::services::snort::generate_snort_conf)
...

This means the snort rules need downloading.

# cd /usr/local/pf
# oinkmaster -C addons/snort/oinkmaster.conf -o conf/snort/

You can make a crontab job to do this daily, e.g. at 11pm

0 23 * * * (cd /usr/local/pf; oinkmaster -C addons/snort/oinkmaster.conf -o conf/snort/)

1.7 Testing with a simulated infection

If you go to http://some.web.server/crack.1.exe then this triggers a Snort rule for a trojan-infected machine. It is rule 2010059:

conf/snort/sid-msg.map:2010059 || ET TROJAN Likely Infostealer exe Download
conf/snort/emerging-trojan.rules:alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS
 (msg:"ET TROJAN Likely Infostealer exe Download"; flow:established,to_server;
 content:"GET"; nocase; http_method; content:"/crack."; http_uri; content:".exe";
 http_uri; pcre:"/\/crack\.\d+\.exe$/Ui"; classtype:trojan-activity; sid:2010059; rev:7;)

So you need to enable PacketFence to quarantine a system in response to rule 2010059.

Add the following to conf/violations.conf:

### LOCAL
[2010059]
desc=Test trojan
priority=4
template=trojan
enabled=Y
actions=trap,email,log
trigger=Detect::2010059

and restart packetfence. Then on a client machine, connect to website http://nsrc.org/crack.1.exe. It takes about 10 seconds for the port to be quarantined (watch the port light to see it be disabled and re-enabled). Then refresh the web browser, and you should see the quarantine page.

Other simulated infections can be done using testmyids and IDSWakeup

1.8 Debugging

Your first port of call is the main log file:

# cd /usr/local/pf
# egrep '(snort|pfdetect)' logs/packetfence.log

Here is an example of where an alert is detected, but the address cannot be resolved to a known client device (node).

Mar 26 09:47:14 pfdetect(1550) INFO: alert received: 03/26-09:47:14.400342  [**] [1:2100498:8] GPL ATTACK_RESPONSE id check returned root [**] [Classification: Potentially Bad Traffic] [Priority: 2] {TCP} 82.165.177.154:80 -> 10.10.0.167:52894 (main::)
Mar 26 09:47:14 pfdetect(1550) INFO: could not resolve 82.165.177.154 to mac in ARP table (pf::iplog::ip2macinarp)
Mar 26 09:47:14 pfdetect(1550) WARN: could not resolve 82.165.177.154 to mac (pf::iplog::ip2mac)
Mar 26 09:47:14 pfdetect(1550) WARN: pfdetect: 82.165.177.154 MAC NOT FOUND for violation 2100498 [GPL] (main::)

In this case the offending packet originated from a machine outside of the local network. It would not be a good idea for PacketFence to isolate machines when they are the receivers of suspicious packets, as it would be an easy denial-of-service target. So PacketFence only isolates the machine if it is the source of the packet.

2 Known bugs

2.1 snort not starting

PacketFence 4.1.0 has a bug which prevents snort from starting. This requires two patches to fix.

# cd /usr/local/pf
# curl https://github.com/inverse-inc/packetfence/compare/packetfence-4.1.0...9c0899990e486281472e366576fcba101563b876.diff | patch -p1
# curl https://github.com/inverse-inc/packetfence/commit/1ec76da2ab76aeafcf55afe0d396dfc1ef57684a.diff | patch -p1
# chmod g+ws var/run
# bin/pfcmd service snort restart
# bin/pfcmd service httpd.admin restart