Configuring Snort with Data Acquisition Module for Intrusion Prevention System (IPS) Mode

       Snort is commonly used as an Intrusion Detection System (IDS) and can be further configured as an Intrusion Prevention System (IPS). Snort uses a Data Acquisition (DAQ) module to monitor the firewall packet queue, leveraging Snort rules with actions such as `drop` and `alert` to process packets. Once Snort is started, the firewall adds a linked queue. When packets pass through the firewall, they are handed over to Snort for processing. If an intrusion detection rule is triggered, Snort immediately responds by blocking the packet. Ideally, an IPS should be directly connected to the network environment and configured as a bridge. Snort’s bridge monitoring functionality requires the firewall to support bridging, which can also be configured in a transparent mode. This post provides a simple attempt at configuring Snort in IPS mode on a single machine to block packets that trigger rules and access the machine. Below are the configuration and testing steps.

1. Preparing the Environment

      1.1. System and Software Versions

           Environment: Ubuntu 15.10 + Snort 2.9.8.0 + DAQ 2.0.4 (Note: Since Snort’s IDS mode was already installed, Snort and DAQ were recompiled and installed.)

      1.2. Dependencies

           To configure Snort in IPS mode, the DAQ module must support the NFQ mode. Install the required dependencies: `netfilter_queue`, `libnfnetlink`, and `libmnl`. Download, extract, compile, and install the corresponding source packages. Alternatively, you can try installing them via package managers, but this example uses source compilation. Additionally, install the development packages for these dependencies, as DAQ compilation requires them. Finally, download, extract, and compile the `libdnet` source package.

2. System Installation Process

      2.1. Data Acquisition (DAQ)

           Configure the DAQ module to support NFQ mode by running the following command:

      liang@ubuntu:~/snort/daq$ sudo ./configure

           If the following output is displayed, the configuration is successful. Otherwise, recheck the dependency installation steps. Note that the NFQ DAQ mode is enabled (`yes`).           

      Build AFPacket DAQ module.. : yes
     Build Dump DAQ module...... : yes
     Build IPFW DAQ module...... : yes
     Build IPQ DAQ module....... : no
     Build NFQ DAQ module....... : yes
     Build PCAP DAQ module...... : yes
     Build netmap DAQ module...... : no

           Compile and link DAQ by running:           

      liang@ubuntu:~/snort/daq$ sudo make

           Install DAQ with the following command:

      liang@ubuntu:~/snort/daq$ sudo make install

            To check the DAQ functionalities supported by Snort, run:

       liang@ubuntu:~/snort_ips/libdnet-1.11$ snort --daq-list

             If NFQ is not listed, recompile the IDS system:

       Available DAQ modules:
      pcap(v3): readback live multi unpriv
      ipfw(v3): live inline multi unpriv
      dump(v2): readback live inline multi unpriv
      afpacket(v5): live inline multi unpriv

      2.2. Intrusion Detection Snort

            Compile and install Snort with the following commands:

       liang@ubuntu:~/snort/snort$ sudo make clean
      liang@ubuntu:~/snort/snort$ sudo ./configure
      liang@ubuntu:~/snort/snort$ sudo make
      liang@ubuntu:~/snort/snort$ sudo make install

             Check the DAQ functionalities supported by Snort again:

       liang@ubuntu:~/snort/snort$ sudo snort --daq-list

             NFQ mode should now be supported, and you can proceed with IPS mode configuration and testing:

       Available DAQ modules:
      pcap(v3): readback live multi unpriv
      nfq(v7): live inline multi
      ipfw(v3): live inline multi unpriv
      dump(v2): readback live inline multi unpriv
      afpacket(v5): live inline multi unpriv

3. Simple Rule Design

      3.1. Adding Two `drop` Rules

       drop tcp any any ->  192.168.213.170 80 (msg:"Drop http:80";sid:26287)
      drop icmp any any ->  192.168.213.170 any (msg:"Drop ping";sid:8886288)

      3.2. `drop` and `alert` Together

       alert icmp any any ->  192.168.213.170 any (msg:"ICMP PING";sid:8886288)
      drop tcp any any ->  192.168.213.170 80 (msg:"Drop http:80";sid:26287)

      3.3. Only `drop` Rules

       drop tcp any any ->  192.168.213.170 80 (msg:"Drop http:80";sid:26287)

4. Snort and iptables Integration

      4.1. Overview

              Start Snort first, then add firewall rules. You can use shell scripts or C programs to monitor Snort’s successful startup and add firewall rules. The firewall rules can be saved in a file and applied using `iptables` commands. Snort can only use one queue, but multiple rules can be added to the same queue in the firewall.

      4.2. Starting Snort

             Start Snort with the following command:

       sudo snort -Q --daq nfq --daq-var device=eth0 --daq-var queue=1 -c /etc/snort/etc/snort.conf

      4.3. iptables Queue

             Configure the firewall queue with the following commands:

       sudo /usr/sbin/iptables -t nat -I PREROUTING -j NFQUEUE --queue-num 1
      sudo /usr/sbin/iptables -I FORWARD -j NFQUEUE --queue-num 1
      sudo /usr/sbin/iptables -t input -I PREROUTING -j NFQUEUE --queue-num 1

             Check the firewall filter table rules:

       liang@ubuntu:~$ sudo iptables -nL

             The output should look like this:

       Chain INPUT (policy ACCEPT)
      target     prot opt source               destination         
      NFQUEUE    all  --  0.0.0.0/0            0.0.0.0/0            NFQUEUE num 1

      Chain FORWARD (policy ACCEPT)
      target     prot opt source               destination         
      NFQUEUE    all  --  0.0.0.0/0            0.0.0.0/0            NFQUEUE num 1

      Chain OUTPUT (policy ACCEPT)
      target     prot opt source               destination 

             Check the firewall NAT table rules:

       liang@ubuntu:~$ sudo iptables -t nat -nL

             The output should look like this:

       Chain PREROUTING (policy ACCEPT)
      target     prot opt source               destination         
      NFQUEUE    all  --  0.0.0.0/0            0.0.0.0/0            NFQUEUE num 1


      Chain INPUT (policy ACCEPT)
      target     prot opt source               destination         


      Chain OUTPUT (policy ACCEPT)
      target     prot opt source               destination         


      Chain POSTROUTING (policy ACCEPT)
      target     prot opt source               destination 

5. Testing

     5.1. Adding Two `drop` Rules

             Monitor the alert output file on the local machine:

       liang@ubuntu:~$ tail -f /var/log/snort/alert  

Another machine attempts to access the local machine’s port 80, and the output is as follows, with the attempt to access port 80 failing:

[] [1:26287:0] “Drop http:80” []
[Priority: 0]
03/28-18:15:37.362404 192.168.213.162:40640 -> 192.168.213.170:80
TCP TTL:64 TOS:0x0 ID:15682 IpLen:20 DgmLen:60 DF
S* Seq: 0x3DB5D5B Ack: 0x0 Win: 0x7210 TcpLen: 40
TCP Options (5) => MSS: 1460 SackOK TS: 16408601 0 NOP WS: 7

[] [1:26287:0] “Drop http:80” []
[Priority: 0]
03/28-18:15:37.595837 192.168.213.162:40642 -> 192.168.213.170:80
TCP TTL:64 TOS:0x0 ID:17709 IpLen:20 DgmLen:60 DF
S* Seq: 0x8619257E Ack: 0x0 Win: 0x7210 TcpLen: 40
TCP Options (5) => MSS: 1460 SackOK TS: 16408659 0 NOP WS: 7

[] [1:26287:0] “Drop http:80” []
[Priority: 0]
03/28-18:15:37.731718 192.168.213.162:40644 -> 192.168.213.170:80
TCP TTL:64 TOS:0x0 ID:6892 IpLen:20 DgmLen:60 DF
S* Seq: 0xA1C7A99 Ack: 0x0 Win: 0x7210 TcpLen: 40
TCP Options (5) => MSS: 1460 SackOK TS: 16408693 0 NOP WS: 7

[] [1:26287:0] “Drop http:80” []
[Priority: 0]
03/28-18:15:37.884915 192.168.213.162:40646 -> 192.168.213.170:80
TCP TTL:64 TOS:0x0 ID:42308 IpLen:20 DgmLen:60 DF
S* Seq: 0x495EC5DF Ack: 0x0 Win: 0x7210 TcpLen: 40
TCP Options (5) => MSS: 1460 SackOK TS: 16408731 0 NOP WS: 7

[] [1:26287:0] “Drop http:80” []
[Priority: 0]
03/28-18:15:38.082540 192.168.213.162:40648 -> 192.168.213.170:80
TCP TTL:64 TOS:0x0 ID:7605 IpLen:20 DgmLen:60 DF
S* Seq: 0xEF657D78 Ack: 0x0 Win: 0x7210 TcpLen: 40
TCP Options (5) => MSS: 1460 SackOK TS: 16408781 0 NOP WS: 7

[] [1:26287:0] “Drop http:80” []
[Priority: 0]
03/28-18:15:38.333060 192.168.213.162:40650 -> 192.168.213.170:80
TCP TTL:64 TOS:0x0 ID:61398 IpLen:20 DgmLen:60 DF
S* Seq: 0x64518EDD Ack: 0x0 Win: 0x7210 TcpLen: 40
TCP Options (5) => MSS: 1460 SackOK TS: 16408843 0 NOP WS: 7

Another machine pings the local host, and the output is as follows, with the ping failing:

[] [1:8886288:0] “Drop ping” []
[Priority: 0]
03/28-18:16:50.932352 192.168.213.162 -> 192.168.213.170
ICMP TTL:4 TOS:0x0 ID:36821 IpLen:20 DgmLen:84 DF
Type:8 Code:0 ID:41134 Seq:1 ECHO

[] [1:8886288:0] “Drop ping” []
[Priority: 0]
03/28-18:16:51.940781 192.168.213.162 -> 192.168.213.170
ICMP TTL:4 TOS:0x0 ID:36847 IpLen:20 DgmLen:84 DF
Type:8 Code:0 ID:41134 Seq:2 ECHO

[] [1:8886288:0] “Drop ping” []
[Priority: 0]
03/28-18:16:52.941954 192.168.213.162 -> 192.168.213.170
ICMP TTL:4 TOS:0x0 ID:37040 IpLen:20 DgmLen:84 DF
Type:8 Code:0 ID:41134 Seq:3 ECHO

[] [1:8886288:0] “Drop ping” []
[Priority: 0]
03/28-18:16:53.941261 192.168.213.162 -> 192.168.213.170
ICMP TTL:4 TOS:0x0 ID:37191 IpLen:20 DgmLen:84 DF
Type:8 Code:0 ID:41134 Seq:4 ECHO

[] [1:8886288:0] “Drop ping” []
[Priority: 0]
03/28-18:16:54.941031 192.168.213.162 -> 192.168.213.170
ICMP TTL:4 TOS:0x0 ID:37319 IpLen:20 DgmLen:84 DF
Type:8 Code:0 ID:41134 Seq:5 ECHO

[] [1:8886288:0] “Drop ping” []
[Priority: 0]
03/28-18:16:55.941207 192.168.213.162 -> 192.168.213.170
ICMP TTL:4 TOS:0x0 ID:37535 IpLen:20 DgmLen:84 DF
Type:8 Code:0 ID:41134 Seq:6 ECHO

[] [1:8886288:0] “Drop ping” []
[Priority: 0]
03/28-18:16:56.941222 192.168.213.162 -> 192.168.213.170
ICMP TTL:4 TOS:0x0 ID:37771 IpLen:20 DgmLen:84 DF
Type:8 Code:0 ID:41134 Seq:7 ECHO

Checking the Snort terminal output, it shows that 29 packets were blocked, and the above output confirms that Snort IPS mode is effective:

Commencing packet processing (pid=3466)
Decoding Raw IP4
^C Caught Int-Signal
===============================================================================
Run time for packet processing was 261.437100 seconds
Snort processed 763 packets.
Snort ran for 0 days 0 hours 4 minutes 21 seconds
Pkts/min: 190
Pkts/sec: 2
===============================================================================
Memory usage summary:
Total non-mmapped bytes (arena): 274706432
Bytes in mapped regions (hblkhd): 21590016
Total allocated space (uordblks): 102918272
Total free space (fordblks): 171788160
Topmost releasable block (keepcost): 59472
===============================================================================
Packet I/O Totals:
Received: 763
Analyzed: 763 (100.000%)
Dropped: 0 ( 0.000%)
Filtered: 0 ( 0.000%)
Outstanding: 0 ( 0.000%)
Injected: 29
===============================================================================

5.2 Drop and Alert Together

Since the rule `alert icmp any any -> 192.168.213.170 any (msg:”ICMP PING”;sid:8886288)` is configured, the ping operation can be completed, but it is logged as an alert. This resembles an intrusion detection mode, but the blocked port 80 is still inaccessible and is logged in the alert log. Additionally, the Snort terminal also prints information about the blocked packets.

5.3 Only Drop Rule Exists

In this case, the ping operation can be completed without being logged. However, accessing port 80 still results in the same situation as above, proving that Snort IPS mode is successfully configured and the packet blocking functionality is performed according to Snort rules.