5

I have snort listening to the SPAN port of a cisco switch. I'd like to be able to add an iptables DROP rule on my webserver for specific snort alerts but having a hard time finding out exactly how to do that. I'd like the blocking to happen in real-time rather than launching a script through cron to periodically trawl the snort logs.

I found an example on Seclists which uses syslog-ng to run a shell script but it must be for an older version of syslog-ng as I get an error about the syntax being deprecated when I restart syslog-ng.

I don't know a lot about syslog-ng filters, so going to do more research on that as it looks promising but thought I would pose the question here in case there is a better way of doing it. What's a good way to run a shell script when a snort alert comes over the SPAN port of my snort box?

Server Fault
  • 3,454
  • 7
  • 48
  • 88

1 Answers1

3

I've pieced together enough documentation to get something working. The solution involves telling snort to log to syslog, and then setting up syslog-ng to trigger on the snort syslog traffic to run the given shellscript. Having snort spooling to disk, or running scripts, isn't ideal for high traffic loads so be advised. If you configure snort to only alert on certain traffic to keep the load down, you should be fine. Setting up and debugging syslog-ng can be a pita so I've included the neccesary bits to get that working. Just add them to the bottom of syslog-ng.conf. Hope it helps someone else. As a note, syslog is logging 3 copies of each message for some reason. No idea why.

I used some of the info here: http://www.mad-hacking.net/documentation/linux/reliability/logging/email-notification.xml

/etc/snort/snort.conf - configure snort to log to syslog
------------------------------------------------------------
# syslog
output alert_syslog: LOG_LOCAL6 LOG_ALERT


/etc/syslog/syslog-ng.conf  - setup filters/destinations for alerts
------------------------------------------------------------
# snort filter - this only pays attention to syslog messages sent by the 'snort' program
filter f_snort
{
  facility(local6) and match("snort" value ("PROGRAM"));                                                
};

# optionally, this would send the snort message to a remote host running a syslog listener.
# I was running tcpdump to debug the whole setup so I use UDP protocol here so the
# message is just blasted out over the ether without needing to actually have a syslog
# listener setup anywhere
destination d_net
{
  udp("10.10.10.1" port(514) log_fifo_size(1000) template(t_snort));   
};

# this one sends the syslog message consisting of priority,time_in_seconds,host and syslog meesage.
# 
destination d_prog
{
  program("/root/bin/snort_script" template("<$PRI>$UNIXTIME $HOST $MSGONLY\n") );
};

# ..or use a pipe if you don't want syslog running scripts
destination d_prog_pipe
{
  pipe("/root/bin/syslog-pipe" template("<$PRI>$DATE $HOST $MSGONLY\n") );
};

# finally, log the message out the snort parsing mechanism
log
{
   source(s_src);
   filter(f_snort);
   destination(d_prog);
   #destination(d_net); 
};



/root/bin/snort_script
------------------------------------------------------------
#!/bin/bash
while read line; do
   echo "$line" >> /tmp/snort.log
done
Server Fault
  • 3,454
  • 7
  • 48
  • 88