Netgate SG-1000 microFirewall

Author Topic: About Pass Lists in Suricata  (Read 759 times)

0 Members and 1 Guest are viewing this topic.

Offline bmeeks

  • Hero Member
  • *****
  • Posts: 3159
  • Karma: +818/-0
    • View Profile
About Pass Lists in Suricata
« on: August 17, 2017, 08:09:30 am »
There seem to always be some questions and/or misconceptions about how Pass Lists work in Suricata.  That's especially true now that Suricata offers two quite different IPS modes:  (1) Legacy Mode and (2) Inline IPS.

Quick Review of Legacy vs Inline IPS Modes
Legacy Mode operation uses a custom output module I wrote that gets patched into the Suricata binary when the package is built for pfSense.  The custom module is called alert-pf.  Suricata Legacy Mode on pfSense uses the libpcap library to capture network packets as they traverse the firewall.  Those copied packets are analyzed by Suricata to determine if alerts should be generated.  The alert-pf module gets a copy of every alert event generated by the Suricata engine.  It pulls the IP addresses from the alert event and makes a FreeBSD system call to insert them into a packet filter (pf) firewall table called "snort2c".  That table is created at boot-up by the pfSense code.  It always exists on a pfSense firewall whether Suricata and Snort are installed or not.  IP addresses placed in that pf table are blocked by the firewall.  Removing an IP address from that table clears the "block".  Because the Legacy Mode process is using copies of the packets to make decisions, there is some leakage of data through the firewall before a block/no-block decision is made.

The new Inline IPS mode solves the leakage problem by making use of a new ability within FreeBSD called Netmap.  Netmap is a mechanism allowing very high-speed processing of network packets.  It basically creates an intercept point between the network hardware driver and the FreeBSD kernel.  Packets going to and from the network driver must pass through the Netmap conduit.  In order for this conduit to work properly, there must be support within the network driver.  Thus Netmap does not work for just any network card.  It depends on some driver implementation support.  If that support is missing or incomplete, then Netmap will either not work at all, or will work in an extremely buggy manner all the way up to crashing the kernel.  Netmap support within Suricata itself is provided from upstream (meaning it comes baked into the binary source code already).  No patching of any kind is done on the pfSense side in order to implement Netmap in Suricata.  It is just enabled at compile time.  This is different from the Legacy Mode custom blocking module mentioned earier.

Pass List Operation
A pass list is just another term for "whitelist".  I chose Pass List so as not to get things confused with the whitelisting function within the Snort IP Reputation preprocessor.  A pass list is simply a collection of IP addresses that are never to be blocked.  The IP addresses can be for individual hosts, or entire CIDR blocks can be defined using the standard syntax supported by the underlying IDS/IPS engine (either Suricata or Snort).  This next sentence is important!  Only Legacy Mode blocking operation supports a true Pass List.  This is because Legacy Mode uses the custom plugin I created, and that plugin understands what a pass list is for and how to use it.  It consults the pass list right before inserting an IP address in that "snort2c" table mentioned above.  If the IP is on the pass list, then it is not put in the table and thus no block happens.

A pass list only works with static IP addresses.  Go back and read that sentence again -- only static IP addresses work in a pass list.  FQDN Aliases or any other kind of dynamic IP address is not suitable for a pass list.  That's because the list is static in memory once created, and it's only created at startup of Suricata.  So it can't know when a host in the pass list gets a new address.  It won't follow FQDN aliases that auto-update.  I've been looking at some options to maybe work with FQDN aliases in a pass list, but there is a fine line to tread before performance of the blocking plugin degrades and packet processing speed would drop.

Pass lists are not supported when Inline IPS mode is enabled because that mode uses the built-in Netmap functionality of Suricata, and the native Netmap code is not patched to recognize and work with pass lists.  So that's why they don't work using Inline IPS mode.  Making them work with Inline IPS mode would require yet more custom patches be created and applied to Suricata when built for pfSense.  We are trying to get away from that kind of customization because it naturally makes keeping in sync with upstream releases more difficult.  There have been several occasions where upstream releases have broken the patch for the Legacy Mode plugin, and time has to be allocated and spent to recode the patch to work with newer Suricata versions.

To mimic Pass List functionality when using Inline IPS mode, you should create custom PASS rules.  These are rules that have PASS as the action keyword instead of ALERT or DROP.  The configuration of Suricata on pfSense ensures that PASS rules are always evaluated first, and the first matching rule wins (just as with the firewall rules).  Some examples can be found with a Google search or at the Suricata documentation Wiki site here:

     https://redmine.openinfosecfoundation.org/projects/suricata/wiki

Bill
« Last Edit: August 17, 2017, 01:32:59 pm by bmeeks »

Offline dcol

  • Full Member
  • ***
  • Posts: 193
  • Karma: +7/-5
    • View Profile
Re: About Pass Lists in Suricata
« Reply #1 on: October 02, 2017, 10:15:55 am »
Great post, thanks. Using Inline Suricata 4.0.0_1. Works Great
Can you, or someone, please post an example of a pass rule that would always pass an IP in Inline mode.
I want to use it for my remote IP when I make changes to rules so I do not inadvertently block myself.

How about this example?
pass tcp 1.2.3.4 any -> any any (msg:"pass all traffic from/to 1.2.3.4"; sid:100000;)

Would this rule allow IP 1.2.3.4 to not ever be dropped by Suricata using Inline mode?
« Last Edit: October 02, 2017, 11:33:17 am by dcol »

Offline bmeeks

  • Hero Member
  • *****
  • Posts: 3159
  • Karma: +818/-0
    • View Profile
Re: About Pass Lists in Suricata
« Reply #2 on: October 02, 2017, 08:15:26 pm »
Great post, thanks. Using Inline Suricata 4.0.0_1. Works Great
Can you, or someone, please post an example of a pass rule that would always pass an IP in Inline mode.
I want to use it for my remote IP when I make changes to rules so I do not inadvertently block myself.

How about this example?
pass tcp 1.2.3.4 any -> any any (msg:"pass all traffic from/to 1.2.3.4"; sid:100000;)

Would this rule allow IP 1.2.3.4 to not ever be dropped by Suricata using Inline mode?

Yes, this would let traffic pass without blocking whenever the SOURCE IP was 1.2.3.4.  It would not prevent a block from happening if the IP 1.2.3.4 was the DESTINATION IP.  If you want to prevent IP 1.2.3.4 from getting blocked no matter the flow direction, use this rule instead:

Code: [Select]

pass ip 1.2.3.4 any <> any any (msg:"pass all traffic from/to 1.2.3.4"; sid:100000;)


Notice the direction symbol is "<>" which stands for "any" as opposed to "->" which signifies a specific direction (from 1.2.3.4 to any other IP).  So the version I posted using "<>" would mimic the old Legacy Mode Pass List operation whereby IP address 1.2.3.4 would never get blocked.