Turn your Raspberry Pi into a Snort IDS

I’m a huge fan of the Raspberry Pi.  If you aren’t already familiar, a Raspberry Pi is a small microcomputer with numerous input/output pins for various electronics projects.  You might be wondering how this is different than something like an Arduino, or a Teensy micro-controller.  The Raspberry Pi definitely has some similarities to these products, but can be thought of more like a fully functional computer, running a complete desktop operating system with extended functionality for electronics projects.  There are several operating systems that can run on the Raspberry Pi Broadcom ARM processor.  The most popular, and officially recommended is the Raspbian OS, a Linux distribution based on Debian Jessie.

My career interest in cyber security naturally lead me to investigate intrusion detection/intrusion prevention systems.  An IDS/IPS (short for intrusion detection system/intrusion prevention system), is a software program that captures and analyzes network packets.  It should be noted that IDS/IPS are not exclusive to each other.  Commercial products can either be an IDS, an IPS, or both.  An IDS passively detects network anomalies to be analyzed in real time, or logged and analyzed at a later time.  An IPS takes an active approach that involves blocking or forwarding traffic, a behavior not unlike a firewall.  For the purpose of this post, I will mainly be referring to IDS functionality.

One of the most popular and publicly accessible IDS/IPS products is the free and open source program Snort.  Snort runs natively on many processor architectures and operating systems.  My goal was to set up a Snort lab in which I could configure rules and set-up various services that have open ports.  Snort is highly configurable and uses user programmed rules to detect and/or filter packets.  A Snort rule is a customized parameter that tells Snort to look for specific traffic and perform an action when it is detected.  For example, I could make a rule to tell Snort to display a message and create a log event anytime an external IP address makes an HTTP request.  This lab should have different services running on various open ports in which I could send traffic.  I would be able to customize Snort to look for specific traffic, as well as reduce false positives through customized rulesets.  The scope of this lab is intrusion detection, although I plan to write about active intrusion prevention at a later time.

Let’s recap.  My goal is to create a lab, running Snort, running various services with open ports, create custom rules, and analyze log events for malicious/non-malicious traffic.  There are many ways I could build out this lab.  I could run it natively on my computer(not ideal, too much extraneous network traffic).  I could run it in a virtual machine running CentOS, Fedora, FreeBSD, or Windows; all of which are acknowledged to work by the Snort team.  I could also use an external machine dedicated to this purpose.  The first two options are less ideal, I want to avoid using my main machine.  The third option is not feasible as I currently only have one computer at my disposal.  What I need is a piece of hardware that runs Linux and has network capability… something like a Raspberry Pi!  The bad news.  The Raspberry Pi, and Raspbian (and by extension Debian) are not officially supported by Snort.  The good news.  Snort provides their source code.  I should be able to compile the Snort source and be able to run it on my Pi.

How to install Snort on a raspberry pi:

The goal of this tutorial is:

  1. Compile from source and install Snort on a Raspberry Pi
  2. Install a basic Apache server.  This will expose port 80 and act as a web server for my home network.
  3. Deploy and configure snort to detect and log any connections to the running Apache server

What you will need:

  1. A basic understanding of the Linux command line, mainly pwd, cd, mkdir, ssh, sudo, cp, nano. Look up how to use these.  I will explain the more complicated commands when we get to that point.
  2. A Raspberry Pi.  I am running this on a Raspberry Pi 2 Model B.  This should work on a Raspberry Pi 3.  I am not sure about the Model 1 or the Zero.
  3. An ethernet connection.  The Raspberry Pi should be directly connected to a port on either a network switch or your home router.
  4. I am running my Pi headless.  If you are doing the same, you will need a terminal emulator for SSH connections.  I am using the standard MacOS terminal.
  5. A FRESH install of Raspbian Lite.  I chose Raspbian Lite to save space and reduce computing overhead.  The Lite version doesn’t include a GUI, which you really don’t need as Snort is a command line tool.  The Lite version is also completely barebone and doesn’t waste space on tools that won’t be used.  I got this working on an 8gb SD card.  You might want more if you foresee large volumes of log data.  For lab and learning purposes, 8gb should be fine.  It would also be a good idea to factory overclock your Pi to squeeze out some extra performance.  Check this link if you aren’t sure how to install Raspbian Lite: https://www.raspberrypi.org/documentation/installation/installing-images/README.md

Follow some of the recommended best practices for expanding the memory space on your SD card once Raspbian is installed.  Also make sure to update your Raspberry Pi using the following command 

sudo apt-get update && sudo apt-get dist-upgrade -y

I would also highly recommend going into your router settings and assigning a static ip setting for your Pi.  This ensures that when your Raspberry Pi automatically obtains it’s IP address through DHCP, it will always be consistent.  Check your router documentation to learn how to do this.  If running your pi headless you can use the command arp -a to learn ip address and mac address mappings on your network.  Some trial and error of SSHing with the command ssh pi@{<ip_address_of_pi>} will allow you to connect.  When you find the ip that works make your static router entry for this ip address.  This will simplify things in the long run.  You can also learn the mac address of the ethernet interface of your Pi by typing in the following command if you have access to a monitor and keyboard:

 ifconfig eth0

We should be ready to go!

With your terminal, initiate an SSH connection to your Pi with the command

ssh pi@{<ip_address_of_pi>} 

If it mentions a certificate, and whether you trust the device, type yes and hit enter.  It will prompt you for a password.  The default password is “raspberry”, hit enter.  If you are able to login, you will see this.

It might be a good idea to check your internet connection at this time.  A simple ping to www.google.com will work.  Now would also be the time to make sure your raspberry pi is up to date.  Use the update and upgrade commands mentioned earlier.

Because we are building Snort from source, we will need to bring in the necessary source code that can be found on the snort.org website.  Before we do this however, we should make a directory to hold our source code just to make things easier to manage and locate.  I will be making the directory in the home location of the current logged in user, ‘pi’ or the ~ which is an alias for current users home directory. 

Run the following two commands to make this directory, and make it the current working directory

mkdir -p ~/sourcecode/snort_src/
cd ~/sourcecode/snort_src/

We now have a place to download the Snort source code.  The source code can be located at snort.org under the “Get Snort” section header.  It will look like this

You will see two links to a compressed tar in the source code box.  The first one is the Data Acquisition Library (DAQ), which is a piece of code that Snort is dependent on to run.  The second link is the Snort source code itself.

Installing the DAQ dependency

Right now, we are only focused on the dependency.  Take note of these links.

Back in your terminal, type the following command to download the file to the current working directory.  Take note that file names can change and won’t always reflect the commands I am giving you.  Always check the official Snort website to ensure you have the right version.  Also verify the file names when using wget and tar to ensure you are downloading and extracting the correct files

wget https://snort.org/downloads/snort/daq-2.0.6.tar.gz

Since this is a compressed tar file, we will need to extract it using the following command

tar xvfz daq-2.0.6.tar.gz

We will now move into the directory we just extracted to begin running scripts to install the software.

cd daq-2.0.6/

If we try to compile this source code at this moment, it will fail because there are missing dependencies.  You can try running ./configure and piecing together the required  dependencies, or use the following commands to easily install them.  Luckily, Raspian’s package manager contains all of the required packages making this an easy task. 

To download and install the dependencies required to compile code, run the following commands

sudo apt-get install bison -y
sudo apt-get install flex -y

There are also three software packages that you may already have.  However, you likely don’t have the required header files, so you will have to also download and install these.  The package manager will make this a trivially easy task.  Run the following commands

sudo apt-get install libpcap-dev -y
sudo apt-get install libpcre3-dev -y
sudo apt-get install libdumbnet-dev -y

Nice, all of our dependencies should now be in order to compile the DAQ.  Usually, you will run the standard ./configure; make; sudo make install; to compile and install source code.   This will definitely work, but I think it is better practice to make everything into an easily manageable package.  The package ‘checkinstall’ will do this automatically.  We will first need to get it from our package manager.

Run the following command

sudo apt-get install checkinstall

We can now get to compiling and installing our code.  Run the following commands

./configure
make
sudo checkinstall -D --install=no --fstrans=no

Checkinstall will ask you some questions about the package to create.  Use the defaults.  Give the description something like “snort-daq” and hit enter again.  Keep all default settings.

You will notice that if you list the directory contents, there will be a a file with .deb extension.  This is the package that checkinstall generated.  The name of this file can vary, so don’t copy the following command verbatim.  Install it using the following command.  If you are unsure, list the contents of the directory.

sudo dpkg -i daq_2.0.6-1_armhf.deb

The DAQ is now installed and we can get back to installing Snort.

Installing Snort

Let’s move back to the directory where we have been downloading our source code

cd ~/sourcecode/snort_src/

We now need to obtain the tar file of source code for Snort and decompress the file.  If you recall from earlier, go to snort.org to find this download.  Run the following commands to download and extract the tar file

wget https://snort.org/downloads/snort/snort-2.9.8.3.tar.gz
tar xvfz snort-2.9.8.3.tar.gz

Installing Snort follows a similar process to compiling and installing the DAQ.  Lets move into the extracted directory. 

cd ~/sourcecode/snort_src/snort-2.9.8.3

Once inside the source directory, we can now begin the compile and install process.  Run the following commands

./configure --enable-sourcefire
make
sudo checkinstall -D --install=no --fstrans=no

Checkinstall will ask you some questions about the package to create.  Make the description something like “snort” and hit enter again.  Follow the prompts and use the defaults.  As we are not distributing the package, you will not have to worry about dependency identification.  Checkinstall will be useful should you choose to remove Snort and the DAQ at a later time

You will notice that if you list the directory contents, there will be a a file with .deb extension.  This is the package that checkinstall generated.  The name of this file can vary, so don’t follow the previous command verbatim.  Install it using the following command

sudo dpkg -i snort_2.9.8.3-1_armhf.deb 

It is also necessary to update the shared library cache.  Run the following command:

sudo ldconfig

Run the following command to verify that Snort has been installed in the proper usr/local/bin/ location

which snort

Snort will run from the usr/local/bin location.  We also want to add a symlink in /usr/sbin that points to /usr/local/bin/snort.  The purpose of this is when we later add the snort user and group, the system process will be able to locate the Snort binary.

sudo ln -s /usr/local/bin/snort /usr/sbin/snort

We can finally check to see if Snort works by verifying the version

snort --version

If you see something like this, you have done the previous steps correctly.

Snort is now mostly installed.  There are two problems now.  The first is that we don’t want Snort running as root user.  The second is that if you try to run Snort now, it will fail due to missing configuration and log file locations.

We are now going to make a Snort user and group.  This will be a system user that the process will run as.  The following two commands will generate the user and group that Snort will run as.

sudo groupadd snort
sudo useradd snort -r -s /sbin/nologin -c SNORT_IDS -g snort

We will now create the directories that will hold the configuration files

sudo mkdir -p /etc/snort/rules/iplists
sudo mkdir /etc/snort/preproc_rules
sudo mkdir /usr/local/lib/snort_dynamicrules
sudo mkdir /etc/snort/so_rules

With these directories created, we will now generate some empty rule files for Snort

sudo touch /etc/snort/rules/local.rules
sudo touch /etc/snort/rules/iplists/white_list.rules
sudo touch /etc/snort/rules/iplists/black_list.rules

Snort will also need a folder to output log files

sudo mkdir /var/log/snort

The Snort user and group will not be able to write log files or read configuration without modifying the privileges of the directories we just created.

sudo chmod -R 5775 /etc/snort
sudo chmod -R 5775 /var/log/snort
sudo chmod -R 5775 /usr/local/lib/snort_dynamicrules
sudo chown -R snort:snort /etc/snort
sudo chown -R snort:snort /var/log/snort
sudo chown -R snort:snort /usr/local/lib/snort_dynamicrules

We are getting close to having a working IDS on our Raspberry Pi.  All that is left is some configuration.  Luckily, we don’t have to build the configuration from scratch.  The tar file that contained the source code also contains various config files for running Snort.  All we have to do is move these to the /etc/snort/ directory.  Change the working directory to the /etc/ directory in the extracted Snort tar

cd ~/sourcecode/snort_src/snort-2.9.8.3/etc

We only want to copy configuration related to Snort.  This excludes any of the makefile(s)

sudo cp *.conf /etc/snort
sudo cp *.config /etc/snort
sudo cp *.map /etc/snort

We will not be utilizing preprocessor rules in this tutorial.  It would still be a good idea to bring them in however, should you choose to implement them at a later time.  I will explore this topic in future tutorials.

cd ~/sourcecode/snort_src/snort-2.9.8.3/src/dynamic-preprocessors/build/usr/local/lib/snort_dynamicpreprocessor

sudo cp * /usr/local/lib/snort_dynamicpreprocessor

Configuring and Running Snort

Snort’s main configuration file is /etc/snort/snort.conf
We will be changing lines within this .conf file to modify Snort’s configuration.  You can use any text editor you are comfortable with: emacs, vi, nano, etc… I will be using the nano text editor to change this file, so it would be a good idea to read up on nano if you are unfamiliar with the program.

If you ‘cat’ the snort.conf file, and scroll all the way down, you will see numerous lines with a “include $RULE_PATH” prefix.  We will not be using these rules at the moment so you should just comment them out.  The following command makes use of the stream editor, or sed, tool to automatically do this

sudo sed -i “s/include \$RULE\_PATH/#include \$RULE\_PATH/“ /etc/snort/snort.conf

Now that these lines, are commented out, we can begin modifying some config

sudo nano /etc/snort/snort.conf

Look for a line that reads ipvar HOME_NET any and modify it as follows

ipvar HOME_NET 192.168.0.0/24

The above should be your own ip subnet followed by a /CIDR suffix.  In most cases, this will be the first 3 octets of your ip address, followed by a 0 for the last octet and /24 to represent a 255.255.255.0 subnet

Scroll down to the line that looks like this

Modify these the first three lines to read

var RULE_PATH /etc/snort/rules
var SO_RULE_PATH /etc/snort/so_rules
var PREPROC_RULE_PATH /etc/snort/preproc_rules

Then we will modify the last two rules to read

var WHITE_LIST_PATH /etc/snort/rules/iplists
var BLACK_LIST_PATH /etc/snort/rules/iplists

Then scroll all the way down to the site specific rules section and uncomment (delete the #) the first line so it reads

include $RULE_PATH/local.rules

Now that this is done, press ctrl+o to save the config file and ctrl+x to exit the config file

We will now run Snort with the configuration validation flag to test all of our settings.  Hopefully it will state that everything validated successfully

sudo snort -T -c /etc/snort/snort.conf -i eth0

Install the Apache server

Now we are going to install the Apache web server so we have something to test a rule on.  This is extremely simple to do.

sudo apt-get install apache2 -y

Once apache is installed, you can test that it is working by going to a web browser on another computer and typing the ip address of your Raspberry Pi.  If you get an Apache splash screen, this works correctly.

Lets set up our rule now

sudo nano /etc/snort/rules/local.rules

You will notice this configuration is blank, lets add our first rule

alert tcp any any -> $HOME_NET 80 (msg:"HTTP request detected"; SID:1000000001; rev:1;)

This means: generate an alert when tcp traffic with the incoming ip address of “any” and with the incoming port of “any” gets sent to our home network subnet on port 80 (80 is the default HTTP port).  The message will state “HTTP request detected”, the SID means Snort process ID, which is a large arbitrary number.  rev is the current rule revision number.

Now that that is done, press ctrl+o to save the config file and ctrl+x to exit the config file

Lets check our configuration again

sudo snort -T -c /etc/snort/snort.conf -i eth0

Lets run snort with the following command

sudo snort -A console -u snort -g snort -c /etc/snort/snort.conf -l /var/log/snort -i eth0

The following flags imply: -A means output to console -u means run as the snort user -g means run as snort group -c means run the following config file -l means log to the following directory, -i means detect traffic on the following ethernet interface

Snort is now running

Try going back to your web browser and attempt to visit the ip address of your Raspberry Pi.  Look again at the console to verify that Snort is detecting and logging the HTTP traffic events to the console.  You can also look in /var/log/snort to see the log files that Snort generated.

Congratulations,

You have compiled and installed Snort from source on your Raspberry Pi, configured it with a rule, installed an Apache web server, and detected incoming HTTP traffic.  This was just a small taste of what Snort can do.  I will be exploring more advanced rules and functionality in later blog posts.  Keep in mind that the Raspberry Pi is limited in processing power and may will not be able to handle large volumes of traffic accurately.  As such, this should obviously not be used in production environments.  I hope you found this tutorial helpful and discovered a new use for your Raspberry Pi.  I will be writing about Barnyard for making more efficient log outputs and PulledPork for automating rule installs in later blog posts. Thanks for reading my first post!

-Holden Kilbride

Sources:
I adapted some ideas from this tutorial on setting up snort in Ubuntu

2 thoughts on “Turn your Raspberry Pi into a Snort IDS”

  1. Hi.
    I had a go and failed. This is the error:
    ERROR: /etc/snort//etc/snort/rules/app-detect.rules(0) Unable to open rules file “/etc/snort//etc/snort/rules/app-detect.rules”: No such file or directory.

    Seems to me that rules are missing.

    Yes, your documnet is 18 months old but still, it’s intrresting. There is not many guides in this matter and many docs are not easy to cope with for a non english speaking fellow.
    Best regards Bengt

  2. I just want to say thank you for these instructions. I was able to follow them. There were some missing packages during my compiling. Specifically libnghttp2 & zlib1g. Googling helped me figure it out.

    I am running Raspberry Pi 3 B. I chose to compile Snort on Ubuntu MATE. I got to the very end, and when I ran sudo snort -T -c /etc/snort/snort.conf -i eth0 command I received a failure. Turns out my Ethernet interface is named something else. So I replaced eth0 with that name.

    I was wondering how I would run this as a back ground service? That would be my only suggestion to add to this tutorial.

Leave a Reply

Your email address will not be published. Required fields are marked *