Snort Inline IPS Mode
Snort Package 4.0 Inline IPS Mode Configuration
IMPORTANT HARDWARE LIMITATION
The new Inline IPS Mode of Snort will only work on interfaces running on a supported network interface card (NIC). Only the following NIC families currently have netmap support in FreeBSD and hence pfSense: em, igb, ixgb, ixl, lem, re or cxgbe. If your NIC driver is not from one of these families, netmap and Inline IPS Mode is not going to work properly, if it works at all.
Introduction:
The Snort 4.0 package offers a new mode of operation called Inline IPS Mode. This mode operates quite differently from the original Legacy Mode blocking. To contrast the difference, let's briefly dive into the details of how Snort works on pfSense.
Snort on pfSense uses a custom output plugin to implement the Legacy Mode blocking. This custom plugin receives a copy of every single alert generated by a Snort rule. The custom blocking plugin extracts the IP addresses from the alerting packet and then, after screening them through a Pass List filter, will make a FreeBSD system call to place the offending IP addresses in a pf
(packet filter) table called snort2c. This table is created by pfSense at boot-up. A hidden firewall rule (hidden from the GUI but visible if you view the contents of the /tmp/rules.debug
file) then blocks any IP address entered into the snort2c table. That's how Legacy Mode blocking works. Any alert can generate a block. The downside of this approach is that the admin can't choose rules to just alert and other rules to block. It's either all block or all alert (blocking off).
The new Inline IPS Mode dispenses with the custom output plugin used by the Legacy Mode blocking. Instead, it uses the netmap module within the DAQ library to create a netmap pipe between a physical NIC driver and the pfSense operating system network stack. In this manner, all traffic flowing to and from the physical interface and the operating system must pass through Snort. Snort can then either allow the packet to pass, or it can drop it. A dropped packet is the same as "blocked". The major advantage offered by this new operating mode is the ability to now select which rules alert but don't block, and which rules alert and block. You do this by changing the rule's action from the default ALERT to either DROP or REJECT. DROP rules drop the packet without any indication to the sender. REJECT rules drop the packet but send either a RST (for TCP traffic) or a "Destination port unreachable" (for UDP or ICMP traffic) to the originating host.
Key and Important Difference Between Inline Mode and Legacy Mode:
With Legacy Mode blocking, once you enable "Block Offenders" there is nothing else to do. All alerts will generate blocks.
However, Inline IPS Mode is quite different! Because the default action of all rules from the rule vendors is ALERT, if you enable Inline IPS Mode but don't change the rule actions, you will get no blocks. You must change the action of rules you wish to block traffic to be either DROP or REJECT. Details on how to do that follow below.
Automatic SID Management and User Rule Overrides in the Snort and Suricata Packages
Both Snort and Suricata offer two similar ways to customize the rules utilized for inspecting traffic. You can use the CATEGORIES tab or the SID MGMT tab. Before diving off into the details, let's first review a few basic points.
General Information About the Rules
IDS (Intrusion Detection System) rules in both Snort and Suricata have two identification keys. The first one is called the Generator ID, or GID. The second one is called the Signature ID, or SID. The SID must be unique for every single rule. The GID, on the other hand, can be the same for many rules. GID is primarily used in Snort where the key value is used to indicate if a rule belongs to a particular preprocessor or if it is a general text rule. Snort has a few pre-defined GID values such as 116 for the decoder rules and 138 for the sensitive data rules. For the vast majority of rules, though, the GID is always "1". However, just to be sure we always identify the rule we want, it is customary to refer to rules by their GID:SID such as 138:4 (for a given sensitive data rule) or 1:21019 for a generic text rule. One key point to always remember, especially if you create your own custom rules, is that the SID must be unique! You cannot have duplicate SIDs with the same GID. So two rules with the GID:SID keys of 1:20119 and 1:20119 is illegal, but two rules can have the same SID so long as they have different GIDs (at least in Snort).
Several vendors maintain and publish collections of Snort and Suricata rules. The two most popular are Emerging Threats (a.ka. Proofpoint) and Snort (a.k.a Talos). These vendors publish a gzip archive containing thousands of rules organized into various categories. Similar rules are grouped into individual category files whose file name sort of indicates the purpose of the rules. For example, one Emerging Threats rule category is Emerging-DNS. They include a file called emerging-dns.rules in their gzip archive. This file includes a collection of IDS rules designed to detect known threats to DNS (domain name service) hosts.
A common misconception among IDS/IPS newbies is thinking all of the rules in a category file are enabled and used. That is not, in fact, true. Some of the rules within a category are what we call "default disabled". This means the rule vendor has "commented out" those rules so they are not used. Rules may be disabled by the vendor for several reasons, but the most likely is that the rule is prone to false positives in many environments. A false positive is what we call it when a rule triggers but the actual traffic that caused the trigger is not really malicious. There can be many reasons for this. That does not mean the rule is useless, it just means that it is designed to function under a very specific set of circumstances that only a few users might experience. Thus the rule vendor may elect to "default disable" that rule and let the admins of networks decide if they want to enable it or not depending on the unique configuration of their network. The prior mentioned emerging-dns.rules category is a great example of this. Nearly one-third of the rules in that category are default disabled by the vendor.
Enabing Rules in Snort and Suricata
There are three ways to enable rules and rule categories in the pfSense Snort and Suricata packages. The first is to use the CATEGORIES tab to select (by checking) the rule categories you want to use from the list extracted from the gzip rule archives you have enabled for download (Snort, Emerging Threats, etc.). Checking boxes on the CATEGORIES tab will add those categories to your list of rules. However, (and this is key!); it won't enable every rule in the category. It will only use the rules from the category that the vendor left enabled. Those "default disabled' rules we mentioned earlier won't be used in your rule set unless you take action on either the SID MGMT tab or utilize the User-Forced actions on the RULES tab to manually add them. If you subscribe to and enable the Snort rules for download, then you have the option of choosing a pre-defined IPS Policy on the CATEGORIES tab. This policy will automatically choose a set of rules from the entire Snort gzip archive collection. When you choose to use a Snort IPS Policy, the manual selection of Snort categories is disabled.
Another way to select rules or rule categories is by using the features on the SID MGMT tab of each IDS package. I won't go into the details of using SID MGMT here. There are example files pre-loaded on the tab. To see them, check the box to enable Automatic SID Management and they will be displayed along with the rest of the settings. You can select rules in SID MGMT by Category Name or by the individual GID:SID values.
The third way to select individual rules is by using the User-Forced Enable/Disable icons on the RULES tab. When a category is selected for viewing on that tab, the first icon on the left of each row of displayed rules will indicate the current "state" of that rule. It will be one of "default enabled", "default disabled", "user-forced enabled" or "user-forced disabled". Various icon shapes and colors are used to indicate the current rule state. A legend at the top of the rules display list describes the icons used. You can click on the icon to change the state of the rule to a user-forced value.
Who Has Precedance?
Snort and Suricata load your active rules using this process –
-
Load all default-enabled rules from the various categories selected on the CATEGORIES tab.
-
Add any rules found in additional categories enabled by name from the enablesid.conf configuration on the SID MGMT tab.
-
Process any IPS Policy rules defined by the policy selected on the CATEGORIES tab.
-
Remove any rules (or entire rules categories) from the list if the rule or category matches an entry in the disablesid.conf configuration on the SID MGMT tab.
-
Process any forced user overrides of rule states (these are the GID:SID values the user may have selected for force-enable or force-disable on the RULES tab).
-
Process and enable any rules required by Automatic Flowbit Resolution (when that feature is enabled)
-
Process any forced user overrides of rules states one more time in case Flowbit Resolution enabled something the user really wants disabled
-
Add any user-supplied Custom Rules (entered on the RULES tab under "Custom Rules") to the set of active rules
The complete list of active rules for the interface is then written to the Snort or Suricata interface subdirectory. Only enabled rules are written to the file. Writing the disabled rules would serve no useful purpose.
What Does "SID State Order" Mean on the SID MGMT Tab?
The SID State Order setting tells Snort or Suricata whether to process the enablesid.conf configuration or the disablesid.conf configuration first. With SID MGMT, the last match wins. So if you enable a rule in the enablesid.conf configuration and disable the same rule in the disablesid.conf configuration, then the rule will wind up disabled if your SID State Order is "enable/disable", but the same rule will wind up enabled if your SID State Order is "disable/enable". So it pays to think through carefully what you want to accomplish and choose the appropriate SID State Order to fit your goals.
https://forum.netgate.com/topic/119238/about-pass-lists-in-suricata
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
https://forum.netgate.com/topic/128270/important-info-about-passlists-with-suricata-inline-ips-mode
If you use Suricata and have a network card that fully supports Inline IPS Mode, then this notice is important to you so read on. If you use Legacy Mode blocking, then none of what is said below applies to you and you can skip it if you desire.
History of Passlists
The idea of passlists sprang from the old Legacy Mode Blocking used in Snort and later in Suricata when that package was created. Legacy Mode uses a custom plugin that runs within the Suricata binary. This plugin intercepts every ALERT triggered by the rules. The plugin extracts the IP addresses from the ALERT (source and destination) and then inserts one or both of them into the snort2c table that lives in the pf (packet filter) firewall engine in pfSense. Any IP address inserted into that pf table will be subsequently blocked by the firewall. So that is how Legacy Mode blocking really works. IP addresses extracted from ALERTS are put into that snort2c table and the pf firewall takes it from there. Some options were added to the Legacy Mode plugin that allow the user to specify which IP address from the alerting packet to block (SRC, DST or BOTH). Another requested feature was the abilty to exempt certain IP addresses from ever being blocked even if they triggered an ALERT. Thus was born the idea of the Passlist. The Passlist is simply a list of IP addresses or IP network subnets that should never be blocked. The Legacy Mode plugin consults this list of Passlist IP addresses before sending the IP from an alert packet over to the pf firewall's snort2c table. If the IP is on the Passlist, then it is not sent over to pf and thus is not blocked.
A passlist was needed in Legacy Mode because once an IP address gets into the snort2c table, all further traffic coming from or going to that IP address is blocked. This includes even non-malicious traffic. So "blocked" really means blocked until the address is physically removed from the snort2c table. This can be done by the user manually, by rebooting the firewall or by means of a cron task that periodically removes addresses from that table.
Why Inline IPS Mode Generally Negates the Need for a Passlist
Inline IPS Mode is a different animal when it comes to blocking traffic. It does not use the firewall at all. Instead, it creates a netmap pipe between the NIC driver and the pfSense kernel and pf firewall. You can visualize this as literally a pipeline that connects these two endpoints. All network traffic to and from the network interface must go through that pipe. Suricata sits in the middle of that pipe and acts like a gatekeeper. If a Suricata rule with the DROP action is triggered, the packet that triggered the rule is literally just dropped by Suricata and not passed on to the other end of the pipe. So assume a packet was coming from the NIC on the way to the kernel and pf firewall for processing and that packet triggered a Suricata DROP rule; then that packet is just ignored by Suricata and never forwarded on to the kernel and pf firewall for futher processing. However, if the packet triggers just an ALERT rule or no rule at all; then it is passed on to the kernel and pf firewall for futher processing.
One key point to note here is that this inspection and passing/dropping is done on a packet-by-packet basis. So since no IP address gets put into the firewall table, you don't have to worry about subsequent non-malicious traffic to or from the same IP host being blocked. This is an important point! Bad packets are dropped for an IP address, but good packets pass for that same IP address. Compare this to the old Legacy Mode where once an IP address was put into the snort2c table all traffic with that IP address in it was blocked (both malicious and non-malicious). So this difference in the way blocks are handled minimizes the need for a Passlist with Inline IPS Mode. In fact, in most instances, you should never need or want a Passlist with Inline IPS Mode.
Suricata 4.0.3 Inline IPS Mode and Default Automatic Passlists
Okay, this is the section where I admit making a mistake by allowing myself to be talked into including a default Passlist option when using Suricata Inline IPS Mode. I added that capability a while back (I think it was when 4.0.1 came out). Anyway, you have the option at the moment on the INTERFACE SETTINGS tab of choosing "none", "default" or any other user-created Passlist for the Passlist Setting on the interface when using Inline IPS Mode. The help text associated with the Passlist control recommends you choose "none", and so do I! Here's why. If you choose "default", then a potentially bad thing happens. Some PASS rules get automatically created that effectively whitelist your entire LAN. By "whitelist" I mean no alerts or drops from anything whose IP address is in your LAN or any other locally-attached firewall networks. And what's worse, this whitelist extends to traffic flow in both directions: (1) FROM a device on your LAN to elsewhere; and (2) from elsewhere TO a device on your LAN. This is not good as bad stuff can flow to/from your LAN hosts and other locally-attached firewall networks and Suricata won't care! This bad situation came courtesy of the existing default passlist code used for Legacy Mode operation.
Here are some examples of how the automatic default Passlist rules can be bad –
The current "default" passlist includes locally-attached networks if you select that option when creating a pass list (and it is checked by default). So assume your LAN is the subnet 192.168.1.0/24. So Suricata will create this pass rule for the default Passlist when the option to include locally-attached networks is checked:
pass ip 192.168.1.0/24 any <-> any any (msg: "Pass List Entry - allow all traffic to/from 192.168.1.0/24"; sid:1000006;
This rule says when the SRC or DST is an IP address in the 192.168.1.0/24 subnet, then let it pass with no inspection. Pass rules in Suricata mean just that – pass the traffic unconditionally with no further inspection. And pass rules are the very first rules the Suricata engine evaluates. So this default pass rule is bad (very bad actually). Some of the other automatic default passlist rules are more restrictive and specify only a single IP address instead of the whole subnet, but even then it still is generally not a good idea to totally whitelist most hosts.
So unless you are totally convinced you need a Passlist with Inline IPS Mode, go right now and set your PassList entry on the INTERFACE SETTINGS tab to "none", save the change and then restart Suricata. Choosing "none" turns off the automatic passlist. In the next Suricata GUI package update, the ability to assign and use a passlist will be removed from Inline IPS Mode operation to prevent users from inadvertently neutering their IPS when running Inline IPS Mode.
What If I Really Need a Passlist with Inline IPS Mode?
If you truly do need to whitelist a specific host for some reason (or perhaps more rarely an entire subnet), then you should probably create your own Custom Rules for this and forget about using a passlist. Custom rules allow you to be more specific. For example, you could specify an IP, a flow direction and even a port or port range to limit the traffic that bypasses normal Suricata inspection (remember that a passlist when using Inline IPS Mode means passlist addresses get evaluated by no rules; any host or network on the passlist bypasses all Suricata inspection). The very first test in the Suricata engine is to check if the SRC or DST addresses, ports and protocol match any PASS rules. If there is a match, the packet is passed on to the netmap pipe endpoint and bypasses all of the other Suricata rules.
So a rule like this is much more limited than the earlier rule:
pass ip 192.168.1.22/32 80 <- any any (msg: "Pass List Entry - allow all traffic to/from 192.168.1.22/32"; sid:1000006;
This rule only passes traffic where the destination is IP address 192.168.1.22 and the port is 80. Only traffic matching that specific criteria bypasses further Suricata inspection.
To create custom passlist rules like this, go to the RULES tab for the interface, choose CUSTOM RULES in the Category drop-down and then type in the rules you need. There are plenty of examples on the web. You can add restrictions by protocol, port and source or destination IP address. Just really think about what your rule is allowing when creating it. It's easy to bypass your Suricata protection with a Passlist! That's why I intend to remove that capability for Inline IPS Mode operation in the next update. Folks needing to whitelist a host or network can do so with custom PASS rules instead.
Realistically, about the only application I can imagine for a Passlist is if you are running a honeypot host and you actually want bad stuff to find its way to that host. In that situation, a passlist makes sense. For about any other case, it does not. So get ready to see Pass Lists disappear from Suricata in the next version when using Inline IPS Mode, and get prepared to use custom PASS rules instead if you really need passlist functionality.
============== End