Taming the beasts… aka suricata blueprint
-
UPDATE: I have updated my script pf IP Reputation Manager to v2.3.1
https://gist.github.com/BBcan17/67e8c456cb399fbe02ee
If anyone needs any help to install please let me know.
Your Feedback is always welcome.
-
@jflsakfja great write up! I have to agree with you; block everything and open up what is needed… To bad I don't do this on my box at home, well my lan is open but my other interfaces are not. So i'm half way there.
@BBcan177 Thank you so much for sharing. When jflsakfja mention the script the other day, I started to search everywhere (including github) but couldn't find it :-( I've been a big fan of pfBlocker but there are too many dups because of list overlap and it doesn't allow you to import other formats.. Maybe someday your script and pfBlocker can get married and have a honeymoon...
I'm using the script basically out of the box without making any major changes to it (Other then disabling the TOR EXIT lists, enabling 2 list from the MAILSERVER section and BadIPs.
Since pfIPRep creates and updates the following pf Tables:
IR_PRI1
IR_PRI2
IR_PRI3
IR_SEC1
IR_SEC2
IR_SEC3
IR_IB
IR_TOR
IR_MAIL
IR_CC
I use them for my URL Alias name. This way, pfSense doesn't create a new pf TableUrl Aliases:
I've created my floating rules like this:
Example of my Outbound Block rule:
Notice in the the description, I started it with the alias name.. This could be used for label matching within your USER: ruleset if needed.Example of my inbound Reject rule:
-
Thanks Cino, I'm glad that you are using the Script ;)
I suggest that you add "enable logging" on the Floating Rules so you can see what is getting Blocked.
I have also added your recommendations for the Widget. (pfIP_Reputation.widget.php)
The widget can be found in my Github GIST.
Copy and save that file in [ [b]/usr/local/www/widgets/widgets ]
From pfSense Status:Dashboard
Click the "+" Icon and add the new "pf_IP_Reputation" Widget"
You may also notice that there is also a "mastermatch" alias that can also be placed into the Floating Rules as a "MATCH" Rule. These are IP Ranges that are in the Safe Country List, but are repeat offending IP Ranges. This can help to indicate malicious behaviour.
-
Example of my Inbound Block rule:
…
Example of my Outbound Reject rule:FTFY :)
Other than that, everything looks good.
EDIT!!!! MISSED THE QUICK CHECKBOX. TICK THAT!A small update on the suricata rules. I'm delaying their release because I wanted to enable all the rules and work my way towards an FP free install, just like snort. The trouble is that I've had to do all the work I did over a few years, in a few weeks. The good news is that most disabled rules are the same on snort and suricata. The medium news is that I still haven't hit all the FPs :p.
I haven't made up my mind if I'll post on the topic recommendations to disable rules no longer needed, since they are handled by the custom rules mentioned previously. Maybe I'll add a small note to them that they can be disabled if using custom rules.
-
I have posted version 2.3.2 of pf IP Reputation Manager to my Gist.
https://gist.github.com/BBcan17/67e8c456cb399fbe02ee#file-pfiprepman_2-3-2
No recent changes to the pfiprep script. You can replace the pfiprepman script completely with this one.
I have also added some code to the pfSense php script /usr/local/www/diag_dns.php
ScreenShot http://imgur.com/L9GeYa2
This will allow you to click on a Blocked IP in the Firewall Log, and it will show you which Blocklists have the Blocked IP Listed. At the bottom are several Threat Sources that can be referenced as well. When 2.1.4 comes out, I will post a new Patch as there are some other changes being made in this file also.
I have created a "patch" that can be applied to pfSense v 2.1.3 (Haven't tested it on other versions, but should work?)
If you don't have the pfSense Package "System Patches", it is available in the pfSense System:Packages list under "System Patches"
Click the "+" Icon to add a new Patch
Enter a Description (diag_dns.php Patch)
In the Patch Contents Dialog Box - Copy/Paste from my Gist the contents of this
link below:https://gist.github.com/BBcan17/67e8c456cb399fbe02ee#file-diag_dns-php_patch
After you paste the patch, look for this line and change it to your pf folder location.
```
$query_list =grep {$hosttrim} /YOUR/BLOCKLIST/FOLDER/* | sed 's/^.*[a-zA-Z]\///'
;These changes need to be made also: Base Directory - **/usr/local/www/** Click **"Save"** Click **"Test"** Look at the top of the patch that it can be successfully added, then Click **"Apply"**
-
Here is a good example about why Reputation in a /24 network is important to monitor:
A recent DNS amplification attack caught by Snort.
The IP Range is listed by 5 different Blocklists, but none of them have that exact IP Range.
The Country code for 204.124.183.211 is in the US. I currently have my script set to not apply a /24 block to a repeated offender IP Range based in the US.
( See ScreenShot ) http://imgur.com/xkRXSFi
-
Suricata Disabled Rules
ALWAYS DISABLE RULES! SUPPRESSING HAS OTHER USES, HIDING KNOWN FALSE POSITIVES IS NOT ONE OF THEM!
What this list is
This list is the definitive guide on what rules should be edited/deleted upstream. Ideally the ET guys will come along and the next iteration of this list will be blank. Practically I've spent months trying to get certain rules deleted, with no success. An example:
2010228 ET POLICY Suspicious Microsoft Windows NT 6.1 User-Agent Detected <<< so WTF is windows 7 then??? DELETE UPSTREAMWindows 7 was (since RTM), is (currently publicly available versions) and always will be, 6.1. Yes it doesn't make sense. It's actually the bitter truth. Windows 7 IS Windows 6.1. Other than Microsoft's NSA ties, there is nothing suspicious about it. An OS used by the majority of PC users should not generate a "suspicious" alert when performing the initial updates after a clean install.
How to use this list
First of all head over to the interface's categories page. Go through the list and enable all categories NOT having "DO NOT USE!" in front of them. Leave the rest disabled. There are some suricata internal rules, that will not be shown on the categories page.After that, move over to the rules page. Select the first entry in the dropdown, and enable all rules. Then manually search for the IDs listed, and click the icon next to them. Open a second browser tab that shows the dashboard. Look at the CPU load. Back on the rules page, hit apply. Back to the dashboard, and wait for the CPU load to return to idle. When that's done, THEN move to the next category in the dropdown.
That's one way to do it. The other way is to enable all in a category,hit apply, and wait for the CPU to idle again, before moving to the next category. THERE ARE 2 EXCEPTIONS TO THIS (the following 2 rules MUST be disabled after hitting enable all, BEFORE HITTING APPLY!- decoder-events > 2200003 SURICATA IPv4 truncated packet
- emerging-policy > 2010815 ET POLICY Incoming Connection Attempt From Amazon EC2 Cloud
Rule 1 will generate a billion alerts per second (trust me on this) and rule 2 is (here's the first revelation of it on the entire internet) responsible for 500MB+ RAM usage. Disabling this rule makes sure that the suricata interface does not ran out of memory while trying to load its rules.
With our selected rules enabled, it's time to head over to the alerts tab. Refresh it after a couple of minutes and watch for rule IDs listed here. Click the icon next to them to force them to a manually disabled state (and never having to deal with them again). While disabling a rule, make sure to keep an eye out on your second tab (dashboard). Only remove a host from the blocked list (icon next to IP) AFTER the cpu returns to idle, otherwise you risk generating an alert again since the rule has not yet been unloaded.
Note to bmeeks: Pretty please bring back the old way of handling manually disabled rules. Manually disabling a rule from either the alerts tab or the rules page, should turn the rule into a manually disabled rule (pale yellow). Currently the rules page turns it into the rule's default state. This is NOT recommended when using this list. Having both setting to manually disabled, allows the list to be used as it was meant to be used. Enable all, then find the 10 that need to be disabled, disable them, and apply. Rinse, repeat.Explanations:DO NOT use the list without reading this!
DO NOT USE! = categories that should be disabled
xxxxxx (number) = rule's ID
text before <<< = rule's explanation
text after <<< = why the rule was disabledbefore xxxxxx = WILL ONLY BE FOUNT ON SOME CATEGORIES.Rules that generated false positives on a suricata production network. I go with the enable all, then manually disable based on the alerts route. These are rules that generated alerts, but the rest of the rules in that category (NO # in front) are known FPs, but have NOT yet generated an FP on the suricata install. Hope that makes sense.
and no # rules explained. BLUE rules are rules that generated FPs on suricata
decoder-events
2200029 SURICATA ICMPv6 unknown type <<< breaks IPv6 tunnels
2200079 SURICATA ICMPv6 invalid checksum <<< breaks sixxs's IPv6 tunnelemerging-chat
2001595 ET CHAT Skype VOIP Checking Version (Startup)
#2002157 ET CHAT Skype User-Agent detected <<< obvious
Hope that clears it up. Sorry for that, but I had to start from the snort topic's list and work my way forward, so I had to copy over the list and manually disable the alerts as they are generated. You are welcome!The Definitive Enabled Rules List
Getting a 500 internal error while trying to upload the list.Will try again (either edit this post, or a new post)The list cannot be uploaded either to this reply, or a new reply, due to a 500 error. Will see where I can paste it so that I can also edit it in the future, which should also help with keeping the thread clean.
List is here:
https://github.com/jflsakfja/suricata-rules/blob/master/list.txt -
Writing custom rules for deep packet inspection
Suricata's intended use is intercepting the packets as they are passing through the network, reassemble them (if needed), open them up and peek inside, looking for specific patterns, and deciding whether to alert or not (or drop, if running in IPS).We'll examine a specific example of a known spammer trying to send spam to our email server.
The logs show this:
2014-06-24T16:35:52+03:00 emailserver1 postfix/smtpd[4324]: NOQUEUE: reject: RCPT from unknown[192.168.1.1]: 554 5.7.1 Service unavailable; Client host [192.168.1.1] blocked using zen.spamhaus.org; http://www.spamhaus.org/query/bl?ip=192.168.1.1; from= example@example.comto= example2@example2.comproto=ESMTP helo=<[192.168.1.1]>The red part shows that the email was rejected because we have set up our email server so that it first checks if the sender is a known spammer, then decides whether to accept the email or not.
The blue part is the server's reply sent to the client (the spammer).Why not use the IP directly in an alias on pfsense? This is not the scope of this post. This post tries to show how to write custom rules based on what you are trying to detect.
Back on topic. We know so far that we are looking for a packet that is originating from our email server (port 25 since that is unencrypted), and could end up anywhere on the internet, containing a specific reply.
So far the rule is:
alert tcp $SMTP_SERVERS 25 -> $EXTERNAL_NET any
This will not get you far, since you detected ALL traffic originating from port 25, with no specific contents.Examining our reply sent back to the client we see that the easiest way to detect this specific traffic is to use the part in red shown below. This is the common part for all replies, and states the reason why the email was denied:
554 5.7.1 Service unavailable; Client host [192.168.1.1] blocked using zen.spamhaus.org; http://www.spamhaus.org/query/bl?ip=192.168.1.1Ok, now we know what we are looking for, but it's time for us to understand our alert.
Our chosen message will be:
Known SPAMMER
The classification for this alert will be bad-unknown (use http://manual.snort.org/node31.html#SECTION00446000000000000000 and choose the most appropriate classtype for your rule)
Our rule version (revision) will be 1
Our sid (signature ID) must be a high value so that it will not interfere with other rules. Each rule MUST have a unique ID! I recommend using a value in the 9mil range. In this rule we use 9900003 because we have other custom rules before it.Don't forget that we are only interested in established connections (actively communicating) and the traffic direction is from the server to the client.
Putting it all together gives us this:
alert tcp $SMTP_SERVERS 25 -> $EXTERNAL_NET any (msg:"Known SPAMMER"; flow:established,from_server; content:"blocked using"; classtype:bad-unknown; sid:9900003; rev:1;)An example of the alert generated:
2014-06-24T16:09:49+03:00 pfsense1 suricata[21435]: [1:9900003:1] Known SPAMMER [Classification: Potentially Bad Traffic] [Priority: 2] {TCP} 192.168.200.1:25 -> 192.168.1.1:63651Since our IP is not banned, suricata will try to ban both IPs (source+destination) (ALWAYS set it up like that) but ignore the source.
We have caught our first offender using suricata's deep packet inspection! :D
The spammer will return after 28 days (since his IP will be unbanned) and try to send another spam email. He will be blocked again for a further 28 days. 1 email per month is nothing compared to 1000 per day.
Taking apart the rule and finding flaws (if any)
The rule should only fire up on messages originating from our email servers. Good!
The rule cannot generate a false positive since the email WILL be rejected regardless by our email server. Good!
The rule shows a generic alert message. Good AND Bad!
The rule's alert message is good in the sense that it does not give too much information about the origin of the block (no list's name appears).This is the bad part. This also allows us to keep the alerts tab clean, since a known spammer is a known spammer regardless of where the intel is coming from. If an IP is listed on list ABC on one month, and list DEF on the next month, two alerts will be logged in the alerts tab. For now it's nothing. Detecting a portscan using my previously recommended rule would end up with a thousand alerts logged on the alerts tab for that IP (NOT if using a generic "Incoming connection to unused port" message). This is the good part!Congratulations. You have now finished your training and are part of the industry's elite in network security. You are one of the best in this field! Use the knowledge wisely./example2@example2.com/example@example.com
-
great work jflsakfja!
You may want to add decoder-events - 2200013 IPv6 truncated packet to the list for noise. My alert file is mostly this alert. What is strange, none of these show up in the GUI, only in the Alert file itself… Because there is no IP, i'm thinking the GUI doesn't display it. But that's for another thread after I confirm my findings.
06/25/2014-06:27:46.251740 [**] [1:2200013:1] SURICATA IPv6 truncated packet [**] [Classification: (null)] [Priority: 3] [**] [Raw pkt: 00 25 90 02 31 65 00 01 5C 33 54 41 86 DD 60 01 EA 40 05 B4 06 34 26 10 01 60 00 11 00 11 00 00 ] 06/25/2014-06:27:46.250371 [**] [1:2200013:1] SURICATA IPv6 truncated packet [**] [Classification: (null)] [Priority: 3] [**] [Raw pkt: 00 25 90 02 31 65 00 01 5C 33 54 41 86 DD 60 01 EA 40 05 B4 06 34 26 10 01 60 00 11 00 11 00 00 ] 06/25/2014-06:27:46.318718 [**] [1:2200013:1] SURICATA IPv6 truncated packet [**] [Classification: (null)] [Priority: 3] [**] [Raw pkt: 00 25 90 02 31 65 00 01 5C 33 54 41 86 DD 60 01 EA 40 05 B4 06 34 26 10 01 60 00 11 00 11 00 00 ] 06/25/2014-06:27:46.251489 [**] [1:2200013:1] SURICATA IPv6 truncated packet [**] [Classification: (null)] [Priority: 3] [**] [Raw pkt: 00 25 90 02 31 65 00 01 5C 33 54 41 86 DD 60 01 EA 40 05 B4 06 34 26 10 01 60 00 11 00 11 00 00 ] 06/25/2014-06:27:46.319106 [**] [1:2200013:1] SURICATA IPv6 truncated packet [**] [Classification: (null)] [Priority: 3] [**] [Raw pkt: 00 25 90 02 31 65 00 01 5C 33 54 41 86 DD 60 01 EA 40 05 B4 06 34 26 10 01 60 00 11 00 11 00 00 ] 06/25/2014-06:27:46.319352 [**] [1:2200013:1] SURICATA IPv6 truncated packet [**] [Classification: (null)] [Priority: 3] [**] [Raw pkt: 00 25 90 02 31 65 00 01 5C 33 54 41 86 DD 60 01 EA 40 05 B4 06 34 26 10 01 60 00 11 00 11 00 00 ] 06/25/2014-06:27:46.543947 [**] [1:2200013:1] SURICATA IPv6 truncated packet [**] [Classification: (null)] [Priority: 3] [**] [Raw pkt: 00 25 90 02 31 65 00 01 5C 33 54 41 86 DD 60 0A B8 B0 05 B4 06 34 26 10 01 60 00 11 00 11 00 00 ] 06/25/2014-06:27:46.319496 [**] [1:2200013:1] SURICATA IPv6 truncated packet [**] [Classification: (null)] [Priority: 3] [**] [Raw pkt: 00 25 90 02 31 65 00 01 5C 33 54 41 86 DD 60 01 EA 40 05 B4 06 34 26 10 01 60 00 11 00 11 00 00 ] 06/25/2014-06:27:46.543837 [**] [1:2200013:1] SURICATA IPv6 truncated packet [**] [Classification: (null)] [Priority: 3] [**] [Raw pkt: 00 25 90 02 31 65 00 01 5C 33 54 41 86 DD 60 0A B8 B0 05 B4 06 34 26 10 01 60 00 11 00 11 00 00 ] 06/25/2014-06:27:46.986163 [**] [1:2200013:1] SURICATA IPv6 truncated packet [**] [Classification: (null)] [Priority: 3] [**] [Raw pkt: 00 25 90 02 31 65 00 01 5C 33 54 41 86 DD 60 05 E7 64 05 B4 06 34 26 10 01 60 00 11 00 11 00 00 ] 06/25/2014-06:27:46.986289 [**] [1:2200013:1] SURICATA IPv6 truncated packet [**] [Classification: (null)] [Priority: 3] [**] [Raw pkt: 00 25 90 02 31 65 00 01 5C 33 54 41 86 DD 60 05 E7 64 05 B4 06 34 26 10 01 60 00 11 00 11 00 00 ]
-
Getting the suricata logs on a remote syslog, and I'm running IPv6 tunnels because my upstream provider has vowed not to support IPv6 until AFTER they are completely cut off from the Internet (it will be the last ISP on earth that moves to IPv6). It might be due to the fact that their "3rd level" support technicians have no clue what an IP (4 or 6) address looks like. This is the same company that has to pay a daily fine for "excessive profits".
I've not seen that alert so far, but I'll keep an eye out for it, thanks for pointing it out.
So far the list seems to have stabilized a LOT, and I'm thinking about clearing up the list (# and no # rules). What gets on my nerves is that although the list originates from the snort topic (which is almost a year old!) most of the rules are still there.
-
I'm wondering since i'm dual stack IPv4/IPv6(DHCP for both on the WAN), that is why i'm seeing this alert.. My ISP(TWC) doesn't officially support IPv6 but its enabled and working pretty well. Better then IPv4 traffic at times…
-
I also dual stack, but have not seen that alert yet. Same here, I get better speeds over the tunnel, than the native IPv4.
On a side note, I'm updating the list. Mostly cleaning it up, moving the DO NOT USE! categories to the top so it's easier to find them, removing the # and no # rules…a line added here, a line taken away there...deleting some rules, updating the counts. I said I'm rarely mistaken (mathematically proven by the world's top universities, and the possibility of me being mistaken comes out to 0.000000000001%) but ffs guys. 5 rules on top of a count that says 4 rules are disabled should be noticed by someone by now :D.
EDIT: Finished cleaning up. The list is now starting fresh for suricata (old rules coming over from snort that did not FP within a reasonable timeframe were removed), cleaned up and ready to go. Enjoy!
-
whitelists were renamed to passlists not long ago. That is a definite bug in the suricata package. please post a link pointing to that post, on the most recent version(ed?) topic on suricata or re-post the same thing there. I'm not the suricata package maintainer, bmeeks is ;D
bmeeks got a tunnel working a few days back, so IPv6 support for both packages should improve.
-
@jflsakfja:
I also dual stack, but have not seen that alert yet. Same here, I get better speeds over the tunnel, than the native IPv4.
On a side note, I'm updating the list. Mostly cleaning it up, moving the DO NOT USE! categories to the top so it's easier to find them, removing the # and no # rules…a line added here, a line taken away there...deleting some rules, updating the counts. I said I'm rarely mistaken (mathematically proven by the world's top universities, and the possibility of me being mistaken comes out to 0.000000000001%) but ffs guys. 5 rules on top of a count that says 4 rules are disabled should be noticed by someone by now :D.
EDIT: Finished cleaning up. The list is now starting fresh for suricata (old rules coming over from snort that did not FP within a reasonable timeframe were removed), cleaned up and ready to go. Enjoy!
You're dual stack and using a Tunnel? When I mean dual stack; I mean receiving IPv4 IPv6 addresses on the same WAN interface.. The alerts are on that interface… Once I get my stuff fine tune, i'm going to copy it over to LAN and see if there is a difference. I should had started with my LAN interface first but oh well...
I noticed the counts were wrong, figured your eyes were getting crossed or something from the long post :o Thanks again for a great thread!
@avink use this topic https://forum.pfsense.org/index.php?topic=73906.msg428032#msg428032 to report the issue
-
Statistics on suricata's system usage
While idling, the system is using about 2% CPU and 23% RAM (4GB,32bit so not all available).
Under normal load (not extreme "ZOMG! multiple 10Gbps duplex laser links into space!") the CPU occasionally spikes to <10% for a brief moment, and the RAM stays about the same.
While reloading rules (when hitting save on the rules page or disabling a rule from the alerts tab) the CPU spikes to 50% with it occasionally going higher (seen up to 92% for a few seconds). CPU is a dual core, so 50% means 100% of one core. RAM usage drops at the start of the reload, and continues to slowly climb to ~23% while the rules are reloaded into RAM.
System has been set up according to this topic, with about 50 custom rules. It's the network gateway to a small datacenter, which also provides Internet connectivity for hosts outside the datacenter.
Matcher is AC, suricata interface is WAN.
@Cino : Having a tunnel means somehow getting the IPv6 addresses onto pfsense. Unless you are doing some pretty complicated stuff (routing packets to Mars, then Venus, then the end of the galaxy :D) all other interfaces that need to use those addresses (except the tunnel's "terminating" WAN interface) ARE dual stacked ;). Clients on the LAN side can connect either using an IPv4 address or completely stop using IPv4 and use an IPv6 address. That is the definition of dual stacked :D
-
@Cino, Thanks. I removed my message from this thread.
-
@jflsakfja:
@Cino : Having a tunnel means somehow getting the IPv6 addresses onto pfsense. Unless you are doing some pretty complicated stuff (routing packets to Mars, then Venus, then the end of the galaxy :D) all other interfaces that need to use those addresses (except the tunnel's "terminating" WAN interface) ARE dual stacked ;). Clients on the LAN side can connect either using an IPv4 address or completely stop using IPv4 and use an IPv6 address. That is the definition of dual stacked :D
Maybe I don't understand but then again I think I do ;) My WAN has both an IPv4 and a IPv6 address, and so does my LAN/Clients.. Before my ISP provided native IPv6; the WAN was IPv4 and I had a separate WAN(Tunneled) Interface for IPv6. That being said, my current WAN/LAN/Clients are all dual stacked. When I only had IPv6 via a tunnel, the LAN and Clients were dual stacked while my WANs were not. Does that make sense?
Question: With a IPv6 Tunnel setup, do you run suricata on that interface also? Or just the IPv4 WAN Interface?
Edit: Noticed emerging-rbn-malvertisers.rules emerging-rbn.rules were not in the DO NOT USE list
-
They were supposed to remove those categories since they are no longer maintained. I'll add them in the do not use.
Yes that's what I meant with dual stack.
No need to run suricata on the IPv6 tunnel. It still alerts as is.
-
@jflsakfja:
They were supposed to remove those categories since they are no longer maintained. I'll add them in the do not use.
Do you think they will? after reading the comments in your enable rule list; hell will have to freeze over…
-
Supposed is the key word :D