RPM package creation for BRO IDS Deployments.

RPM package creation for BRO IDS Deployments.

Basically, there are two ways to install BRO. One is, download the source and compile it for your machine. The other option is to install BRO from a package. Compiling from source is a great option, which allows for customization but can become problematic when deploying BRO on several sensors. To address this challenge, compiling BRO on a build machine, and distributing the resulting package to sensor nodes for installation, seems like a good idea.

There is no shortage of articles on how to compile BRO from source but there aren’t many that discuss building custom packages. I hope this information is helpful in that regard. There are some key differences worth noting between the source built package and the pre-built repo packages. Namely, when using the --binary-package build option, permissions on the target folder are not set the same, a specific group is not set, nor is the bro group created on the system during install. Another thing is RPATH is stripped as part of the package build so Dynamic linking loaders need to be properly identified on the target machine by placing a file in etc/ld.so.conf.d/.

Building a custom BRO IDS binary package.

All the steps within this article assume CentOS 7 as the platform of choice. The steps should be similar on other platforms but they are out of scope of this document. The first thing to do is install prerequisite software using yum on the build system. In this case, the build system is a Centos 7.5.1804 (Core) VM running on VMware 6.5 with kernel 3.10.0-862.6.3.el7.x86_64.

Install prerequisite software:

install pf_ring:

The pf_ring package was installed from an rpm using the ntop.org repo.

Install build tools:

yum install cmake make gcc gcc-c++ flex bison libpcap-devel openssl-devel python-devel swig zlib-devel rpm-build

Building the BRO IDS package:

Get the sources from the git repo

cd ~ (use of an unprivileged user account is fine)
git clone --recursive https://github.com/zeek/zeek.git

Edit files prior to the build:

The two files below provide content for the %post and %pre sections of the spec file.

/bro/cmake/package_postupgrade.sh.in
/bro/cmake/package_preinstall.sh.in

Edit package_postupgrade.sh.in and change the section defining world writable directories.
Change from this

# Set up world writeable spool and logs directory for broctl, making sure
# to set the sticky bit so that unprivileged users can't rename/remove files.
# (CMake/CPack is supposed to install them, but has problems with empty dirs)
if [ -n "@EMPTY_WORLD_DIRS@" ]; then
    for dir in "@EMPTY_WORLD_DIRS@"; do
        mkdir -p ${dir}
        chmod 777 ${dir}
        chmod +t ${dir}
    done
fi

to this

# Set up world writeable spool and logs directory for broctl, making sure
# to set the sticky bit so that unprivileged users can't rename/remove files.
# (CMake/CPack is supposed to install them, but has problems with empty dirs)
if [ -n "@EMPTY_WORLD_DIRS@" ]; then
    for dir in "@EMPTY_WORLD_DIRS@"; do
        mkdir -p ${dir}
        chmod 3770 ${dir}
        chgrp bro ${dir}
    done
fi

Make additions to the spec file template:

Note: Managing the creation of the /etc/ld.so.conf.d/bro-x86_64.conf file is well handled using the spec file. However, I was having some trouble figuring out where/what to update to make changes stick(I’m still not sure of the right way to do it but I’ll keep looking). Eventually, I found the CPackRPM.cmake file, which has a template. The way I worked around this as a temporary solution was editing the template in /usr/share/cmake/Modules/CPackRPM.cmake, which is bad form I’m sure but it works.

Add ldconfig to the %post and %postun sections so the library path is loaded. Example below.

%post
ldconfig

\@CPACK_RPM_SPEC_POSTINSTALL\@

%postun
ldconfig

Then make additions to the %pre and %preun sections and changes to the %defattr setting in the spec file template:

%pre
/usr/bin/getent group bro >/dev/null || /usr/sbin/groupadd -r bro

# Check for additional library declaration files in /etc/ld.so.conf.d/
# Create file on install
if [ ! -f /etc/ld.so.conf.d/bro-x86_64.conf ]; then
  echo \"/opt/bro/lib\" > /etc/ld.so.conf.d/bro-x86_64.conf
  echo \"/opt/bro/lib64\" >> /etc/ld.so.conf.d/bro-x86_64.conf
fi

\@CPACK_RPM_SPEC_PREINSTALL\@

%preun
# Check if library declaration files are in /etc/ld.so.conf.d/
# Remove them on uninstall
if [ -f /etc/ld.so.conf.d/bro-x86_64.conf ]; then
  rm /etc/ld.so.conf.d/bro-x86_64.conf
fi

\@CPACK_RPM_SPEC_PREUNINSTALL\@

%files
%defattr(-,root,bro,-)

Configure for deployment:

cd ~/zeek
LDFLAGS="-lpfring -lpcap" ./configure --prefix=/opt/bro --with-pcap=/usr/local/ --pkg-name-prefix=Bro --binary-package --build-type=Release
cd build
make package

Finishing up:

The above process will leave us with an rpm package in ~/bro/build named something like Bro-2.5-725-Linux-x86_64.rpm. At this point we need to distribute the package in some way to other nodes and perform the final configuration. Distribution options are up to the reader but I can offer a few ideas.

REF: https://www.ntop.org/guides/pf_ring/thirdparty/bro.html
REF: https://www.bro.org/sphinx/install/install.html#prerequisites
REF: https://www.bro.org/development/howtos/cmake.html
REF: https://codeyarns.com/2017/11/02/how-shared-library-locations-are-found-at-runtime/
REF: https://codeyarns.com/2014/01/14/how-to-fix-shared-object-file-error/
REF: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html-single/rpm_packaging_guide/index#what-is-a-spec-file

You must be logged in to post a comment.

Proudly powered by WordPress   Premium Style Theme by www.gopiplus.com