On Fri, May 31, 2013 at 07:41:21PM -0400, Lawrence Teo wrote:
> This patch fixes two issues with the IPFW DAQ module that's used by
> Snort inline:
I would really like to commit these two DAQ fixes so that they can be
included on time for the 5.4 release. These fixes are needed for Snort
to run properly in inline mode.
To recap, this diff fixes two issues:
1. Snort inline does not drop/reject packets
2. Snort inline cannot run as an unprivileged user
Since not many people are familiar with Snort inline on OpenBSD, I have
included my test procedure below for anyone who would like to replicate
my tests.
Comments? OK?
Thanks,
Lawrence
1. Snort inline does not drop/reject packets
============================================
You'll need two systems: a test system to run Snort, and another to ping
the test system.
On your test system, use divert-packet in /etc/pf.conf to divert inbound
ICMP packets to divert port 800:
pass in quick on egress proto icmp divert-packet port 800
Create a test rule to match ICMP traffic in /etc/snort/rules/test.rules:
drop icmp any any -> any any (msg:"ICMP Test Rule"; sid:1000001; rev:1;)
Note that the rule uses "drop" instead of "alert", which means that ICMP
packets are supposed to be totally dropped by Snort.
In /etc/snort/snort.conf, add a line to include that test rule:
include $RULE_PATH/test.rules
Start Snort in inline mode and bind it to divert port 800:
/usr/local/bin/snort -Q -k none --daq ipfw --daq-var port=800 \
-c /etc/snort/snort.conf -t /var/snort -l /var/snort/log
Watch for inbound alerts:
tail -f /var/snort/log/alert
On another machine, ping the IP of the test system where Snort is
running.
You should see alerts triggering for the test rule (one alert for every
ICMP packet received):
[**] [1:1000001:1] ICMP Test Rule [**]
[Priority: 0]
07/10-17:20:37.553908 x.x.x.x -> y.y.y.y
ICMP TTL:237 TOS:0x0 ID:53489 IpLen:20 DgmLen:84
Type:8 Code:0 ID:50960 Seq:3 ECHO
You should see the following difference before and after the fix is
applied:
Without the fix, the alerts are logged but the pings will still succeed.
This behavior is NOT expected because the Snort rule explicitly used
"drop", so Snort is supposed to drop the packet.
With the fix, the alerts are logged but the pings will fail. This is
the expected "drop" behavior.
2. Snort inline cannot run as an unprivileged user
==================================================
To confirm if Snort can run as the unprivileged _snort user in inline
mode, use the -u and -g flags as follows:
/usr/local/bin/snort -Q -k none --daq ipfw --daq-var port=800 \
-c /etc/snort/snort.conf -u _snort -g _snort -t /var/snort \
-l /var/snort/log
Without the fix, the above command will fail with:
ERROR: Can't start DAQ (-1) - ipfw_daq_start: can't create divert
socket (Permission denied)
With the fix, the above command will start Snort and it will run as the
desired _snort user:
_snort 22243 0.0 21.5 352316 112704 pk S+ 5:13PM 0:27.46
/usr/local/bin/snort -Q -k none --daq ipfw --daq-var port=800 -c
/etc/snort/snort.conf -u _snort -g _snort -t /var/snort -l
/var/snort/log
Index: Makefile
===================================================================
RCS file: /cvs/ports/net/daq/Makefile,v
retrieving revision 1.6
diff -u -p -r1.6 Makefile
--- Makefile 21 Mar 2013 08:46:34 -0000 1.6
+++ Makefile 31 May 2013 21:22:49 -0000
@@ -3,7 +3,7 @@
COMMENT = data acquisition library for snort
DISTNAME = daq-2.0.0
-REVISION = 0
+REVISION = 1
SHARED_LIBS += daq 1.0 # 2.0
SHARED_LIBS += sfbpf 0.0 # 0.1
Index: patches/patch-os-daq-modules_daq_ipfw_c
===================================================================
RCS file: patches/patch-os-daq-modules_daq_ipfw_c
diff -N patches/patch-os-daq-modules_daq_ipfw_c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-os-daq-modules_daq_ipfw_c 31 May 2013 21:44:58 -0000
@@ -0,0 +1,33 @@
+$OpenBSD$
+
+This patch fixes two issues in the IPFW DAQ module that is used by
+Snort in inline mode (both fixes have been sent upstream):
+
+1. Fixes a bug where ipfw_daq_inject() ignores the buf and len
+ arguments that are passed to it, causing packet injections to fail
+ http://marc.info/?l=snort-devel&m=136185602610571&w=2
+
+2. Removes DAQ_CAPA_UNPRIV_START from the list of capabilities so that
+ Snort can run as an unprivileged user in inline mode
+ http://marc.info/?l=snort-devel&m=136254358118711&w=2
+
+--- os-daq-modules/daq_ipfw.c.orig Thu Sep 6 11:17:26 2012
++++ os-daq-modules/daq_ipfw.c Fri May 31 17:26:38 2013
+@@ -256,7 +256,7 @@ static int ipfw_daq_inject (
+ int reverse)
+ {
+ IpfwImpl* impl = (IpfwImpl*)handle;
+- int status = ipfw_daq_forward(impl, hdr, impl->buf, hdr->pktlen, 0);
++ int status = ipfw_daq_forward(impl, hdr, buf, len, 0);
+
+ if ( status == DAQ_SUCCESS )
+ impl->stats.packets_injected++;
+@@ -397,7 +397,7 @@ static int ipfw_daq_get_snaplen (void* handle)
+ static uint32_t ipfw_daq_get_capabilities (void* handle)
+ {
+ return DAQ_CAPA_BLOCK | DAQ_CAPA_REPLACE | DAQ_CAPA_INJECT |
DAQ_CAPA_INJECT_RAW
+- | DAQ_CAPA_BREAKLOOP | DAQ_CAPA_UNPRIV_START | DAQ_CAPA_BPF;
++ | DAQ_CAPA_BREAKLOOP | DAQ_CAPA_BPF;
+ }
+
+ static int ipfw_daq_get_datalink_type(void *handle)