Video Screencast Help

Complete Snort-based IDS Architecture, Part One

Created: 06 Nov 2002 • Updated: 02 Nov 2010
Language Translations
Anonymous's picture
+2 2 Votes
Login to vote

by Anton Chuvakin and Vladislav V. Myasnyankin


Intrusion detection systems (IDS) are one of the fastest growing technologies within the security space. Unfortunately, many companies find it hard to justify acquiring IDS systems due to their perceived high cost of ownership (for example see Justifying the Expense of IDS by Kevin Timm and David Kinn). However, not all IDS systems are prohibitively expensive. This two-part article will provide a set of detailed directions to build an affordable intrusion detection architecture from hardware and freely available software. This discussion will avoid the classic "build or buy" debate and instead focus on building the system at a minimum cost.

Building often provides a definite cost advantage, especially for companies that are unsure about the long-term necessity of the IDS. Building it cheaply allows one to evaluate the technology with very little investment and without necessarily possessing sophisticated network security skills. That said, it is reasonable to expect that maintaining and tuning the IDS will require relatively advanced security knowledge.

Also, while the goal of this discussion is to help readers to build a low-cost IDS, they should be aware of the expenses that are involved with operating, maintaining and adequately monitoring the system. In fact, it has been claimed that running a self-built IDS is more expensive than running a commercial system due to the lack of support provided by IDS vendors. This statement may be or not be true, but free support sources such as mailing lists and user forums can often be more thorough and timely than the official support channels.

Either way, it is clear that the initial acquisition cost is lower for the free solution. Furthermore, if the in-house staff is qualified to build the IDS, one can likely conclude that they will be able to run it without outside support, thus saving money on the day-to-day operation of the IDS. This does not mean that there are not significant expenses involved in the operation of the system. For instance, personnel requirements for round-the-clock monitoring of a single console range have been estimated from 3-7 analysts on full-time staff (8-hour shifts, weekends, backup staff, etc).

General Design

The intrusion detection platform discussed in this paper will be based on Debian GNU Linux OS, Snort network IDS, MySQL database, and ACID analysis console. Debian is entirely free software that may be used under GNU General Public License. Of course, one can use any Linux system, as they generally differ from each other only by package format and start-up scripts hierarchy. But Debian has been chosen for this example because among its general features are security and stability. It is also a highly configurable system: users can select and install only the things they need to perform the set of tasks, which is very important for security reasons. Debian also allows for easy deployment of the minimum system, a characteristic that is highly desirable for IDS sensors.

The first thing to consider in the general design of the IDS is to determine the best place to position the IDS. Unfortunately, a detailed discussion of this subject is beyond the scope of this paper, and can be found elsewhere on the Internet or in various books, which look at various deployment schemes (external connection, IDS behind firewall, both inside and outside, DMZ, internal network, etc). (Two such resources are Network Intrusion Detection: An Analyst's Handbook by Judy Novak and Stephen Northcutt, and the SecurityFocus article Managing Intrusion Detection Systems in Large Organizations by Paul Innella, Oba McMillan, and David Trout.)

In all cases, one needs to keep one common problem in mind: traffic availability. To run an IDS, one needs to have all network traffic available for an IDS inspection. If the network is hub-based, this is no problem: one has only to connect an IDS sensor to any unused hub port and sniff all the information. But in the switched environment the sensor will become blind because packets are send only to ports, where the appropriate destination MAC address is located. Only broadcast packets are available to all hosts in such environment.

Many switches have a special port, called "SPAN-port", "mirror-port", etc. This may be a dedicated port or any port, configured to be a monitor port by the switch software. Usually, this port works at higher speed than others for a simple reason: to monitor 10 channels at 10 Mbps, one needs a 100 Mbps line as a minimum.

Another related problem is VLAN-divided networks. If the hardware does not allow the user to monitor different VLANs on a SPAN-port at the same time, one option is to try to monitor a trunk-link. Usually, this is a link between switches or routers, where packets from all VLANs are transmitted marked with a particular label, called "VLAN ID tag", according to IEEE 802.1q standard (also known as "dot 1q"). However, an IDS or a sniffer cannot directly deal with this traffic to due to VLAN ID change to packet structure. Fortunately, newer Linux kernels support 802.1q, so one can tune VLAN parsing on primary interface (for example, eth0) and direct appropriate traffic to the virtual interfaces (eth0.1, eth0.2, eth0.3, etc) according to VLAN ID. Note that Linux VLAN interfaces are designated as "eth0.X" and should not be confused with IP aliases which are marked "eth0:X".

All one needs to do is to turn on 802.1q VLAN support in the kernel configuration and install vlanconfig. Traffic on each virtual interface will be analyzed by its own IDS sensor.


This series will discuss two deployment scenarios: a single IDS box (possibly with many Snort instances for VLANs) and a true distributed system with numerous sensors. The set-ups have one important similarity: for security reasons, sensor and administrative network interfaces must be separate. So one needs to have at least two NICs on the computer.

The first option (single host) is more appropriate for a small network with 3-4 hosts or for a network with single low-speed Internet connection. In this case the Snort software, Alert SQL database, Web server and additional software are deployed on a single computer. The second (distributed) option is similar but will involve several sensors, each deployed on a separate computer and one central console with SQL database, Web server and additional software on a dedicated computer. In cases of higher traffic load one might want to install the database and a Web server on different computers.

Because components of the distributed IDS are connected via network, several security measures must be implemented. First, to protect traffic between analyst workstation and a database, SSL connection will be used. To restrict access to the console, the standard feature of Apache Web server, basic http authentication via .htpasswd, will be utilized for ACID-based console.

As was noted above, separate interfaces are used for sniffing and administration. The main reason for this is that the sniffing interface will have no IP address assigned to it. In Linux, it is easy to activate a network interface with no IP by using a command similar to ifconfig eth1 up. While not providing total security, this solution is much better than having a regular interface for detection. On switched networks, if one connects the sensor to the special switch port in "port monitor" mode (mirror port, SPAN, etc), then this port is considered to be read-only by the switch itself, so the sensor cannot send any data through this port and is extremely hard to attack through it (notwithstanding the bugs in packet capture libraries and rumoured vulnerabilities of the TCP/IP stack).

Base System Set-up

The guidelines below can be used to implement a secure minimal Linux system.

It is recommended that readers use a Debian CD or network install via floppies (4 are needed). In fact, an intermediate variant (minimum CD and network install) might be an option for some environments. This option was used for the test configuration by one of the authors.

First, you should download Debian floppies or download and burn a minimal CD image (or acquire a full distribution CD set. Four floppy images are needed (rescue.bin, root.bin, driver-1.bin and driver-2.bin). You can create the floppy images using rawrite.exe (Windows) or dd> (under Linux) .

You then need to insert rescue floppy and boot from rescue. When prompted, insert root diskette and continue loading. For CD ROM case, boot from the CD ROM but keep the computer connected to the network for downloading additional software packages.

Here is guide for secure base system building:

  1. Partition a hard disk. While you may create only one Linux native partition and one swap partition, it is recommended that you separate at least /tmp and /var from the rest (/, /usr, /home). The size of swap partition depends on the available hardware and should be equal to at least twice the RAM size. For partitioning in the installation process, you can use cfdisk - a friendly program with built-in help.
  2. Install kernel and configure driver modules - the configure networking
  3. Install the base system packages as suggested by the install program. For network install, select "Network" (http or ftp connection) for further installation and enter (or confirm) the download URL. The default URL is, but other locations can be selected as well (for example, If a direct Internet connection is unavailable, one will need to enter proxy server parameters such as address and port.
  4. Reboot the system. At this point, core Debian installation is complete but some preliminary configuration should be done. One needs to choose the appropriate timezone, setup password security options, define root password and create other accounts.
  5. Run tasksel. Do not select any additional software. The precise set of required software will be installed manually later. Choose "no" if asked about installing further software. Do not run dselect. When the set-up script asks about the mail system configuration, answer "local delivery only."

The base system install is now complete. Now the resulting system should be hardened. The minimum required hardening is to remove all network services by editing the /etc/inetd.conf or by disabling the inetd daemon completely.

Add to crontab synchronization with time reference machine:

 # crontab -e 0 2 * * * /usr/sbin/rdate -s 

OpenSSH will be used for secure remote administration. Debian install might install the SSH package by default. If the SSH is not running after the system reboot, install the package using:

 # apt-get install ssh 

During the post-install configuration, one should answer "yes" to the question "Do you want to run the sshd server?" Additional access control should be configured to only let specified IP addresses access the system. TCP wrappers are the simplest to configure, as they are installed by default. Add a line "ALL:ALL" to /etc/hosts.deny and the IP address of the administration system to the /etc/hosts.allow. The format is:

 sshd: 111.222.333.444 

To add yet another layer to the remote access security, one can enable passwordless SSH authentication via public keys and totally disable password authentication. It is also highly recommended that you deploy a host firewall with a restrictive rule set (similar to the one described in Netfilter How-To).

The base system configuration is complete. The system can now be deployed in the server room and the next steps can be performed remotely via secure shell.

Snort Installation

At this point two versions of the Snort set-up are possible. The first is a single box set-up (sensor, database and console on one machine), which is more appropriate for a small environment. First, the database for storing alert information is added to the Linux system. This set-up uses MySQL database.

 # apt-get install MySQL-server 

The access to a database is controlled by a MySQL admin password ("BigSecretPassword" in the example below):

 # mysqladmin -u root password BigSecretPassword 

Next, the Snort IDS with SQL logging support is deployed:

 # apt-get install snort-mysql 

It is more consistent to accept the default values and then run through a configuration checklist below. First, create snort_log database and set up user passwords:

 # cd /usr/share/doc/snort-mysql/contrib. # gunzip -d create_mysql.gz # mysql -u root -p Enter password: Welcome to the MySQL monitor.  Commands end with ; or \g. mysql> create database snort_log; mysql> connect snort_log; mysql> source create_mysql mysql> grant CREATE, INSERT, SELECT, DELETE, UPDATE on snort_log.* to snort; mysql> grant CREATE, INSERT, SELECT, DELETE, UPDATE on snort_log.* to snort@localhost; mysql> grant CREATE, INSERT, SELECT, DELETE, UPDATE on snort_log.* to acid; mysql> grant CREATE, INSERT, SELECT, DELETE, UPDATE on snort_log.* to acid@localhost; mysql> create database snort_archive; mysql> connect snort_archive; mysql> source create_mysql mysql> grant CREATE, INSERT, SELECT, DELETE, UPDATE on snort_archive.* to acid; mysql> grant CREATE, INSERT, SELECT, DELETE, UPDATE on snort_archive.* to acid@localhost; mysql> set password for 'snort'@'localhost'=password(''); mysql> set password for 'snort'@'%'=password(''); mysql> set password for 'acid'@'localhost'=password(''); mysql> set password for 'acid'@'%'=password(''); mysql> exit 

Since the IDS platform can be used to sniff many interfaces or many virtual (VLAN) connections, the default set-up needs to be modified. For each VLAN circuit a separate instance of Snort will be used. Provided below is the set of Snort configuration files that seamlessly support any number of VLAN links and are easy to maintain and upgrade.

First, an additional directory needs to be created to store the common config files:

 # mkdir  /etc/snort/common 

If you need to switch interfaces into promiscuous mode, then simply create a file named "promisc" in the "common" directory, which will be referenced by the start-up script:

 # touch promisc 

Now one needs to create a file named "interfaces", containing the list of interfaces that Snort must be run on. For example, one can add either real (eth1, eth2 - in the case of multiple network cards) or virtual (eth1.0, eth1.1 - in case of a VLAN set-up) interfaces, one for each monitored line. Virtual interfaces are monitored via the 802.1Q support in Linux, and in this case one must ensure that the master interface is already up, because the ifconfig eth1.1 up command does not bring up the master interface (eth1).

Next, edit the common configuration file. In this example it will contain:

 ##### begin file #### # common variables pass ICMP $HOME_NET any -> $HOME_NET any pass TCP $HOME_NET any -> $HOME_NET any pass UDP $HOME_NET any -> $HOME_NET any # preprocessors preprocessor frag2 preprocessor stream4: detect_scans preprocessor stream4_reassemble preprocessor http_decode: 80 -unicode -cginull preprocessor rpc_decode: 111 preprocessor bo: -nobrute preprocessor telnet_decode # output plugins output database: log, mysql, user=snort password= dbname=snort_log host=localhost #### end file #### 

The "pass" rules might not be appropriate for all networks since internal-to-internal attacks will not be recorded. For a busy network where the perceived threat is outside the "pass" rules might be a good idea since they will decrease the hardware requirements and thus save some money.

Next, one must create the configuration file for each sensor in /etc/snort directory. The naming convention is simple: "snort.conf.<interface>", where "interface" is eth1, or eth1.0 etc.

Typical config may contain:

 #### begin snort.conf.eth1 example file #### var HOME_NET  #for example: var EXTERNAL_NET !$HOME_NET var SMTP $HOME_NET var HTTP_SERVERS $HOME_NET var DNS_SERVERS $HOME_NET var SQL_SERVERS $HOME_NET var HTTP_PORTS 80 var SHELLCODE_PORTS !80 var ORACLE_PORTS 1521 include /etc/snort/common/ # # Include classification & priority settings # include classification.config # # Customize the rule set # include bad-traffic.rules include exploit.rules include scan.rules include finger.rules include ftp.rules include telnet.rules include smtp.rules include rpc.rules include rservices.rules include dos.rules include ddos.rules include dns.rules include tftp.rules include web-cgi.rules #include web-coldfusion.rules #include web-frontpage.rules #include web-iis.rules include web-misc.rules include web-attacks.rules include sql.rules include x11.rules #include icmp.rules #include netbios.rules include misc.rules include attack-responses.rules #include backdoor.rules #include shellcode.rules #include policy.rules #include porn.rules #include info.rules #include icmp-info.rules #include virus.rules include local.rules #### end of snort.conf.eth1 example file #### 

Of course, one needs to review the set of rules based on the specific conditions. For example, if you do not use any Windows machines or UNIX samba servers, you probably do not need to include the "netbios.rules" file. In some cases, you will need to write your own rules or modify existing rules. See Snort documentation for additional details on rule writing.

What are the factors that might influence the choice of rules? While a detailed discussion of IDS tuning is beyond the scope of this article, readers can refer to Kevin Timm's SecurityFocus article Strategies to Reduce False Positives and False Negatives. That said, one approach is to enable all rules and spend several days flooded with alerts, analyzing them and reducing the rule set accordingly. This route is more appropriate for internal network IDS deployment. Another solution is to narrow the ruleset to only watch the "risky" services. This works better in a highly secure DMZ set-up in which all machines are carefully audited and hardened.

Everything should run properly once the configurations are completed, but sometimes bugs and crashes happen. To automatically restart the Snort instances, the following root-owned cron job will be used:

 */5 * * * * /usr/local/bin/snortcheck >/dev/null 2>&1 

It uses the script provided below:

 #### begin /usr/local/bin/snortcheck #### #!/bin/sh #snort restarting num=`ps aux|grep "\/etc\/snort"|wc -l|awk '{print $1}'` if [ $num -lt 3 ] then /etc/init.d/snort restart date >> /var/log/snortrestart echo "Snort was restarted at `date`" | /usr/bin/mail root fi ####end of  /usr/local/bin/snortcheck #### 

One should ensure the appropriate permissions on the file /usr/local/bin/snortcheck (read and execute by the owner i.e. root).

The final step in the set-up process is to edit the Snort startup script:

 #### begin /etc/init.d/snort #### #!/bin/sh # # Script to control SNORT execution under Debian # Written by Vladislav V. Myasnyankin . PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin DAEMON=/usr/sbin/snort PIDFILES=`ls /var/run | grep snort` INTERFACES=`cat /etc/snort/common/interfaces` # Arguments passed to SNORT # # To watch only our system ARGS="-o -p -X -u snort -g snort -D" # # Check if we need to watch all packets in the segment if [ -e /etc/snort/common/promisc ] then ARGS="-o -X -u snort -g snort -D" fi test -x $DAEMON || exit 0 case "$1" in   start)     echo -n "Starting Network Intrusion Detection System: snort"     for IFACE in $INTERFACES;         do         PIDFILE=/var/run/snort_$         CONFIG=/etc/snort/snort.conf.$IFACE         echo $IFACE         echo $CONFIG         echo $PIDFILE          /sbin/ifconfig | grep $IFACE > /dev/null           if [ $? -ne 0 ]             then                                           /sbin/ifconfig $IFACE up                     fi  /sbin/start-stop-daemon --start --pidfile $PIDFILE --exec $DAEMON -- -i $IFACE $ARGS -c $CONFIG 	case "$?" in 	  0) echo "." ;; 	  1) echo "...already running." ;; 	  2) echo "...failed." ;; 	esac         done     ;;   stop)     echo -n "Stopping Network Intrusion Detection System: snort"     for PIDFILE in $PIDFILES;         do         echo         echo $PIDFILE         echo         /sbin/start-stop-daemon --stop --quiet --oknodo --pidfile /var/run/$PIDFILE --exec $DAEMON         echo "."         rm -f /var/run/$PIDFILE         done     ps cax | grep '/usr/sbin/snort' 	   | awk '{ print $1 }' 	   | xargs --no-run-if-empty kill -9 >/dev/null     ;;   restart|force-restart|reload|force-reload) 	/etc/init.d/snort stop  	# stop will take care that the thing is really dead 	/etc/init.d/snort start        	;;   *)     echo "Usage: /etc/init.d/snort {start|stop|restart|force-reload|reload}"     exit 1     ;; esac exit 0 #### end of /etc/init.d/snort #### 

Now the IDS can be safely restarted using the new multisensor configuration.


This concludes the first part of our two-part discussion of how to build a Snort-based IDS from scratch. In the next installment, we shall discuss Web interface configuration, summaries and daily reporting, automated attack response, sensor installation, installation of the central station, and big distributed IDS systems.

To read Complete Snort-based IDS Architecture, Part Two, click here.

Vladislav V. Myasnyankin, security expert, author and translator of several IT security related papers. At present time he works as Chief Information Security Officer at the bank. The author would like to thank Paul Pokrovsky and Michael Plotnikov for help with article development.

Anton Chuvakin, Ph.D., GCIA is a Senior Security Analyst with a major information security company. His areas of infosec expertise include intrusion detection, UNIX security, honeypots, etc. In his spare time he maintains his security portal

This article originally appeared on -- reproduction in whole or in part is not allowed without expressed written consent.