Author: Joe Barr
Nicholas Thill — known as Nico in the OpenWrt community — maintains three separate packages for Snort in his repository of packages. They include a plain Jane version, without any support for logging to a database, and two database-specific packages: one for MySQL and one for PostgreSQL. All are based on the Snort release 2.3.3-1 and are considered to be in a testing state and not yet included in the official release.
For the sake of simplicity, I’ll discuss the plain Jane installation in this article. Regardless of which version you select, you need to be aware of the fact that you can overload and/or potentially crash your OpenWrt router by running Snort wide-open with all its rule sets and preprocessors (rule sets look for specific signatures, while preprocessors are plugin modules that extend Snort’s capabilities), or simply by logging Snort’s output to the local system and filling up all available space.
OpenWrt is a wonderful distribution, but it often runs on systems with serious memory and/or storage constraints, which you can easily overload by running Snort with all the trimmings.
Syslog remotely
Snort reports its findings in log records, so running Snort without saving them for later analysis is like typing a book without putting paper in the typewriter: you go through a lot of motions but don’t get much of a return for your efforts. Given the typical router’s constraints both in processing power and storage space, it makes sense to log Snort’s findings remotely.
In order to start syslog logging remotely, you’ll need to make changes to your configuration both on the router and on the system where the logging will be done. It’s a snap to set up remote logging on OpenWrt, as explained in this Mini-HOWTO on the OpenWrt wiki.
From the OpenWrt command line, enter the following:
nvram set log_ipaddr=<192.168.1.101> nvram commit
Change the IP address to match the address of the system running syslogd. Then edit /etc/initab and add these two lines:
::respawn:/sbin/syslogd -n ::respawn:/sbin/klogd -n
And finally, edit /etc/init.d/rcS to add:
mkdir /var/log
To handle the logging on the remote side of the connection, add the -r
option to the command line that starts syslogd and you’re good to go. If you’re using Ubuntu, for example, edit /etc/init.d/sysklogd and change the line that reads:
SYSLOGD="-u syslog"
to read:
SYSLOGD="-r -u syslog"
Of course, if you’re like me and think that syslogd is so last generation, you can install syslog-ng instead, which accepts remote logging by default.
Installing and Configuring Snort
The easiest way to install the version of Snort is with the OpenWrt Admin Console. But before you do that, check /etc/ikpg.conf on the router and make sure the repository mentioned above is included as a source. If it’s not, add this line to the file:
src nico-t http://nthill.free.fr/openwrt/ipkg/testing
Then click on System and Installed Software in the OpenWrt Admin Console and refresh the list of available packages by clicking on Update package lists. All that’s left to do then is scroll down the list of packages, find the version of Snort you want, and click on Install next to it.
Before you configure Snort, you’ll need to get some rules from the Snort site. Snort rules define the packets that Snort should identify and take action on, and the actions that should be taken.
Rather than downloading only the rules included in the default OpenWrt snort.conf file, I downloaded a full set and put them in /etc/snort/rules. That way, I don’t have to get new rule sets each time I tweak snort.conf.
You’ll need to define the HOME_NET variable near the top of /etc/snort/snort.conf, and also define an output method near the bottom. Once you’ve done those two things, Snort should be ready to run, except for whatever tweaking you need to do for preprocessors and rules.
The pre-configured version of snort.conf, for example, comes with almost all the preprocessors commented out. To activate them, simply remove the #
signs from the beginning of each line of the section for the preprocessor you want. The same thing is true for the rules. Note: Remember to keep an eye on memory usage as you activate preprocessors and rule sets.
My HOME_NET in snort.conf already looked like this, so I kept it:
var HOME_NET 192.168.1.0/24
For the output option, I removed the # from this line:
# output alert_syslog: LOG_AUTH LOG_ALERT
Those two changes made, I started snort running by entering snort -i vlan1 &
and it blasted off, producing the following on my OpenWrt console:
root@OpenWrt:~# Running in IDS mode with inferred config file: /etc/snort/snort.conf Initializing Network Interface vlan1 --== Initializing Snort ==-- Initializing Output Plugins! Decoding Ethernet on interface vlan1 Initializing Preprocessors! Initializing Plug-ins! Parsing Rules file /etc/snort/snort.conf +++++++++++++++++++++++++++++++++++++++++++++++++++ Initializing rule chains... ,-----------[Flow Config]---------------------- | Stats Interval: 0 | Hash Method: 2 | Memcap: 10485760 | Rows : 4099 | Overhead Bytes: 16400(%0.16) `---------------------------------------------- No arguments to frag2 directive, setting defaults to: Fragment timeout: 60 seconds Fragment memory cap: 4194304 bytes Fragment min_ttl: 0 Fragment ttl_limit: 5 Fragment Problems: 0 Self preservation threshold: 500 Self preservation period: 90 Suspend threshold: 1000 Suspend period: 30 Stream4 config: Stateful inspection: ACTIVE Session statistics: INACTIVE Session timeout: 30 seconds Session memory cap: 8388608 bytes State alerts: INACTIVE Evasion alerts: INACTIVE Scan alerts: INACTIVE Log Flushed Streams: INACTIVE MinTTL: 1 TTL Limit: 5 Async Link: 0 State Protection: 0 Self preservation threshold: 50 Self preservation period: 90 Suspend threshold: 200 Suspend period: 30 Enforce TCP State: INACTIVE Midstream Drop Alerts: INACTIVE Stream4_reassemble config: Server reassembly: INACTIVE Client reassembly: ACTIVE Reassembler alerts: ACTIVE Zero out flushed packets: INACTIVE flush_data_diff_size: 500 Ports: 21 23 25 53 80 110 111 143 513 1433 Emergency Ports: 21 23 25 53 80 110 111 143 513 1433 X-Link2State Config: Ports: 25 691 112 Snort rules read... 112 Option Chains linked into 57 Chain Headers 0 Dynamic rules +++++++++++++++++++++++++++++++++++++++++++++++++++ Warning: flowbits key 'tls1.client_hello.request' is checked but not ever set. Warning: flowbits key 'sslv3.client_hello.request' is checked but not ever set. +-----------------------[thresholding-config]---------------------------------- | memory-cap : 1048576 bytes +-----------------------[thresholding-global]---------------------------------- | none +-----------------------[thresholding-local]----------------------------------- | none +-----------------------[suppression]------------------------------------------ | none +------------------------------------------------------------------------------ Rule application order: ->activation->dynamic->alert->pass->log Log directory = /var/log/snort --== Initialization Complete ==-- ,,_ -*> Snort! <*- o" )~ Version 2.3.3 (Build 14) '''' By Martin Roesch & The Snort Team: http://www.snort.org/team.html (C) Copyright 1998-2004 Sourcefire Inc., et al.
To make sure Snort was logging to the remote machine, I checked the syslog there and found these two new entries in /var/log/syslog:
Mar 2 15:40:44 192.168.1.1 kernel: vlan1: dev_set_promiscuity(master, 1) Mar 2 15:40:44 192.168.1.1 kernel: device vlan1 entered promiscuous mode
Before making any big changes to the rules or preprocessors, I wanted to have baseline measurement of how much system resources Snort was eating in terms of memory and CPU, so I asked top. Top said:
Mem: 18420K used, 12164K free, 0K shrd, 896K buff, 4664K cached Load average: 1.00, 1.01, 0.76 (State: S=sleeping R=running, W=waiting) PID USER STATUS RSS PPID %CPU %MEM COMMAND 571 root R 436 1 98.4 1.4 vi 899 root R 412 561 0.7 1.3 top 898 root S 7916 561 0.3 25.8 snort 560 root S 640 537 0.3 2.0 dropbear 890 root S 640 537 0.0 2.0 dropbear 561 root S 464 560 0.0 1.5 ash 891 root S 460 890 0.0 1.5 ash 530 nobody S 436 1 0.0 1.4 dnsmasq 49 root S 428 1 0.0 1.3 syslogd 537 root S 420 1 0.0 1.3 dropbear 379 root S 400 1 0.0 1.3 udhcpc 1 root S 392 0 0.0 1.2 init 55 root S 392 1 0.0 1.2 init 541 root S 388 1 0.0 1.2 httpd 50 root S 340 1 0.0 1.1 klogd 542 root S 300 1 0.0 0.9 telnetd 3 root SWN 0 1 0.0 0.0 ksoftirqd_CPU0 7 root SW 0 1 0.0 0.0 mtdblockd 6 root SW 0 1 0.0 0.0 kupdated 4 root SW 0 1 0.0 0.0 kswapd 32 root SWN 0 1 0.0 0.0 jffs2_gcd_mtd4 5 root SW 0 1 0.0 0.0 bdflush 2 root SW 0 1 0.0 0.0 keventd
Right out of the box, and with only minimal rules in place, Snort was eating 25% of system memory. I added rules and preprocessors, primarily for the detection of scans, but I’ve tried to avoid taking more than 50% of memory or to have less than 1000K free memory. So far, so good, and with no impact on performance of the router. But remember, you can overload the router if you’re not careful, so keep a watchful eye on available resources as you tweak the config.
After I enabled the scan detection preprocessors and added a couple of additional rule sets, Snort’s memory consumption climbed to 49.3% and the amount of free memory had shrunk to just over 5000K. I decided to stop there.
You might consider installing the plain Jane version first, then moving to one of the database-specific versions if you like. But if you do, remember that changing versions requires more than simply changing your snort.conf to indicate the database: you have to remove the plain Jane version of Snort and then install the database version. That process will replace your snort.conf, so if you want to keep your old one, make a copy before you install the new version of Snort.
For further information about Snort on OpenWrt, see this report by David Schwartzburg.
Category:
- Security