Install Snort_inline on your firewall to contain intrusions, or stop them as they’re happening.
Wouldn’t it be nice if your NIDS could not only detect intrusions, but also do something about them? It would be great if it could actually stop an intrusion occurring on the host that was being attacked, but the next best thing would be to block the network traffic propagating the attack. One tool that can do this for you is Snort_inline, which has been integrated into the main Snort source tree as of Snort 2.3.0.
Snort_inline allows Snort to read data from the Linux kernel’s Netfilter queue, which enables Snort to effectively integrate itself with the firewall. This allows it not only to detect intrusions, but also to decide whether to drop packets or to forward them to another host (using libnet). This, of course, requires that your kernel be compiled with IP queue support, either statically or as a module.
You can see if you have the module by running a command like this:
$ locate ip_queue.ko
/lib/modules/2.6.16/kernel/net/ipv4/netfilter/ip_queue.ko
In this case, the output shows that the module is available. If it isn’t, check to see whether the file /proc/net/ip_queue exists. If you can’t find the module, but that file exists, it means IP queue support is compiled into your kernel statically. If neither file exists, you’ll need to enable IP queue support in your kernel and recompile.
Snort_inline also requires libipq, a library that comes with Netfilter and is used by applications to communicate with Netfilter’s queue. You can check to see if it’s installed on your system by running this command:
$ locate libipq
/usr/include/libipq.h
/lib/libipq.a
If you don’t see output similar to this, chances are that you don’t have libipq installed. You can install it by downloading the iptables source from the Netfilter distribution site (http://www.netfilter.org
). For instructions on compiling it, refer to “Fool Remote Operating System Detection Software” [Hack #65]. After compilation is finished, run make
install-devel
, since libipq is not installed by default.
You might encounter an error that looks like this:
Extensions found: IPv4:dccp IPv4:recent IPv4:string IPv6:REJECT cc -O2 -Wall -Wunused -I/usr/src/kernels/2.6.14/include -Iinclude/ -DIPTABLES_VERSION=\"1.3.5\" -fPIC -o extensions/libipt_ah_sh.o -c extensions/libipt_ah.c In file included from /usr/src/kernels/2.6.14/include/linux/netfilter_ipv4.h:8, from /usr/src/kernels/2.6.14/include/linux/netfilter_ipv4/ip_tables.h:26, from include/libiptc/libiptc.h:6, from include/iptables.h:5, from extensions/libipt_ah.c:8: /usr/src/kernels/2.6.14/include/linux/config.h:6:2: error: #error including kernel header in userspace; use the glibc headers instead! make: *** [extensions/libipt_ah_sh.o] Error 1
If you do, you’ll need to edit the config.h file mentioned in the error message (e.g., /usr/src/kernels/2.6.14/include/linux/config.h in this example) and comment out the line that begins with #error
by adding two slashes at the start of the line.
In addition to IP queue support and the libipq package, you’ll need the
libnet packet injection library (http://www.packetfactory.net/projects/libnet/
). Simply download the source distribution, unpack it, run ./configure
&& make
, and then become root and run make install
.
Now that all the prerequisites are out of the way, you can compile Snort_inline. First, download and unpack the source distribution and change to the directory that is created. Then, run this command:
$ ./configure --enable-inline && make
You can use any options to configure that you’d normally use with Snort, since at its heart Snort_inline is still Snort.
Don’t be alarmed if your compile aborts with the following error:
gcc -DHAVE_CONFIG_H -I. -I. -I../.. -I../.. -I../../src -I../../src/sfutil -I/usr/include/pcap -I../../src/output-plugins -I../../src/detection-plugins -I../../src/preprocessors -I../../src/preprocessors/flow -I../../src/preprocessors/portscan -I../../src/preprocessors/flow/int-snort -I../../src/preprocessors/HttpInspect/include -I/usr/include -g -O2 -Wall -DGIDS -D_BSD_SOURCE -D__BSD_SOURCE -D__FAVOR_BSD -DHAVE_NET_ETHERNET_H -DLIBNET_LIL_ENDIAN -c spo_alert_fast.c In file included from /usr/include/linux/netfilter_ipv4/ip_queue.h:10, from /usr/local/include/libipq.h:37, from ../../src/inline.h:8, from ../../src/snort.h:36, from spo_alert_fast.c:51: /usr/include/linux/if.h:59: error: redefinition of'
struct ifmap'
/usr/include/linux/if.h:77: error: redefinition of'
struct ifreq'
/usr/include/linux/if.h:126: error: redefinition of'
struct ifconf'
spo_alert_fast.c: In function'
AlertFastInit'
: spo_alert_fast.c:124: warning: pointer targets in passing argument 1 of'
ParseAlertFastArgs'
differ in signedness make[3]: *** [spo_alert_fast.o] Error 1 make[3]: Leaving directory \Q/tmp/snort-2.4.4/src/output-plugins' make[2]: *** [all-recursive] Error 1 make[2]: Leaving directory \Q/tmp/snort-2.4.4/src' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory \Q/tmp/snort-2.4.4' make: *** [all] Error 2
This error is caused by the kernel headers in /usr/include/linux being out of sync with the headers of the kernel for which you’re building Netfilter. To fix this, create a symbolic link from the /include/linux directory in the kernel source tree to /usr/include/linux:
#cd /usr/include
#mv linux linux.orig
#ln -s /usr/src/kernels/2.6.14/include/linux .
You can then restart the compilation from where it left off by simply typing make
, or, if you’re paranoid, you can use this command to completely start over:
$ make clean && make
After compilation has finished, become root and type make install
.
You can now configure Snort_inline just as you would configure Snort regularly [Hack #106]. However, it’s recommended that you run a separate instance of Snort if you want alerting and use Snort_inline solely for setting firewall rules.
In addition to modifying Snort to capture packets from Netfilter rather than libpcap, the Snort_inline patch adds three new rule types—drop
, sdrop
, and reject
—as well as a new rule option. The drop
rule type drops the packet that triggered the rule without notifying the sending host, much like the iptables
DROP
target, and logs that it has done so. The sdrop
rule type is similar, except that it drops the packet silently, with no log entry to inform you. Using the reject
rule type blocks the offending packet but notifies the sending host with either a TCP RST or an ICMP port unreachable message, depending on whether the packet that triggered the rule used the TCP or UDP protocol, respectively.
The new rule option added by Snort_inline allows you to replace arbitrary content within a packet with whatever you choose. The only restriction is that the replacement byte stream must be the same length as the original. This is implemented with the replace
rule option, which is used in conjunction with the content
rule option to select what is to be replaced.
To run Snort_inline, start it just as you would start Snort. If you want to use it in inline mode, though, use its -Q
command-line switch, which tells Snort_inline to use IP queues rather than libpcap to gather packets. In this case, you’ll also need to configure the kernel to send the packets to the IP queues before starting Snort_inline. This is done with the iptables
command:
#iptables -F
#iptables -A INPUT -j QUEUE
#iptables -A OUTPUT -j QUEUE
#iptables -A FORWARD -j QUEUE
This pushes all traffic going in, out, and through the machine into an IP queue from which Snort_inline will read its packets. You can then start snort
(just don’t forget to use the -Q
option):
# snort -Qvc /etc/snort/snort_inline.conf
If you’re using a version that isn’t from Snort.org, substitute snort_inline
for snort
.
If you’re administering the machine remotely, you’ll probably want to start snort
before enabling the QUEUE
targets, since it’s snort
that will actually pass the packets back and forth. Otherwise, your remote logins will be dropped as soon as you put the iptables
rules in place. To be extra cautious, have your QUEUE
target rules ignore packets coming from a certain IP address or range of addresses.