Suricata custom rule alerts but won't block
-
-
You need to be sure the relevant variables are properly populated for your servers. In this case, that means your SMTP server. The package just uses defaults for all variables that resolve to be the same as HOME_NET. HOME_NET is the sum total of all the protected networks, so that means every single subnet defined on your firewall interfaces, plus the WAN IP, the default gateway, configured DNS servers, Virtual IPs and VPN addresses.
If you want a more restrictive setup, then create a firewall alias containing your mail server and then assign that alias to SMTP_SERVERS on the VARIABLES tab, save the change and then restart Suricata on the interface so it will pick up the change.
You also need to be sure that you are not duplicating a rule SID. You can't have two SIDs the same, and I don't think Suricata will warn you about that in the current version.
-
The fact your bottom rule works tells you that blocking is working fine. You have a rule content issue and/or a pass list content issue. It might be time for you to do a packet capture to see what is actually going back and forth on the wire.
Blocking is totally unaware of the content of a rule. It simply looks at the IP addresses in the packet, and if the IP address is not on a pass list (or covered by the default pass list), then it is blocked.
-
@bmeeks I don't understand what you mean by populating variables.
Would being configured wrong cause it to still alert but not block?
-
@RedDelPaPa said in Suricata custom rule alerts but won't block:
@bmeeks I don't understand what you mean by populating variables.
Would being configured wrong cause it to still alert but not block?
No, it won't impact blocking or not blocking. It can impact when the rule triggers, though. The default value for SMTP_SERVERS would be a ton of network space defined on your firewall.
You appear to have a case where traffic you think should get a block is actually covered in the pass list defined for the interface. If you have not changed the pass list from the value of "default", then I'm telling you that pass list is rather large as it will encompass all the locally-attached networks plus VPNs. It might be that during your testing responses that you think would be your client's public IP might actually be showing up to Suricata as being wrapped with a locally-attached network (the VPN tunnel, for example). That's why you might want to capture the traffic to examine the IP headers.
The default pass list is more than just individual IP addresses. It includes entire subnets as defined on the pfSense local interfaces.
-
@bmeeks But I told you that the rule that doesn't work alerts, and writes to the log. But it won't block.
As stated earlier, VPN is down and disabled for testing.
The suricata log file logs his public IP when it alerts. It just won't block it.
-
@RedDelPaPa said in Suricata custom rule alerts but won't block:
@bmeeks But I told you that the rule that doesn't work alerts, and writes to the log. But it won't block.
As stated earlier, VPN is down and disabled for testing.
The suricata log file logs his public IP when it alerts. It just won't block it.
Okay. I'm looking at something now in the custom blocking plugin source code that might be at play. If you want to help troubleshoot, do these steps:
Use the rule that you said is alerting but not blocking, and try it using two different settings for "Which IP to Block" on the INTERFACE SETTINGS tab. Each time you change this parameter, you will need to restart Suricata on the interface so it picks up the change.
Change that option to block just the DST IP address (change the setting from BOTH to DST). Save the change and restart Suricata. Then test your rule. It should alert and block the remote client (the one with the public IP of your customer).
If the above test works, that validates what I think I see in the source code of the blocking module.
-
@bmeeks One more question for you if you don't mind that's off topic.
How does the suppress list work? Obviously if I click suppress and add IP in the log, it will suppress and whitelist that IP to do whatever activity that IP was doing. But If I just click suppress, say, I get a ton of different IP's attacking voip and SIP which I don't use. If I just click to suppress that action without adding the IP, will suricata continue to block that activity without logging it?
-
do you think that if one ip is on the passlist and the "Which IP to Block" is set to both it will ignore both ip instead of only the one in the passlist?
-
@bmeeks Ok! I will test that out for you later today when my client has gone home for the day. Right now, he and his staff are using their workstations.
-
@RedDelPaPa
Suppress Lists prevent an alert from firing. There are several conditions available, but the only ones available in the GUI are to suppress by SRC IP, suppress by DST IP or suppress by GID:SID. If you manually edit a Suppress List, you can add other thresholding options using many of the same techniques available for thresholding available in rules.Suppressing an alert means to ignore that alert from now on. That will also prevent future blocks from that alert. Suppressing an alert has the effect of letting that traffic through the firewall.
-
@bmeeks Oh I see. Thank you.
Is there a way I can set surricata to not log certain alerts, but to continue blocking them? I really need to clear out all the SIP stuff so I can watch for more important things.
-
@kiokoman said in Suricata custom rule alerts but won't block:
do you think that if one ip is on the passlist and the "Which IP to Block" is set to both it will ignore both ip instead of only the one in the passlist?
No, but it is possible (but unlikely) that if the Source IP is on a Pass List the code could erroneously assume the Destination IP is also on the list.
-
@RedDelPaPa said in Suricata custom rule alerts but won't block:
@bmeeks Oh I see. Thank you.
Is there a way I can set surricata to not log certain alerts, but to continue blocking them? I really need to clear out all the SIP stuff so I can watch for more important things.
No. It is not possible to suppress alert logging but still block. The blocking plugin actually works off receiving the alerts, so without getting the alerts the blocking plugin will see nothing to block (as it won't see alerts from that rule or host).
-
@bmeeks Ack. Thank you.
I will get back to you later with the results of that test you requested.
-
@bmeeks Ok guess what?
I ran your test with my original rule:
alert tcp $SMTP_SERVERS 25 -> $EXTERNAL_NET any (msg:"Custom SMTP AUTH LOGON brute force attempt"; flow:from_server,established; content:"Authentication failed"; offset:54; nocase; threshold:type threshold, track by_dst, count 3, seconds 60; classtype:suspicious-login; sid:1000001; rev:3;)
Changing the "which IP to block" to DST from BOTH, and restarting suricata, now alerts and blocks as it should.
Changing "which IP to block" back to BOTH from DST, restarting suricata and running the same test again with the same rule alerts but will not block.
What does this mean?
-
@RedDelPaPa said in Suricata custom rule alerts but won't block:
@bmeeks Ok guess what?
I ran your test with my original rule:
alert tcp $SMTP_SERVERS 25 -> $EXTERNAL_NET any (msg:"Custom SMTP AUTH LOGON brute force attempt"; flow:from_server,established; content:"Authentication failed"; offset:54; nocase; threshold:type threshold, track by_dst, count 3, seconds 60; classtype:suspicious-login; sid:1000001; rev:3;)
Changing the "which IP to block" to DST from BOTH, and restarting suricata, now alerts and blocks as it should.
Changing "which IP to block" back to BOTH from DST, restarting suricata and running the same test again with the same rule alerts but will not block.
What does this mean?
Thank you for the test results feedback. That gives me a valuable clue about processing flow in the custom plugin I wrote. I think I know how to fix the issue in the source code, but I'm not sure why the fix is needed. It's a sort of long explanation, but the short version is a variable is passed to another built-in Suricata function to search a list of IP addresses in order to determine if a given IP is present in the list. So essentially this is searching the Pass List for one of the IP addresses from the current alerting packet. When BOTH is selected for the "Which IP to Block" parameter, two consecutive calls are made to this function. One with the SRC IP and then another following with the DST IP. The variable passed that indicates if the IP was found or not is supposedly reset by the built-in Suricata function each time. But your results indicate that perhaps it is not always getting reset. Very weird.
Nonetheless, I will make the change in the C source code of my custom blocking plugin. It will take at least a couple of days to get it posted and for the pfSense developer team to merge the change into the package repositories.
TL;DR; section for programming geeks --
When the "Which IP to Block" parameter is set to BOTH, two consecutive calls are made to the built-in Suricata function SCRadixFindKeyBestMatchIPv4() for IPv4 addresses or SCRadixFindKeyBestMatchIPv6() for IPv6 addresses. With each call to this function, a pointer variable is passed that will be set to NULL if the IP passed is not present in the Radix Tree. If the IP is present in the tree, the variable will be filled with a pointer to the user data associated with that IP entry. In the custom blocking module used by Suricata, when the BOTH mode is enabled, the first call to the Radix Tree search function is made using the SRC IP from the alerting packet. If the SRC IP is not found in the Radix Tree (which is actually the pass list), then the SRC IP is blocked. Next, a call is made to the same function to search the Radix Tree for the DST IP. What is happening, and I can't really explain why yet, is that variable that is supposed to be set to NULL when an IP is not in the list is actually retaining the old value from the first SRC IP search. Thus the code mistakenly thinks the DST IP is on the pass list whenever the SRC IP is on the list.
So applying the described logic to your rule above, it's working this way. When set to BOTH, the first call to the Radix Tree search is done with the SRC IP from the offending packet. In your rule, the SRC IP will be your mail server. Your mail server is on your local network and thus its IP address will automatically be in the default pass list. So the Radix Tree search finds that the IP address of your mail server (the SRC IP in your rule) is covered by the pass list so it does not block that IP. Next, the code makes another call to the Radix Tree search function but this time with the DST IP from the alert (in your rule, that would be $EXTERNAL_NET). But now, due to the bug described above, the search function returns a value indicating that the $EXTERNAL_NET IP is also in the pass list when in reality it is not. Thus the $EXTERNAL_NET IP is not blocked.
By switching the "Which IP to Block" mode over to DST only, that results in only a single call being made to the SCRadixFindKeyBestMatchIPv()* function. The function then correctly determines the IP is not in the pass list and thus it is blocked.
-
@bmeeks Glad I could be of some help, Bill! How will I know when the fix is ready for download?
-
@RedDelPaPa said in Suricata custom rule alerts but won't block:
@bmeeks Glad I could be of some help, Bill! How will I know when the fix is ready for download?
A new package version will appear in the Package Manager section under SYSTEM > PACKAGE MANAGER.
-
@bmeeks Ack, thank you.