Introduction
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.
Deployment
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:
- 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.
- Install kernel and configure driver modules - the configure
networking
- 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 http://http.us.debian.org/debian, but other
locations can be selected as well (for example, http://ftp.uk.debian.org/debian). If a direct
Internet connection is unavailable, one will need to enter proxy
server parameters such as address and port.
- 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.
- 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 time.nist.gov
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: 127.0.0.1 .gooddomain.org 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 common.inc 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 common.inc 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: 192.168.1.0/24
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/common.inc
#
# 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_$IFACE.pid
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.
Conclusion
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.
|