Files
nonox-1.17.jar -- the jar file containing NoNox 
nonox.conf -- the configuration file 
startup.sh -- an example of how to start NoNox from a script 
 Installation
These quick-start instructions assume NoNox will be installed in /usr/local/nonox... but that's not required. 
1. Do you have Java 1.4 or later? 
  java -version 
if not, get it from Sun and install it. That work is well beyond the scope of this document. 
  
2. Become root 
   su  
  
3. Create the directory /usr/local/nonox 
   mkdir /usr/local/nonox 
  
4. Place the files nonox-1.17.jar, nonox.conf and startup.sh there 
  
5. If necessary, tweak your logrotate script: 
You may have to adjust the logrotate configuration for files that NoNox is watching. If you don't, then NoNox can't figure out that the log file has been rotated out and may continue reading the old file (or nothing). That sucks. As a safety against this, Nonox closes and re-opens all the monitored files every 60 minutes, just to be sure it's reading the correct file, so that even if you don't make this change, the max time you'd be without Nonox coverage is 60 minutes every time the logs are rotated. 
  
Add this to the logrotate configuration for all affected log files: 
   copytruncate 
  
Example logrotate file, /etc/logrotate.d/syslog: 
 /var/log/messages /var/log/secure /var/log/maillog /var/log/spooler { 
 sharedscripts 
 copytruncate 
 postrotate 
 /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true 
 endscript 
 } 
  
6. Edit nonox.conf to reflect the patterns you want to match, and the actions you want to execute. 
See the reference section below for guidance, as well as the provided nonox.conf file that already contains one pattern and one action. 
  
7. Test NoNox 
  java -cp /usr/local/nonox/nonox-1.17.jar com.challengeandresponse.nonox.NoNox -t  
Try some failed logins... confirm that they're logged to the file, and that NoNox is seeing them (it'll write to standard output whenever it has a match). 
  
8. Run NoNox 
  /usr/local/nonox/start.sh
 
  
9. Monitor NoNox 
  tail /var/log/nonox.log
 
 
  
REFERENCE
SIMPLE nonox.conf TO DETECT AND BLOCK SSHD LOGIN ATTACKS 
# SSHD failure in /var/log/secure on a box that writes an IPV6 header as well as the address (::ffff:) 
# 	Nov 27 07:31:05 localhost sshd[31585]: 	Failed password for invalid user adam from ::ffff:211.114.82.252 port 55889 ssh2 
pattern 	sshd_login_fail		/var/log/secure		(^.*?:\d\d:\d\d)\D.*Failed password.*?from\s::ffff:(\d+?\.\d+?\.\d+?\.\d+).* 
# Block an IP address if there are 4 failed sshd logins within half an hour from it 
action	sshd_login_fail		4	1800	/sbin/iptables -A INPUT --source %s -j DROP 
 
Command Line Parameters
NoNox can accept some command line parameters. 
Each parameter must be written by itself (e.g. -t -d -f *NOT* -tdf). The parser is dumb. My bad. 
-t  TEST MODE -- run normally but DO NOT execute the actions. Useful when debugging patterns to see if they're detecting the right stuff. 
-d  DEBUG MODE -- print lots of info about what the program is doing, including echoing all lines as they are processed 
-f  FULL FILE MODE -- don't tail the file, but read the entire file from the beginning and process as if those entries were just coming in. Use this to "catch up" against a log file if Nonox has been offline, or when testing your patterns against logged attack entries. 
-c /path/to/config.file  CONFIG FILE -- use this config file instead of the default /usr/local/nonox/nonox.conf 
 
Configuration File
- The NoNox configuration file contains PATTERN and ACTION descriptors. 
- The file is processed from top to bottom, so declare all patterns first, then declare all actions. 
- For safety, the file should only be writeable by the userid under which NoNox runs (rw-r--r--)... Future versions of NoNox will test for this and won't run if the file is open to writing by others. 
Patterns
Patterns are regular expressions, bound to files, that detect matching lines in those files and return information (an IP address primarily) that could be used in a defensive action (for example, blocking that IP address at a firewall). Pattern descriptors are stored in the NoNox configuration file.
The format of a pattern descriptor is: 
  
     pattern pattern_name filename regex_pattern 
  
Parameters are separated by white space (a blank space or a tab) 
  
pattern -- the literal word "pattern" introduces a pattern 
pattern_name -- you can name the pattern anything you'd like. Alphanumerics only. No spaces. Actions are bound to patterns through this name. Pattern names are not case-sensitive. More than one pattern may have the same name. If more than one pattern with the same name matches an event, the counter will be incremented once for each pattern's match... so take care not to have multiple patterns matching against the same event occurrences, or the counter will run up faster than you intended.
 
filename -- the full absolute path to the file to watch for this pattern 
regex pattern -- the regular expression that will match the pattern 
  
regex_pattern is a Java compatible regular expression with these restrictions: 
The pattern may return zero, one, or two GROUPS: 
First group: The date in standard logfile date/timestamp, e.g.: Aug 15 11:03:56 
Second group: The IP address to hand to the action(s) 
If no IP address is provided (i.e. there is no Match.group(2)), then the text constant "NONE" is used instead. Careful! if your action needs an IP address, be sure your pattern always returns one. 
  
Example patterns (preceded by comment-lines that begin with "#"): 
# Detect dictionary attacks against sshd by monitoring /var/log/secure 
# SSHD failure in /var/log/secure on a box that writes an IPV6 header as well as the address (::ffff:) 
# Nov 27 07:31:05 localhost sshd[31585]: 	Failed password for invalid user adam from ::ffff:211.114.82.252 port 55889 ssh2 
pattern 	sshd_login_fail		/var/log/secure		(^.*?:\d\d:\d\d)\D.*Failed password.*?from\s::ffff:(\d+?\.\d+?\.\d+?\.\d+).* 
  
# Detect dictionary attacks against sshd by monitoring /var/log/messages 
# Nov 27 10:01:10 localhost sshd(pam_unix)[8822]: authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.123.103  user=bert 
pattern sshd_login_fail		/var/log/messages	(^.*?:\d\d:\d\d)\D.*authentication failure.*?rhost=(.*\d).* 
 
Actions
Actions connect patterns with the conditions for triggering commands, and also provide the commands to run when they're triggered. Action descriptors are stored in the NoNox configuration file. The file is processed from top to bottom, so declare all patterns first, then declare all actions. 
NoNox actions are one-shots. Once an action is triggered for an (action,sourceIP) pair, it won't trigger again for that pair -- otherwise, continued attacks would result in multiple executions of the same command, for example, sending a flood of notices to an operator about an event once the threshold has been reached and more instances of the same event occur. 
The format of an action descriptor is: 
  
     action pattern_name threshold_count timelimit_seconds command 
  
Parameters are separated by white space (a blank space or a tab) 
  
action -- the literal word "action" introduces an action 
pattern_name -- the pattern_name to count occurrences of, matching an already-declared pattern as described above. 
threshold_count -- the number of times a pattern should match within timelimit_seconds in order to trigger execution of the command associated with this action. 
timelimit_seconds -- the maximum number of seconds between the oldest and most recent threshold_count pattern matches, in order to execute the command, for example, "4 matches in 30 minutes" 
command -- the command to execute when threshold_count matches occur within timelimit_seconds seconds.  
command may contain embedded spaces. The config file reader will capture everything from the start of command to the end of the line. 
  
In the command, the token %s is a placeholder for the IP address that triggered the action, provided one was captured as match group 2 (see Patterns above). 
 
A Note About Iptables
I use iptables to respond to in-progress password scans by dropping packets from the attacking host. I created a chain called "loganddrop" that logs any further packets received from that host (I was curious about how many more attempts they would make) and then drops the packet. 
  
To create a "loganddrop" chain in iptables, that LOGS a packet and the DROPs it (doh), do this: 
  /sbin/iptables -N loganddrop 
  /sbin/iptables -A loganddrop -j LOG --log-level info 
  /sbin/iptables -A loganddrop -j DROP 
  # this line saves the current iptables state (including the new chain) to make it persist after restart 
  /sbin/iptables-save 
  
If you just want to DROP the packets and not log new activity from blocked sources, don't bother with the above. Just make the ACTION end with "-j DROP" (note all upper case) rather than "-j loganddrop" 
  
Example action (preceded by a one-line comment): 
# Block an IP address if there are 4 failed sshd logins within half an hour from it 
action	sshd_login_fail		4	1800	/sbin/iptables -A INPUT --source %s -j loganddrop 
NoNox Memory Usage and Actions
NoNox creates one object per (action,sourceIP) and keeps these active until either they are triggered, or all records have completely aged out. A reaper thread runs occasionally to purge objects referencing events that are too old to trigger any actions. 
When an action is triggered, the object for that (action,sourceIP) is *not* purged. It is kept in memory indefinitely, to support the one-shot-per-trigger rule. If you have a massive number of actions firing, this could consume a nontrivial amount of memory. But on most ordinary systems, this isn't going to be an issue. The objects are small, consisting of one Long object per discrete event (so if your trigger is "10" events, there will be at most 10 Longs stored for a given source), and a few management fields... nothing big.
 
For version 1.17, this was the data structure: 
  Stack timestamps; (Longs, 16 bytes per entry)  
  int howmany; (4 bytes) 
  long maxAgeMsec; (8 bytes) 
  boolean fired; (1 byte) 
 
So, considering that the counter object itself, and the Stack inside it, each have overhead of 8 bytes, memory usage is on the order of 8+8+8+4+1+(16 * threshold_count), or 29 + (16 * threshold_count) bytes. So, if you've got an action that triggers after 10 pattern matches from a single IP address, that action's counter will use about 189 bytes for each IP address that triggers it. So again, in case it wasn't clear, the counters for sources that trigger an action are retained as long as NoNox is running. The counters for sources that disappear without triggering an action are gradually purged. 
 
Saving/Recovering State Between Invocations
NoNox does NOT save or recover state between invocations... so when you stop NoNox and restart it, all records of previously triggered actions are cleared and they will in fact be triggered again if the pattern matching rules are tripped again. Not too huge a deal in some cases (for example, if NoNox has previously created a firewall rule to block a host, then that host isn't going to get through later and trigger NoNox again) but something to be aware of. The importance or irrelevance of this "feature" depends on the commands you're executing. As Frosty the Snowman once said upon donning a magic hat, "Hap-py Birth-day"
Samples of log output
startup 
Sun Nov 27 12:22:29 EST 2005 NoNox version 1.17 of 2005-11-26 started. Read loop will pause:5 msec between read cycles (hardcoded, sorry!) 
Sun Nov 27 12:22:29 EST 2005 configuration parameters:  testMode=false; tailMode=true; debugMode=false 
Sun Nov 27 12:22:29 EST 2005 Using config file:/usr/local/nonox/nonox.conf 
Sun Nov 27 12:22:30 EST 2005 Opening file:/var/log/secure 
Sun Nov 27 12:22:30 EST 2005 In tail mode. Skipping to EOF of:/var/log/secure size:6522 
Sun Nov 27 12:22:30 EST 2005 loaded pattern:Pattern:sshd_login_fail bound to file:/var/log/secure with regexp:(^.*?:\d\d:
\d\d)\D.*Failed password.*?from\s::ffff:(\d+?\.\d+?\.\d+?\.\d+).* 
Sun Nov 27 12:22:35 EST 2005 loaded action:Action bound to pattern:sshd_login_fail threshold:4 time limit in seconds:1800
 Command:/sbin/iptables -A INPUT --source %s -j DROP 
Sun Nov 27 12:22:35 EST 2005 Files will be closed and reopened every 3600000 msec (60 minutes) 
Sun Nov 27 12:22:35 EST 2005 Starting reaper thread 
Sun Nov 27 12:22:35 EST 2005 Reaper thread running. Reaper will run every 1800000 msec (30 minutes) 
Sun Nov 27 12:22:35 EST 2005 Starting monitor loop 
  
periodic entries, while it's running 
Mon Nov 28 06:22:31 EST 2005 Opening file:/var/log/messages 
Mon Nov 28 06:22:31 EST 2005 In tail mode. Skipping to EOF of:/var/log/messages size:11283 
Mon Nov 28 06:22:36 EST 2005 Reaper thread running. Reaper will run every 1800000 msec (30 minutes) 
  
attack in progress, leading to triggering an action 
Mon Nov 28 06:46:23 EST 2005 MATCH pattern:sshd_login_fail count:1 action:0 address:210.245.189.235 source:Nov 28 06:46:23 localhost sshd[22158]: Failed password for root from ::ffff:210.245.189.235 port 53435 ssh2 
Mon Nov 28 06:46:31 EST 2005 MATCH pattern:sshd_login_fail count:2 action:0 address:210.245.189.235 source:Nov 28 06:46:31 localhost sshd[22171]: Failed password for root from ::ffff:210.245.189.235 port 53586 ssh2 
Mon Nov 28 06:46:40 EST 2005 MATCH pattern:sshd_login_fail count:3 action:0 address:210.245.189.235 source:Nov 28 06:46:40 localhost sshd[22179]: Failed password for root from ::ffff:210.245.189.235 port 53703 ssh2 
Mon Nov 28 06:46:50 EST 2005 MATCH pattern:sshd_login_fail count:4 action:0 address:210.245.189.235 source:Nov 28 06:46:50 localhost sshd[22187]: Failed password for root from ::ffff:210.245.189.235 port 53835 ssh2 
oldest timestamp: 1133178383645 msec 1133178383 seconds 18886306 minutes 
AGE of oldest timestamp in seconds:27 
Current system time: 1133178410673 
Mon Nov 28 06:46:50 EST 2005 ACTION running command:/sbin/iptables -A INPUT --source 210.245.189.235 -j DROP 
Mon Nov 28 06:46:51 EST 2005 Command executed. Exit value:0 
Contact Information
The author of NoNox is Jim Youll, jim@cr-labs.com 
Challenge/Response, LLC creates security and privacy software to support safe, private e-ecommerce transactions and to detect and reduce online fraud.
 |