Friday, March 25, 2011

Custom Snort 2.9 package for Solaris 10 x86

So...for the past week I've been spending most of my time trying to build a custom Snort 2.9 package for our Solaris customers. Nothing special about the package, other than the fact that it will be self contained to include all dependencies (libpcap, libdnet, pcre, etc..).

Its just an easy way to install and manage Snort without worrying about impacting other applications on the system.

I am using the gcc and gmake that come with Solaris 10 in /usr/sfw so I had to add the following to my path:
setenv PATH ${PATH}:/usr/sfw/bin:/usr/sfw/sbin:/usr/ccs/bin
Since I am plan on building a package I also wanted to have a build directory that will only contain the files I will be packaging.
mount -F lofs /export/home/build /usr/local
I then proceeded to build and install the pre-requisite libraries libdnet, libpcap, and pcre:
# configure --prefix=/usr/local/AVGsnort
# gmake
# gmake install
I didn't have any issues building or installing the libraries. Now was the time to start building the snort binaries. First up was DAQ 5.0...and I had issues right out of the gate:
checking for libpcap version >= “1.0.0″… no
ERROR! Libpcap library version >= 1.0.0 not found.

Get it from http://www.tcpdump.org

At first this seems straightforward, simply point the configure script to the location of libpcap. From the configure help:
--with-libpcap-includes=DIR libpcap include directory
--with-libpcap-libraries=DIR libpcap library directory
That's obvious enough:
# configure --prefix=/usr/local/AVGsnort --with-libpcap-includes=/usr/local/AVGsnort/include -with-libpcap-libraries=/usr/local/AVGsnort/lib
Still failed....at which point I spotted this little nugget:
ld.so.1: conftest: fatal: libpcap.so.1: open failed: No such file or directory
I pulled the conftest.c code out of the config.log, this is the program that configure builds and runs to test the version of libpcap. I figured I could narrow this down a bit more if I could figure out why that section of code was failing.
# gcc -o conftest -g -O2 -std=c99 -D_GNU_SOURCE -I/usr/local/AVGsnort/include/ -L/usr/local/AVGsnort/lib conftest.c -lpcap
#
Interestingly there were no issues building the code...however when I ran it:
# ./conftest
ld.so.1: conftest: fatal: libpcap.so.1: open failed: No such file or directory
Killed
Huh?!?!?! The issue is appears to be that conftest does not know where the libraries are, so when it fails to find pcap. Despite the fact that it is designated with the -L and -I flags when built.

To resolve this I simply had to adjust my library path. This can be done two ways:
# setenv LD_LIBRARY_PATH /lib:/usr/lib:/usr/local/AVGsnort/lib
or
# crle -l /usr/local/AVGsnort/lib
Either way will ensure that conftest succeeds when run. That should get you through the configure. However, during the make I ran into the following error:
sll.h:87: error: syntax error before "u_int16_t"
sll.h:87: warning: no semicolon at end of struct or union
The issue here is the fact that Solaris uses uint16_t instead of u_int16_t. To get around this I just added a typdef to map for the two u_int types:
typedef uint8_t u_int8_t;
typedef uint16_t u_int16_t;

Still working on the build....will update with other findings as they pop-up

UPDATE

decode.c: In function `DecodePflog':
decode.c:1928: warning: long unsigned int format, unsigned int arg (arg 3)
decode.c: In function `DecodeIP':
decode.c:3118: error: `IPPROTO_GRE' undeclared (first use in this function)
decode.c:3118: error: (Each undeclared identifier is reported only once
decode.c:3118: error: for each function it appears in.)

The first issue at line 1928 can be solved by changing the code as follows:# diff decode.c.orig decode.c
1928c1928
< "(%d < %lu)\n", cap_len, PFLOG2_HDRMIN);
---
> "(%d < %u)\n", cap_len, PFLOG2_HDRMIN);
The issue appears to be from the printf error message, which was set to have a decimal integer (%d) which it got from cap_len and a long unsigned (%lu) integer which was from PFLOG2_HDRMIN. However, it appears the PFLOG_HDRMIN is returning just an unsigned integer (%u) and not a long unsigned (%lu).

The next one is a bit trickier...and I can find my "Programming C" book to assist me. (As programming really isn't something I do often).

Well, I've found a workaround. The code is expecting GRE to be defined:
#ifdef GRE
if (p->greh != NULL)
pc.gre_ip++;
#endif

However, it apparently isn't. So I could either try to find some GRE code and add an #else section to the #ifdef above OR I could enable GRE when I complile and see if that adds the code I need without me having to muck about any more than usual.
# gmake distclean
# ./configure --prefix=/usr/local/AVGsnort --enable-gre
# gmake
What do you know it works:
# ./snort
Running in packet dump mode

--== Initializing Snort ==--
Initializing Output Plugins!
pcap DAQ configured to passive.
Acquiring network traffic from "e1000g0".
Decoding Ethernet

--== Initialization Complete ==--

,,_ -*> Snort! <*-
o" )~ Version 2.9.0.4 GRE (Build 111)
'''' By Martin Roesch & The Snort Team: http://www.snort.org/snort/snort-team
Copyright (C) 1998-2011 Sourcefire, Inc., et al.
Using libpcap version 1.1.1
Using PCRE version: 8.12 2011-01-15

Commencing packet processing (pid=863)
03/29-11:38:14.606885 ARP who-has 10.0.2.15 (FF:FF:FF:FF:FF:FF) tell 10.0.2.15

Now I simply follow the steps posted by the fine people that run sunfreeware.com to create a package







No comments: