Managing Alerts

Network Security Monitoring, as a practice, is not a solution you can plug into your network, make sure you see blinking lights and tell people you are “secure.” It requires active intervention from an analyst to qualify the quantity of information presented. One of those regular interventions is to ensure that you are tuning properly and proactively attempting to reach an acceptable level of signal to noise.

Alerting Engines & Severity

There are two alerting engines within Security Onion: Suricata and Playbook (Sigma). Though each engine uses its own severity level system, Security Onion converts that to a standardized alert severity:

event.severity: 4 ==> event.severity_label: critical

event.severity: 3 ==> event.severity_label: high

event.severity: 2 ==> event.severity_label: medium

event.severity: 1 ==> event.severity_label: low

All alerts are viewable in Alerts, Dashboards, Hunt, and Kibana.

NIDS Testing

The easiest way to test that our NIDS is working as expected might be to simply access from a machine that is being monitored by Security Onion. You can do so via the command line using curl:


Alternatively, you could also test for additional hits with a utility called tmNIDS, running the tool in interactive mode:

curl -sSL -o /tmp/tmNIDS && chmod +x /tmp/tmNIDS && /tmp/tmNIDS

If everything is working correctly, you should see a corresponding alert (GPL ATTACK_RESPONSE id check returned root) in Alerts, Dashboards, Hunt, or Kibana. If you do not see this alert, try checking to see if the rule is enabled in /opt/so/rules/nids/all.rules:

grep 2100498 /opt/so/rules/nids/all.rules

You can also test using so-test.

Identifying rule categories

Rulesets come with a large number of rules enabled (over 20,000 by default). You should only run the rules necessary for your environment, so you may want to disable entire categories of rules that don’t apply to you. Run the following command to get a listing of categories and the number of rules in each:

cut -d\" -f2 /opt/so/rules/nids/all.rules | grep -v "^$" | grep -v "^#" | awk '{print $1, $2}'|sort |uniq -c |sort -nr

So what’s next?

In tuning your sensor, you must first understand whether or not taking corrective actions on this signature will lower your overall security stance. For some alerts, your understanding of your own network and the business being transacted across it will be the deciding factor. For example, if you don’t care that users are accessing Facebook, then you can silence the policy-based signatures for Facebook access.

Another consideration is whether or not the traffic is being generated by a misconfigured piece of equipment. If it is, then the most expedient measure may be to resolve the misconfiguration and then reinvestigate tuning.

There are multiple ways to handle overly productive signatures and we’ll try to cover as many as we can without producing a full novel on the subject. After making one of the changes described below, your ruleset will need to be updated as shown in the Managing Rules section.

You can disable, modify, or threshold alerts by going to Administration –> Configuration –> idstools.


Disable the alert

You can disable an alert by going to Administration –> Configuration –> idstools –> sids –> disabled.

If you want to disable multiple alerts at one time, you can use regular expressions. For example, to disable all alerts that contain heartbleed:


Modify the alert

You can modify an alert by going to Administration –> Configuration –> idstools –> sids –> modify.

To include an escaped $ character in the regex pattern you’ll need to make sure it’s properly escaped. For example, if you want to modify SID 2009582 and change $EXTERNAL_NET to $HOME_NET:

2009582 "\\\$EXTERNAL_NET" "\$HOME_NET"

The first string is a regex pattern, while the second is just a raw value. You’ll need to ensure the first of the two properly escapes any characters that would be interpreted by regex. The second only needs the $ character escaped to prevent bash from treating that as a variable.

Rewrite the alert

In some cases, you may not want to use the modify option above, but instead create a copy of the rule and disable the original. You can add local rules as shown in the Adding Local Rules section. After pasting the rule, you may want to bump the SID into the 90,000,000 range and set the revision to 1. Then make any other changes to the rule. Now that we have a signature that will generate alerts a little more selectively, we need to disable the original SID as shown above.


Thresholds, rate filters, and suppressions allow you to make finer grained decisions about certain alerts without having to rewrite them. The most common is a suppression which allows you to suppress alerts by specifying the SID, whether you want to track by source/destination/either, and the IP address or subnet. This way, you can still have certain alerts enabled, but the situations in which they alert are limited. It’s important to note that with this functionality, care should be given to the thresholds being written to make sure they do not suppress legitimate alerts. You can learn more about Suricata thresholds at

You can manage threshold entries for Suricata by going to Administration –> Configuration –> suricata –> thresholding –> SIDS.


<signature id>:
  - threshold:
      gen_id: <generator id>
      type: <threshold | limit | both>
      track: <by_src | by_dst>
      count: <count>
      seconds: <seconds>
  - rate_filter:
      gen_id: <generator id>
      track: <by_src | by_dst | by_rule | by_both>
      count: <count>
      seconds: <seconds>
      new_action: <alert | pass>
      timeout: <seconds>
  - suppress:
      gen_id: <generator id>
      track: <by_src | by_dst | by_either>
      ip: <ip | subnet>

Please note that Suricata 6 has a 64-character limitation on the IP field in a threshold. You can read more about this at


For example, suppose you want to suppress SID 2013030 where the source IP address is in the subnet:

  - suppress:
      gen_id: 1
      track: by_src


idstools may seem like it is ignoring your disabled rules request if you try to disable a rule that has flowbits set.


For a quick primer on flowbits, see

For example, consider the following rules that reference the ET.MSSQL flowbit.

First rule:

alert tcp $HOME_NET any -> $EXTERNAL_NET !1433 (msg:"ET POLICY Outbound MSSQL Connection to Non-Standard Port - Likely Malware"; flow:to_server,established; content:"|12 01 00|"; depth:3; content:"|00 00 00 00 00 00 15 00 06 01 00 1b 00 01 02 00 1c 00|"; distance:1; within:18; content:"|03 00|"; distance:1; within:2; content:"|00 04 ff 08 00 01 55 00 00 00|"; distance:1; within:10; flowbits:set,ET.MSSQL; classtype:bad-unknown; sid:2013409; rev:3;)

Second rule:

alert tcp $HOME_NET any -> $EXTERNAL_NET 1433 (msg:"ET POLICY Outbound MSSQL Connection to Standard port (1433)"; flow:to_server,established; content:"|12 01 00|"; depth:3; content:"|00 00 00 00 00 00 15 00 06 01 00 1b 00 01 02 00 1c 00|"; distance:1; within:18; content:"|03 00|"; distance:1; within:2; content:"|00 04 ff 08 00 01 55 00 00 00|"; distance:1; within:10; flowbits:set,ET.MSSQL; classtype:bad-unknown; sid:2013410; rev:4;)

Third rule:

alert tcp $HOME_NET any -> $EXTERNAL_NET !1433 (msg:"ET TROJAN Bancos.DV MSSQL CnC Connection Outbound"; flow:to_server,established; flowbits:isset,ET.MSSQL; content:"|49 00 B4 00 4D 00 20 00 54 00 48 00 45 00 20 00 4D 00 41 00 53 00 54 00 45 00 52 00|"; classtype:trojan-activity; sid:2013411; rev:1;)

If you try to disable the first two rules without disabling the third rule (which has flowbits:isset,ET.MSSQL) the third rule could never fire due to one of the first two rules needing to fire first. idstools helpfully resolves all of your flowbit dependencies, and in this case, is “re-enabling” that rule for you on the fly. Disabling all three of those rules by adding the following to disablesid.conf has the obvious negative effect of disabling all three of the rules:


When you run sudo so-rule-update, watch the “Setting Flowbit State…” section and you can see that if you disable all three (or however many rules share that flowbit) that the “Enabled XX flowbits” line is decremented and all three rules should then be disabled in your all.rules.