Building a Distributed IDS (Encrypted)

Problem

You have to protect an organization's network infrastructure. How do you protect it with your Snort sensors at remote locations or even within a single building? As you will see in other chapters, Snort data can be displayed in several formats, such as web (ACID) and windows applications (SnortCenter). How do you get the data from multiple sensors into one of these formats for analysis in an encrypted, secure format?

Solution

The simple solution would be to use Snort's ability to log to a database. The function of logging to a database solves a couple of organization problems with IDS data, such as:

Storage of network IDS data

A database can store about two to four million full events in a MySQL database, for example.

Scalability

The database and events can grow from a small tower system to a complete storage array, if your organization can afford it.

Client side

We're using the database output postprocessor of Snort for this functionality. This example uses MySQL because of its popularity and the wealth of documentation on its setup.

Encryption only

If you are going to build Snort to communicate with an SSL native MySQL database, you will need to modify the Snort source code to get SSL native support. There is a one-line edit to the code to make this change. Edit snort-/src/output-plugins/spo_database.c and change the following line:

"if(mysql_real_connect(data->m_sock, data->shared->host, data->user, data->password, data->shared->dbname, x, NULL, 0) = = 0)"

to:

"if(mysql_real_connect(data->m_sock, data->shared->host, data->user, data->password, data->shared->dbname, x, NULL, CLIENT_SSL) = = 0)"

Then just compile Snort with MySQL support and any other options you choose.

Next, you'll need to get a source build of MySQL, then compile the client only with SSL support.

./configure --without-server --with-vio --with-openssl=[dir] --with-openssl-libs=[dir] --with-openssl-includes=[dir]

Once the MySQL client is rebuilt on your sensor, compile Snort as in the previous example, but change with-mysql to with-mysql=/path/to/mysql. Then place the server's keys on your sensor and insert them in the mysqls directory for MySQL to use. The MySQL client looks for a my.cnf file for any system changes it might need to use when the client is used. The actual making of these keys will be placed in the server configuration portion. For the majority of your MySQL configuration options, copy the file my-medium.cnf from the support-files subdirectory of the mysql distribution to either /etc/my.cnf or /usr/local/var/my.cnf. Then append these lines to your my.cnf file:

[mysqld] ssl-ca=/path/to/cacert.pem ssl-cert=/path/to/server-cert.pem ssl-key=/path/to/server-key.pem

That's all that's needed on the sensor side of the connection other than copying the three previously listed files from the server.

Server side

If you are going to display your events, ACID is in the stable of almost every IDS shop. Compile MySQL with SSL support if you are following the encryption portion of the client side.

MySQL source build:

./configure --with-vio --with-openssl=[dir] --with-openssl-libs=[dir] --with-openssl-includes=[dir] make make install

The following is the Apache/SSL/PHP source build (some dependencies may need to be satisfied before the build will succeed):

#APACHE ./configure --prefix=/my/base/dir --enable-so --enable-ssl --with-ssl=/path/to/ssl #PHP (NEEDED FOR ACID TO WORK ./configure --prefix=/path/to/apache/php --with-apxs2=/path/to/apache/bin --with-config-file-path=/path/to/apache/php --enable-sockets --with-sockets --with-mysql=/path/to/mysql --with-zlib --with-gd

We are going to skip the rest of the Apache setup for our database setup. The database now needs to be set up to use SSL for its connections. Let's start and create our database to use for Snort with its user.

If you didn't already create a user for MySQL to use, do so using the following:

groupadd mysql useradd -g mysql mysql

Create the default database from the MySQL source directory:

scripts/mysql_install_db

Change ownership of the database directory to the mysql user:

chown -R mysql /usr/local/var chgrp -R mysql /usr/local/var

Copy the my-medium.cnf file out of the MySQL source directory to /usr/local:

cp support-files/my-medium.cnf /usr/local/var/my.cnf

Start the MySQL server in the background:

/usr/local/bin/mysqld_safe --user=mysql &

Log in to mysql:

/usr/local/bin/mysql

A good security practice is to require a password for the root MySQL user:

mysql> UPDATE user SET Password=PASSWORD('my_pass') WHERE users='root';

Apply the changes:

mysql> FLUSH PRIVILEGES;

Check that SSL was compiled into MySQL:

mysql> show variables LIKE 'have_openssl';

If this shows anything other than YES, go back and recompile SSL, unless you aren't using encryption. Next create the ACID database:

mysql> CREATE DATABASE ;

Create a user account for our sensors to use (unique for our sensors for the paranoid):

mysql> GRANT UPDATE,SELECT,INSERT on .* TO sensoracid@ IDENTIFIED BY 'sensorpassword'; # For the SSL encrypted folks mysql> GRANT UPDATE,SELECT,INSERT on .* TO sensoracid@ IDENTIFIED BY 'sensorpassword' REQUIRE SSL;

Create a separate account for your web interface to use. This one has all privileges to help prune the database:

mysql> GRANT ALL PRIVILEGES on .* TO webfront@localhost IDENTIFIED BY 'webfrontpass';

If you are using SSL encryption, you must build the OpenSSL certificates needed. The rest of the steps apply only if you are using SSL. Copy the files from the OpenSSL install directory to use:

cp /usr/local/ssl/openssl.conf ~/userX/SSL_MYSQL cp -R /openssl-source/apps/demoCA ~/userX/SSL_MYSQL cd ~/userX/SSL_MYSQL

Build your own Certificate Authority:

/usr/local/ssl/bin/openssl req -new -x509 -keyout cakey.pem -out cacert.pem -config openssl.cnf

Build your server key and request:

/usr/local/ssl/bin/openssl req -new -keyout mysql-server-key.pem -out mysql-server-req.pem -days 365 -config openssl.cnf

This is an optional step to remove security:

/usr/local/ssl/bin/openssl rsa -in mysql-server-key.pem -out mysql-server-key.pem

Make a newcerts directory under demoCA:

mkdir demoCA/newcerts

Sign the server certificate with our new CA:

/usr/local/ssl/bin/openssl ca -policy policy_anything -out mysql-server-cert.pem -config openssl.cnf -infiles mysql-server-req.pem

Done! Now just copy the files to a directory for MySQL to use:

cp cacert.pem /usr/local/etc/SSL_MYSQL/ cp mysql-server-*.pem /usr/local/etc/SSL_MYSQL/

Tell MySQL to use them by appending these three lines to your my.cnf file:

[mysql] ssl-ca=/usr/local/etc/SSL_MYSQL/cacert.pem ssl-cert=/usr/local/etc/SSL_MYSQL/mysql-server-cert.pem ssl-key=/usr/local/etc/SSL_MYSQL/mysql-server-key.pem

Finally, restart the MySQL server with the new changes.

For more database tweaking, check out MySQL Reference Manual (O'Reilly) for more detailed MySQL information.

In addition, feel free to edit your MySQL databases and tweak your IDS databases, as MySQL has an entirely GPL licensing system. For clarification, check the following: http://www.mysql.com/company/legal/licensing/opensource-license.html.

Discussion

This example uses MySQL for the database and to modifies the Snort source code to enable native MySQL connections. However, there are other database formats supported by Snort such as PostgreSQL, Oracle, and even Microsoft SQL.

All the database systems have their differences, and some may be easier or harder for people to use and install. However, before building your database backend, consider its size and support. Consider the size, because you need to gauge how large your database is likely to get. Two to four million records is the max for MySQL, while several hundred million is the Oracle limit. Consider support, because you want to choose a database for your core IDS backend that's familiar to you and to other maintainers. Hardware and prices are another important consideration before you go call Oracle and Dell for your backends.

One word about the database output plug-in: as your sensors grow, you'll have geo-location considerations. Take a look at the output line from the snort.conf file. There is a keyword that's not normally used: sensor_name. If you don't use this keyword in your conf file, when the sensor changes hostname or can't find its DNS name, the sensor and its data appear in the database as a new sensor. This can cause quite a bit of confusion on a large network like an ISP.

Another option for encrypting your sensor to database connections is the hack job of using Stunnel. Stunnel (www.stunnel.org) is tool that allows for SSL-encrypted connections. Stunnel was used to encrypt the connections between the MySQL database server and the sensors before MySQL supported native SSL connections. If you still want to use this method, it's been fairly well documented in HOWTOs across the Internet. But for the quick and dirty setup, it would look like this.

On your database server, add the following line to your /etc/services file:

echo "mysqls 3307/tcp" >> /etc/services

Add the following line to your /etc/hosts.allow file:

mysqls:

Block all other connections for the mysqls service by editing your /etc/hosts.deny file:

mysqls:ALL

Create an SSL certificate and PEM file for Stunnel to use:

/path/to/ssl/bin/openssl req -new -out .pem -keyout .pem -nodes -x509 -days

On BSD systems, you must put your settings in a snort_stunnel.conf file:

Cert = .pem key = .pem [mysqls] accept = 3307 connect = 3306 # If you want logging of the connections #debug = 5 or 7 # depending on how much information you want logged #output =

Start the Stunnel listener with your new config file:

stunnel snort_stunnel.conf

To configure the sensors, copy the serverID.pem file to each of your sensors. Append the same mysqls 3307/tcp to your sensor's /etc/services file.

Create a "snort_sensor_stunnel.conf" file and edit it as follows:

Client = yes # enables this machine to talk to the server listener Cert = .pem key = .pem #debug = 5 #output = [mysqls] accept = 127.0.0.1:3306 connect = :3307

Start the Stunnel connection with:

stunnel sensor_stunnel.conf

Finally, configure Snort to use Stunnel:

output database: log, mysql, user= pasword= sensor_name= dbname= host=127.0.0.1

A third option exists to use SSH's support for port forwarding of connections through the SSH-encrypted tunnel. However, this option creates a considerable load on most networks and is subject to timeout issues on the connection. However, if you want to use it as your connection from database to sensor, a hub-and-spoke scenario might be most appropriate from a management perspective.

On the database server, start an SSH connection on each sensor with a remote port being forwarded. The following example uses port 3306/tcp for a MySQL solution:

ssh -R 3306:127.0.0.1:3306 -l

Then on the Snort sensor, configure the snort.conf file much like the configuration for the Stunnel connection:

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

The keyword sensor_name is important to add, because unless you are just monitoring one sensor, it can quickly become unclear where your IDS data is coming from.

See Also

Other database Snort implementations

Online (http://www.snort.org) resources for database options and changes

Logging, Alerts, and Output Plug ins

Категории