June 16, 2003

Real-time alerting with Snort, part 3 of 3

- by Jack Koziol -
Last time we looked at deploying a hybrid server/sensor using Snort. Larger organizations may prefer to deploy Snort in a distributed three-tier setup. Here's how.

This article is excerpted from the new book Intrusion Detection with Snort by Jack Koziol.

In a three-tier Snort setup it would be a waste of time and resources to install a mailing application (such as sendmail) and swatch on each sensor. But making a change to swatch and sendmail configurations across multiple sensors is bound to create confusion and possibly mistakes. To solve this problem, you can make use of syslog-ng and Stunnel to forward alerts securely from the sensors to the Snort server. You could optionally install another server to handle the alert collection and mailing functionality, in which case you would forward alerts to this new server.

Syslog-ng is a replacement for the syslog logging facility used by many different applications on Unix systems. Error messages and security alerts from applications or the operating system are posted to syslog. The original syslog has only 20 possible event types, which are known as facilities. Each facility has a priority assigned to it. The facilities are generic and are used by many different applications, meaning you will have many different applications reporting events to syslog with the same facility. With many applications reported as the same facility, it becomes difficult to search for events generated by a specific application.

Filtering is difficult when you have a large amount of data stored in a syslog file. Syslog-ng solves this problem by making the filtering process more granular. With syslog-ng, you can filter events based on the content of the event as well as the facility and priority. You can make use of regular expressions to filter events, which is not possible with the original syslog.

Syslog-ng supports some additional features that make it ideal for the Snort environment. The source of alerts from the original syslog can be obscured if the alerts are forwarded over more than one host or forwarded with Stunnel. If you collect alerts from many different machines on one host, syslog reports the correct logging host. But if you forward these syslog alerts again to a master host, the alerts appear to come from the second host. In a large Snort environment, where multiple logging servers are used, this can make determining the source of the alert difficult. Syslog-ng solves this problem by storing the complete hostname, along with time the alert was generated on the local host.

The original syslog sends alerts via UDP. This is problematic, because Stunnel does not currently support the encryption of UDP traffic. You could install a UDP tunneling package specifically for syslog sessions, such as Zebedee, to fix this problem. But it is easier to upgrade to syslog-ng, which uses TCP, and make use of the Stunnel package you have already installed.

Syslog-ng also has native support for emailing alerts. You can add lines in the configuration file to automatically mail alerts that match a particular string. This eliminates the need to install swatch.

The first step to deploying syslog-ng is to install and configure the package on the sensors. Syslog-ng is dependent on the libol package. You must install it before attempting to install syslog-ng. Run the familiar configure, make, and make install commands to install the libol package. After you have this completed, download syslog-ng and run through the configure, make, and make install commands to install the package.

Configuring syslog-ng for the sensor

Syslog-ng is controlled via a configuration file, syslog-ng.conf. You will be writing this file from scratch. The examples in this book use the ports typically used by rservices (512, 513, 514) for syslog-ng. You should not be using any of the rservices on the Snort tiers because they are insecure. You are free to use ports other than those specified in the examples.

To begin to configure syslog-ng for the sensor you must create a configuration file located at /etc/syslog-ng/syslog-ng.conf. (Be sure to create a new file; don't use one of the default or sample syslog-ng.conf files included with the package.) The syslog-ng.conf file lets syslog-ng know where to look for syslog information and what to do with it after it is discovered. To use it you enter sources and destinations and then associate the two. Sources are potential locations from which syslog-ng can receive alerts, and destinations are areas to which they should be output.

Associating a source with a destination tells syslog-ng exactly where to look for alerts and where to send them. After you define a source you can associate it with as many destinations as your heart desires. The same holds true for sources.

The first line you need to build is a source line. It is used to identify the source of the syslog-ng alerts to the syslog-ng application. You need to name the source with an identifier as well. A good guideline for naming is to use the name of the sensor, then an underscore, and finally the integer the sensor uses in ACID (Analysis Console for Intrusion Databases). For example:

source identifier {source-driver(parameter);};

The source-driver is where you want syslog-ng to look for alerts. The source-driver can be the local machine, a TCP port, or even a file. You can specify as many source-drivers as you wish. For the sensor installation of syslog-ng, you should accept alerts from the local system. Use the following configuration line to accept alerts from the local system:

source sensor_7 {unix-stream("/dev/log ");internal();};

The name of the sensor is sensor, which corresponds with the integer of 7 in ACID, so the identifier is sensor_7. The unix-stream("/dev/log ")source-driver tells syslog-ng that this is a Linux system and to listen for alerts in SOCK_STREAM mode. If you are using a BSD variant you would change this to unix-dgram("/dev/log "). The internal command tells syslog-ng to also listen for messages generated internally in syslog-ng.

The next line to create is the destination to which the alerts are to be sent. On the sensor, all alerts should be forwarded directly to the Snort server via a destination line with the format:

destination identifier {destination-driver(parameter);};

The identifier is the name of the Snort server. The destination is the IP address and port that corresponds to the syslog-ng service that will be installed on the server. You should insert a line similar to the following:

destination snort_server { tcp("Snort_Server_IP " port (514)); };

This line sends alerts to a syslog-ng daemon listening on port 514/TCP located at Snort_Server_IP.

The final configuration line you need to add lets syslog-ng know which sources you want to correspond to which destinations. In this case there is only one source and one destination, so only a single configuration line is needed. The log configuration line has the format:

log {source(source_name); filter(filter_name); destination(destination_name) };

Because we are not using any filters at this point, we can ignore the filter options. We will need to filter syslog alerts later on to support real-time alerting, but for now, to construct the log line you simply utilize the source and destination lines you created previously:

log {source(sensor_7); destination(snort_server); };

This completes the configuration of syslog-ng on the sensor. We will have to revisit this file later to enable Stunnel. To start syslog-ng, run the command /usr/local/sbin/syslog-ng.

Installing and configuring syslog-ng on the server

You can follow the same process for installing syslog-ng on the server as you did for the sensors. Download and install libol, then install syslog-ng.

Configuring syslog-ng for the Snort server is relatively painless now that you understand how to configure a syslog-ng.conf file. Create a syslog-ng configuration file located at /etc/syslog-ng/syslog-ng.conf and open the file for editing. First create a source line that listens to both a TCP port and the local syslog-ng application. We want to see alerts that are incoming from the sensors, as well as any related to the syslog-ng application itself. Use the following source line:

source sensors {unix-stream("/dev/log "); internal(); tcp(ip(Snort_Server_IP ) port(514) max-connections(7) };

This command listens for alerts generated locally by syslog-ng. It also listens for alerts via TCP to port 514 to the interface with the IP address of Snort_Server_IP assigned to it. You should change this IP address to match the IP of the management NIC you use to control the sensors. The max-connections()option sets the maximum number of sensors that can connect to the syslog-ng server.

The next line to create is the destination configuration line. You should send alerts to a logfile local to the server. Do so with this line:

destination localhost { file("/var/log/snort.log ")); };

This writes all the logs from the sensors to the log file located where specified. To complete the posting of alerts to a local file, add a log statement to associate the source and destination:

log {source(sensors); destination(localhost); };

You should now test Snort by sending traffic to generate alerts and by checking the /var/log/snort.log file. If everything is working correctly, you can move on to configuring real-time alerting with syslog-ng.

Configuring syslog-ng for real-time alerting

Configuring syslog-ng to send alerts via email or pager involves creating a simple shell script that is executed by syslog-ng when a string is matched. The shell script in turn executes the mailing or paging application. Some additional configuration lines are required as well.

First add the configuration lines, then create the shell script. Open the syslog-ng.conf file for editing. You will use the source line that is used to log to the local snort.log file, so you need not create a new source line. The destination for the alerts is the shell script you have yet to create. Use this destination line to execute the script:

destination email_alert_script {program ("/usr/local/bin/alert_mail.sh "); };

The program option specifies the command to be executed that will receive the alerts. Be sure to include the full path.

Next, create a filter that matches only your high-priority Snort alerts. If you want to match all Snort alerts with a priority of 1, create this filter line:

filter high_priority {match ("\\[Priority:1 \\]"); };

Notice that you must escape the bracket symbols with a double backslash, \\. Create filters for each of the priorities on which you want to alert.

Now you must add the final log statement to tie the source, destination, and filter lines together.

log {source(sensors); filter(high_priority); destination(email_alert_script); };

This completes the setup of the syslog-ng.conf file. Exit and restart syslog-ng.

The final piece of the puzzle is to write the simple shell script that syslog-ng is to execute. Open /usr/local/bin/alert_mail.sh for editing. Enter the following script:

while read line; do
echo $line |mail -s "High Priority Snort Alert" IDS__admin@domain.com

This script emails the alert to IDS_admin@domain.com with the subject of "High
Priority Snort Alert." You can change this script to your liking if you are using a paging
package or mailing application other than sendmail. You can easily alert on other priorities by creating new filters and new log statements. You should test to ensure that the
real-time alerting is functioning and then move on to encrypting the syslog-ng communication via Stunnel.

Encrypting syslog-ng sessions with Stunnel

If you have yet to install Stunnel on the Snort sensors and server, you can read how in chapters 6 and 7 of the book from which this article is excerpted. To make use of Stunnel you have to make changes to the syslog-ng.conf files on both the sensors and the server.

Open the syslog-ng.conf file on the sensor for editing. The first step is to include a global option that preserves the correct name of the local syslog-ng machine. If you do not set this option, all the alerts will have the hostname set as localhost, making it difficult to determine which sensor has generated the alert.

options { keep_hostname(yes); };

Next create a new destination line. You want to route traffic from syslog-ng so that Stunnel can read it, encrypt it, and forward the traffic on to the server. Add a new destination line that reads:

destination stunnel {tcp("" port (513)) ;};

This destination sends alerts to the localhost (127.0 0.1) on port 513. Next, change the existing log line to use the new destination:

log { source(sensor_7); destination(stunnel); };

Save and exit the syslog-ng.conf file. Restart the syslog-ng process so that syslog-ng recognizes the new configuration file.

Now start a Stunnel daemon to handle the encrypted syslog-ng traffic:

/usr/local/stunnel/sbin/stunnel -c -d -r \
Snort_Server_IP :512 -s stunnel_user -g stunnel_group &

This command sets Stunnel in client mode with the -c switch. It forwards syslog-ng traffic sent to port 513 on the localhost to the Snort server located at Snort_Server_IP . It also runs the daemon as stunnel_user, which is a member of stunnel_group. Stunnel is now configured for the sensor.

Moving to the Snort server, you need to make similar changes to the syslog-ng configuration file. Open the syslog-ng.conf file for editing. On the server, Stunnel accepts the traffic and forwards it to the local syslog-ng TCP port. The first step is to create a new source line that reflects the change. Add the following source line:

source stunnel { unix-stream("/dev/log "); internal();
tcp(ip( port(514) max-connections(7) };

Now you need to alter the log line to reflect the new source. Change your existing log line to:

log {source(stunnel); destination(localhost); };

Save and exit, and restart the syslog-ng daemon. You are now ready to log from Stunnel to the local syslog-ng service. The final step is to start the Stunnel daemon on the server:

/usr/local/stunnel/sbin/stunnel -d 512 -r
-p /usr/local/ssl/certs/stunnel.pem &

This command starts Stunnel listening on port 512 for incoming syslog-ng traffic. It then forwards traffic to the local syslog-ng server running on port 514. This completes the configuration of Stunnel. Alerts will now traverse the network encrypted.

Closing the loop

This distributed Snort setup is relatively resistant to session-based attacks. The MySQL connection is encrypted, the syslog-ng session is encrypted, and the ACID browser session is encrypted. Although the setup is by no means bulletproof, it should make the interception and modification of alerts relatively difficult for most intruders. The only major hole you could have in the system is the real-time alerting emails.

If you have bothered to encrypt all these connections, you should close the loop and encrypt the real-time email alerts. Check the documentation for your mailing application for instructions on installing an encrypted email system.

Jack Koziol is manager of
information security at a national health benefits company
headquartered in the western suburbs of Chicago.
He has been working in network security since
1998. He has held senior management
positions in the ecommerce, healthcare, and financial
industries, where he has architected large scale
Snort-based intrusion detection systems for production
environments. He has contributed to Information Security
Magazine, teaches "Hack and Defend" and CISSP review
sessions courses, and speaks on various information
security topics.


  • Security
Click Here!