2009-04-09

Single Snort IDS (with Web Interface)

Snort IDS (with web interface)


Written by Graham Mead


Click here to read in wide screen!


Abstract

This guide will be a snort set up with an administrative front end. Snort will be implemented in this manner so it can easily installed and maintained. This configuration is only for use on one local system as it bypasses a lot of security features that would be required for external access. This install is intended to be used to develop snort rules but it could also be used for monitoring a home network.



  • Setting up MySQL
  • Apache and PHP
  • Basic Analysis and Security Engine
  • Installing Oinkmaster
  • Bleeding Edge Rules
  • Installing Snort from source (Recomended)
  • Installing Snort (Ubuntu binary version)
  • Configuring Snort
  • Installing Oinkmaster




Software Used

Base system: Ubuntu 8.10

Installed from the Ubuntu package manager:

MySQL, Apache HTTP Server, PHP, Oinkmaster, Snort.



Downloaded from sites as source.

BASE and Snort.



How it works

The Snort service would listen to a network interface for traffic it thinks are attacks. Once an attack has been detected Snort would create an alert which would then be up loaded to a SQL server installed on the local system. The web interface (BASE) would then be able to display and manage the alerts in the database.




Set up MySQL

The first stage is to set up the database server so both Snort and BASE can connect and store/retrieve alerts. First we have to install the MySQL server (which in Ubuntu is MySQL 5). The input is marked as bold text.

$ sudo apt-get install mysql-server mysql-client



This section is a little ugly as I don't really speak SQL very well. We will be setting up two databases, the 'snort' and the 'archive' database. For the snort alerts database the username is 'snort', the password is 'snortconfpasswd' and the database name is also 'snort'. For the archive database the username is 'archive', the password is 'archiveconfpasswd' and the database name is again also 'archive'.



Snort Database

$ mysql -u root -p

mysql> CREATE DATABASE snort;

mysql> grant INSERT,SELECT,UPDATE,CREATE,DELETE on snort.* to snort;

mysql> grant INSERT,SELECT,UPDATE,CREATE,DELETE on snort.* to snort@localhost;

mysql> SET PASSWORD FOR snort=PASSWORD('snortconfpasswd');

mysql> SET PASSWORD FOR snort@localhost=PASSWORD('snortconfpasswd');

mysql> flush privileges;

mysql> exit



Archive Database

$ mysql -u root -p

mysql> CREATE DATABASE archive;

mysql> grant INSERT,SELECT,UPDATE,CREATE,DELETE on archive.* to archive;

mysql> grant INSERT,SELECT,UPDATE,CREATE,DELETE on archive.* to archive@localhost;

mysql> SET PASSWORD FOR archive=PASSWORD('archiveconfpasswd');

mysql> SET PASSWORD FOR archive@localhost=PASSWORD('archiveconfpasswd');

mysql> flush privileges;

mysql> exit



We then install the schema from the Snort download, the schema file is located in the schema folder of the downloaded archive. Then we import the database schema by issuing the following command in the schema directory.

$ cat create_mysql mysql -u snort -D snort -p



Or if Snort (snort-mysql) was downloaded from the Ubuntu repos.

$ zcat /usr/share/doc/snort-mysql/create_mysql.gz mysql -u snort -D snort -p



Check Database was created correctly.

$ mysql -u root -p

mysql> show databases;

mysql> use snort



A fast way of checking that the schema was imported is to check the tables were created in the Snort database, naturally this only works for a new install. You should see something like this if was successful.

mysql> show tables;


+------------------+

Tables_in_snort

+------------------+

data

detail

encoding

event

icmphdr

iphdr

opt

reference

reference_system

schema

sensor

sig_class

sig_reference

signature

tcphdr

udphdr

+------------------+

16 rows in set (0.00 sec)


Then we check that the Snort user has a password set and has the correct permissions by issuing the below command. Its worth noting that the percentage symbol is a wildcard in MySQL, so snort@% would be accepted from anywhere on the network interface.

mysql> show grants for 'snort';

+------------------------------------------------------------------------------------------------------+

Grants for snort@%

+------------------------------------------------------------------------------------------------------+

GRANT USAGE ON *.* TO 'snort'@'%' IDENTIFIED BY PASSWORD '*461162D3DA0A6C03D88954BE694A7D05FC8AB884'

GRANT SELECT, INSERT, UPDATE, DELETE, CREATE ON `snort`.* TO 'snort'@'%'

+------------------------------------------------------------------------------------------------------+

2 rows in set (0.00 sec)

mysql> exit



After any changes to the configuration 'my.cnf' we need to restart the MySQL service.

$ sudo /etc/init.d/mysql restart



Apache and PHP

BASE requires a PHP capable web server, Apache will be used in this example. The following installs the apache2 web server, PHP5 (the apache module), the ADOdb database abstraction library and the PHP PEAR mail modules for BASE to work properly.



$ sudo apt-get install apache2 php5-mysql libphp-adodb php-mail-mime php-mail



First we change into the web server root directory and delete the default "It Works!" page and replace it with a PHP version.

$ cd /var/www/

$ sudo rm index.html

$ sudo nano index.php



Then we enter this PHP test code into the newly created file:

<?php echo "PHP WORKS";?>


Set the Apache bind address to the loopback address (127.0.0.1) so that the web server is only visible on the local computer.


$ sudo nano /etc/apache2/ports.conf

Listen 127.0.0.1:80



We have just changed the normal HTTP port and just to be safe we will also change the SSL port so if we accidentally enable SSL, BASE will not exposed.



<IfModule mod_ssl.c>

Listen 127.0.0.1:443

</IfModule>


To enable the PHP module on Debain/Ubuntu you would run the following:

$ a2enmod php5

Module php5 already enabled


If you get the above message about the PHP module already being enabled all you need to do is to restart Apache. After we change the address that Apache listening on we need to restart Apache.

$ sudo /etc/init.d/apache2 restart



Then use a web browser and browse to the web server at 127.0.0.1, "PHP WORKS" should be displayed if PHP is working.



Basic Analysis and Security Engine

BASE is the PHP script that is used to monitor and manage Snort alerts. We need to download and extract the archive.


This command will copy BASE into the web server root overwriting the old 'index.php' file.

$ sudo cp -R ~/Desktop/base-php4/* /var/www/



We change the web server root so that it is owned (thus writable) by the web server user so the configuration file for BASE can be written to disk. After the setup has finished and the configuration is installed don't forget to change back the permissions.

$ sudo chown www-data /var/www/



Browse to the web server and follow the on screen instructions to start the setup process. The first part of the setup is where BASE checks the settings are fine for BASE to operate with any problems being displayed in red.

The second page of the setup is where BASE asks for the path of the ADodb library that was installed along side Apache.





The next page is where the database connection information is entered.

After the SQL information has been entered we have the option to enable an authentication system build into BASE.

BASE database Schema

Once BASE can connect to the Snort database, there will be an error saying that the BASE tables are not installed.

The database version is valid, but the BASE DB structure (table: acid_ag)is not present. Use the Setup page to configure and optimize the DB.



Click on the setup page and then click the button to create the BASE tables. After this is done there will be another message. In order to support Alert purging (the selective ability to permanently delete alerts from the database) and DNS/whois lookup caching, the DB user "snort" must have the DELETE and UPDATE privilege on the database. We have set up the Snort user with update and delete privileges.


After these stages you should be able to access BASE via a web browser by entering 'http://127.0.0.1/' into the address bar. The build in authentication can be used to provide a layer of security however only user that can access the local system can access BASE.



Installing Oinkmaster

Oinkmaster is a perl script that helps administrators update and manage Snort rules. An Oinkcode can be obtained by registering on the snort website and entering your profile, here there will be an option to generate your Oinkcode.



First we install Oinkmaster.

$ sudo apt-get install oinkmaster



Then we edit the Oinkmaster config file to use an Oinkcode.

$ sudo nano /etc/oinkmaster.conf



We then must comment out any 'url=' lines like the one below and add a line for the Oinkcode.

#url = http://www.snort.org/dl/rules/snortrules-snapshot-*.tar.gz

url = http://www.snort.org/pub-bin/oinkmaster.cgi/<oinkcode>/snortrules-snapshot-2.8.tar.gz



Or add this this line if you want to install the current rule snapshot.

url = http://www.snort.org/pub-bin/oinkmaster.cgi/<oinkcode>/snortrules-snapshot-CURRENT.tar.gz



This is how the URL is formed.

http://www.snort.org/pub-bin/oinkmaster.cgi/<oinkcode>/snortrules-snapshot-<major version>.<minor version>.tar.gz



Then we add this line to the oinkmaster.conf file so Oinkmaster will manage both the official Snort rules and the emerging edge rules.

url = http://www.bleedingthreats.net/rules/emerging.rules.tar.gz



We make the directory for the Snort rules and backups to be stored in.

$ sudo mkdir -p /etc/snort/rules

$ sudo mkdir -p /etc/snort/backup



Then we change the owner of the Snort directory to the 'snort' user.

$ sudo chown -R snort:snort /etc/snort/



Emerging Threats Rules

The emerging threats rules are a set of Snort rules developed by the community.

Create the emerging.conf in the same directory as the Snort config file.



Add the following to the rules section of snort.conf

include emerging.conf



Add the following to the emerging rules conf file to enable the rules. Make sure there are no BLOCK or .xml files listed or enabled.

include $RULE_PATH/emerging-attack_response.rules

include $RULE_PATH/emerging-dos.rules

include $RULE_PATH/emerging-exploit.rules

include $RULE_PATH/emerging-game.rules

include $RULE_PATH/emerging-inappropriate.rules

include $RULE_PATH/emerging-malware.rules

include $RULE_PATH/emerging-p2p.rules

include $RULE_PATH/emerging-policy.rules

include $RULE_PATH/emerging-scan.rules

include $RULE_PATH/emerging-virus.rules

include $RULE_PATH/emerging-voip.rules

include $RULE_PATH/emerging-web.rules

include $RULE_PATH/emerging-web_sql_injection.rules

include $RULE_PATH/emerging.rules

include $RULE_PATH/emerging-drop.rules

include $RULE_PATH/emerging-rbn.rules

include $RULE_PATH/emerging-compromised.rules

include $RULE_PATH/emerging-botcc.rules

include $RULE_PATH/emerging-dshield.rules



Rules would be enabled and disabled via Oinkmaster with the 'enablesid' and 'disablesid' statements.

disablesid 1,3,4

enablesid 2



Finally we run Oinkmaster manually to install the rules.

$ sudo oinkmaster -o /etc/snort/rules/ -b /etc/snort/backup



Emailing the output of Oinkmaster's updates to the rules is possible but its outside the scope of this guide.


Installing Snort from source (Recommend)

First thing we have to do is install the software that we need to build Snort from the source code.

$ sudo apt-get install build-essential libpcap0.8-dev libmysqlclient15-dev bison flex libc6-dev g++ gcc pcregrep libpcre3-dev



Then we obtain the latest stable version (which was snort-2.8.3.2 at time of writing) and extract the archive.

$ wget http://www.snort.org/dl/snort-2.8.3.2.tar.gz

$ tar zxvf snort-2.8.3.2.tar.gz



The install notes for Snort are held in the doc sub directory and lists all the configure options. All these commands are run from the Snort source code directory.



$ ./configure --enable-dynamicplugin --with-mysql



Then we compile the software and install it to the system.

$ make

$ sudo make install



I had a compile time error with ubuntu 8.10 but a quick trip to the linuxforums.org I managed to fix the problem.



Next we add a user account for Snort so that it's not running as the root user. Any password can be used as the account will be locked anyway. We need to set the shell to '/bin/true' which does nothing.

$ sudo adduser snort

$ sudo chsh snort

$ sudo passwd snort -l



Finally we create some of the directories that Snort need to run and assign the correct permissions.


$ sudo mkdir -p /etc/snort/rules /etc/snort/backup /var/log/snort


$ sudo chown -R root:snort /var/log/snort

$ sudo chmod -R 770 /var/log/snort


We need to copy the etc directory from the source tarball to the local install's config directory.


$ sudo cp <snortSRC>/etc/* /etc/snort/


Then we need to write/install a boot script. I'm using the script written by bodhi.zazen from the Ubuntu forums. Then after the boot script is installed to the system we add the following line to the /etc/rc.local file before any 'exit 0' statements so Snort will be started at boot time. We also need to make the script executable before it can be run.


$ sudo cp ubuntu.snort.init.txt /etc/init.d/snort


$ sudo chmod +x /etc/init.d/snort


$ sudo nano /etc/rc.local


exec /etc/init.d/snort boot


Installing Snort (Ubuntu's binary version)

Ubuntu installed from the package manager. This should only be used if the Install from source fails and you can't fix it.

$ sudo apt-get install snort-mysql



After you run this, the installer will ask you to configure the HOME_NET, this should be set to your network mask. Apport will most likely pop up telling you that Snort has crashed, this is unlikely the case as the Snort (with MySQL) version in Ubuntu comes with a block that stops it from starting until an output source has been configured. To see the error message, you would try to start Snort with the init script that comes with the Ubuntu package.

$ sudo /etc/init.d/snort start


Configuring Snort

First we need to copy the config file in case we make a lot of mistakes.

$ sudo cp /etc/snort/snort.conf /etc/snort/snort.conf.org



Then we edit the main Snort configuration file.

$ sudo nano /etc/snort/snort.conf



We set the HOME_NET variable to the network address with network mask.

var HOME_NET [192.168.58.0/24]

var EXTERNAL_NET !$HOME_NET



This line sets the base path for the rules files which are listed at the bottom of the config file.

var RULE_PATH /etc/snort/rules



This is an important option to uncomment if your computer has low memory, as with all most of the standard rules and the emerging threats rules on my test computer it used 558.78 Mbytes of memory on one interface. However with this option enabled it used about 15 Mbytes. On a system with large amounts of memory like a dedicated Sensor higher performance can be gained by keeping it commented out.

config detection: search-method lowmem



The output database line should be configured for now, so we can see that everything is working. Unless barnyard is to be used, then see below.

output database: log, mysql, user=snort password=snortconfpasswd dbname=snort host=127.0.0.1



These following options are only used by Debian systems (Ubuntu packages). Most of these are defaults and they should stay that way. However you should configure the HOME_NET line and make sure that Snort is listening on the correct interface if you have more than one.

$ sudo nano /etc/snort/snort.debian.conf

DEBIAN_SNORT_STARTUP="boot"

DEBIAN_SNORT_HOME_NET="192.168.58.0/24"

DEBIAN_SNORT_OPTIONS=""

DEBIAN_SNORT_INTERFACE="eth1"

DEBIAN_SNORT_SEND_STATS="true"

DEBIAN_SNORT_STATS_RCPT="root"

DEBIAN_SNORT_STATS_THRESHOLD="1"



Once the basic configuration has been done we check to see if Snort has any problems with it by running the following command. If all goes well you should see something similar to the output below.

$ sudo snort -c /etc/snort/snort.conf

....

--== Initialization Complete ==--



,,_ -*> Snort! <*-

o" )~ Version 2.7.0 (Build 35)

'''' By Martin Roesch & The Snort Team: http://www.snort.org/team.html

(C) Copyright 1998-2007 Sourcefire Inc., et al.



Rules Engine: SF_SNORT_DETECTION_ENGINE Version 1.6 <Build 11>

Preprocessor Object: SF_SMTP Version 1.0 <Build 7>

Preprocessor Object: SF_DCERPC Version 1.0 <Build 4>

Preprocessor Object: SF_FTPTELNET Version 1.0 <Build 10>

Preprocessor Object: SF_SSH Version 1.0 <Build 1>

Preprocessor Object: SF_DNS Version 1.0 <Build 2>

...



If Snort does find any errors in the configuration, it will exit to the user prompt with the error just above it. The following example is when the MySQL logging is configured but the MySQL server has not been started or can't be contacted.

ERROR: database: mysql_error: Can't connect to MySQL server on '192.168.58.13' (113)

Fatal Error, Quitting..



Restart Snort every 6 hours

We have to restart Snort every few hours because the database connection can timeout if no traffic has been received for a while. Yes this is a bad thing and is a big problem with a well tuned sensor that has few false positives (normal traffic being detected as an attack). It's also used to automatically get Snort to reload the rules so any new ones will be loaded.


$ sudo crontab -e

20 0,6,12,18 * * * /etc/init.d/snort restart >/dev/null 2>&1



Testing

Once any errors have been fixed, we move on to test that Snort will generate alerts and it is in fact working properly. From one of your other computers you can simulate an attacker scanning your system with the popular tool nmap.


Disclaimer: You are responsible for your own actions. Testing of any security settings should only be done on your own equipment in your own lab, unless you have written permission from the owner of the equipment.



If you are having problems first thing to do is to restart all the service so that all changes have taken affect.

$ sudo /etc/init.d/apache2 restart

$ sudo /etc/init.d/snort restart

$ sudo /etc/init.d/mysql restart



If Snort fails to start this command can be used to check Snort config for errors.

$ sudo snort -c /etc/snort/snort.conf -T



References

http://ubuntuforums.org/showthread.php?t=919472 (bodhi.zazen's IDS sticky)

No comments: