Network intrusion detection can give you some really interesting insights into your network
and alert you to potential threats. I've been using a very popular tool called Suricata lately,
and having spent a bit of time trawling through documentation
I thought "You know what this needs? A nice easy getting started guide!"
Welcome back to The Pro Tech Show. Suricata is a network intrusion detection and prevention
system. I say detection AND prevention because it can operate in two ways. One is it stands at
the side and watches your network and alerts you to anything suspicious going on. This is
detection mode. The other is it sits right in the middle of your network traffic and if
it sees anything suspicious it says "No!" and blocks it outright. This is prevention mode.
You're watching a getting started guide, so start with detection. This isn't magic.
Suricata is not psychic. It's making informed guesses as to the intention of network traffic,
but it will get things wrong - especially in the early stages before you've tweaked it. You want
some time to review and adjust it before you block anything. If you go straight to prevention you'll
almost certainly break your network. Suricata is used in a lot of commercial security products but
it's actually free. It's the underlying engine that inspects your network traffic and detects
anomalies, but it's often paired with analytics platforms like Elasticsearch or comprehensive
security suites. We're not going to cover that in this video. We're just looking at getting
Suricata installed and then tweaking it to make the data useful. If enough of you make it to
the end and comment, though; I can do a follow-up where we collect the data into something pretty.
Now let's jump over to our Linux server to get it installed. It is available for Windows, BSD, and Mac;
but most of the guides and documentation are Linux-orientated, so I think you'll have an easier time
in Linux. I'm going to briefly show you two flavours of Linux because there's a tiny difference at the
start. So this one is running Ubuntu 22.04 and this one is running Rocky Linux 8. Rocky is a rebuild
of Red Hat Enterprise Linux, so anything that applies to Rocky should equally apply to Red Hat,
AlmaLinux, or Oracle Linux. They're all the same by design. I'm going to assume you know enough to
get Linux running and edit a text file. Installing Linux itself is beyond the scope of this video but
there are plenty on YouTube. First up, let's check for a Suricata package. For Ubuntu that's "apt list
suricata", and for Rocky it's "dnf list suricata". Ubuntu shows 6.0.4 and Rocky shows... nothing. That's
because Red Hat (and therefore Rocky) ships with a more limited number of packages compared to
other than Linux distros. Red Hat is enterprise-focused and comes with commercial support, so this is a
way of them drawing a box around the software that they have specifically created and are responsible
for supporting. To enable additional software you need to add the EPEL repo - Extra Packages for
Enterprise Linux. This software (much like Red Hat) originates with the Fedora project, which is Red
Hat's upstream development distro. So they're curated by a team of people in a Red Hat-owned
project specifically to be used with Red Hat-based distributions like Rocky, but they are not covered
by Red Hat's commercial support. Having said that, neither is Rocky, so let's crack on! Enable EPEL
with "dnf install epel-release" and now if we check for Suricata it's there, but it's an old version. By
the way: a lot of the commands here will require admin privileges so I'll be prefixing many of them
with "sudo" but I'm not going to call it out every time. If you get a permissions error, just check
your sudo'd. The Ubuntu version isn't bang up to date either. The latest version at the time of
recording is 6.0.8. To get the latest version we need to get it from the people behind Suricata:
the Open Information Security Foundation. We can enable their community repo in Ubuntu with
"add-apt-repository ppa:oisf/saracada-stable". On Rocky it's "dnf copr enable @oisf slash/suricata-6.0";
although you'll presumably need to put a different version number at the end of that in
the future. You can get these commands from the official documentation, which I'll link in the
video description. Now if we check again on both servers they have the latest version of Suricata
available, and we can install it on Ubuntu with "apt install suricata" or on Rocky with "dnf install suricata".
At this point I'm going to drop the Ubuntu server and stick with Rocky, because the
steps are going to be the same. Before you go further type "ip ad" and check the name of your
network interface. It's not "lo", that's the loopback interface. If using a different distribution and
"ip ad" doesn't work, try "ifconfig". You want the one with your IP address on it. In my case that's eth0.
Now let's jump into the main Suricata configuration file. You'll find that at /etc/suricata/suricata.yaml.
I'm using them Vim. Use whatever text editor you're comfortable with. The
first thing we want to do is change the HOME_NET here, near the top. There are a few examples here.
The hashtags are comments, so anything starting with the hash is ignored; meaning the only HOME_NET
that matters is the first one. By default it includes all private IP address ranges, but you
should change it to match your own network. You can have a look at the other settings, but by default
they all reference your HOME_NET. The exclamation mark in front of the EXTERNAL_NET means anything
that isn't your HOME_NET. The next setting to look at tells Suricata which network interface
to use. It's called "af-packet" If you're using Vim like me you can search for it by entering "/"
in command mode then "af-" and Enter should be enough to find it. Mine's set to eth0
of the box, which is handy because if you remember when we checked our interface using "ip ad" mine was
called eth0; so I don't need to make any changes. You might need to change this if your interface name
is different, or if you have multiple and want to select a specific one. There are a lot of options
in here and it's worth reading up on them, but this is enough to get started. Save the file and quit.
In order to detect threats hidden within your network, Suricata needs some rules. It provides
a default set but we can give it more threat intelligence to work with. Run "suricata-update list-sources"
to see what we have available. These are provided by third parties. Some of these
are free, others are commercial. If we look at Proofpoint, for example, they provide one
of each. There's the Emerging Threats Open Ruleset, which is free; and the Emerging Threats Pro
Ruleset, which is paid. Have a look, Google the rule sets to see what they do, and choose the
ones that you want. To enable them, it's "suricata-update enable-source", and then the name
of the ruleset. For example to enable the free Emerging Threats Open Ruleset from Proofpoint
it's "suricata-update enable-source et/open". As you can imagine, Suricata's rulesets
get updated fairly regularly so we need to download a fresh copy. To do that it's
"suricata-update". We'll get some warnings here about protocols that weren't configured and have been
set to enabled. You'll find these settings in the suricata.yaml file that we were in previously, and
you can tweak them to explicitly enable or disable them so Suricata knows whether you care about the
traffic. I'm going to leave as-is for now, with them getting enabled by default in version 6.
The warnings are there to tell you that in a later version if you've not explicitly enabled them in
the file Suricata will turn them off instead of on. You want to run "suricata-update" every so often to
get the latest detection rules but we probably don't want to literally log on and type this every time
so I'm going to set up a Cron job to do it automatically. That's "crontab -e" to edit. Using
crontab is safer than editing the file directly and protects you from silly mistakes. We want to
run "suricata-update", and to apply the new rules you can either restart the service or you can use
suricatasc to load them without restarting. That requires more memory to hold both sets temporarily,
but it means no service interruption. If you're not familiar with Cron you can copy what I'm
doing and it will run every 6 hours. A little tip: while it's not strictly necessary to include the
full path to executables, it is good practice. If you just use the executable name it will almost
certainly work, but it might also be exploitable if an attacker gets onto the system and uses a bit of
path manipulation to trick it into running the wrong file. Right, we've talked about restarting
the service; but we've not actually started it yet ourselves. Thats "systemctl enable suricata" to
set it to start automatically after a reboot and "systemctl start suricata" to start at now.
That Suricata running and you're now doing intrusion detection, but at the moment the only
network traffic it can see is its own. If you want Suricata to see the rest of your network traffic
you need to mirror the network traffic to your Suricata server. How exactly you achieve this will
depend on your network setup so I can't give you a direct answer, but the words you're looking for
are "port mirroring" "port monitoring" "SPAN" (short for Switch Port ANalyzer) and "promiscuous mode". For
some examples: in VMware if you're using a vSphere standard vSwitch you can enable promiscuous mode
on the vSwitch, then any virtual machine on the switch can view all traffic from the same switch.
If you have a distributed switch you can do proper port mirroring beyond that switch. In Hyper-V under
the network adapter's "advanced" features you'll find "mirroring mode" Set your Suricata virtual
machine as the destination and your other machines as sources to view their traffic. If you're using
a physical Cisco switch then it's "SPAN" or "monitor" you're looking for. If in doubt, look up the manual
for your physical or virtual network switches to find out how they do it. Once you've got the
traffic mirrored to Suricata you're ready to start detecting intrusions into your network; but how
do you know it's working? There's a handy website from 3CORESec that you can use to generate
safe but suspicious looking traffic. The website is "https://testmynids.org" and there's nothing much here.
If you follow the link to the GitHub project, though; you'll find a script for running some tests. We'll
just use the first one because you don't even need their script to run the test - you just need to
visit a website. You can see the address here: "http://testmynids.org/uid/index.html". If I go to that
site you just see a bit of text with the root user ID. This isn't malicious. There is nothing dangerous
about this response. If I run "sudo id" to check my user ID when elevated to root on my Linux machine
here, you'll see a similar result. The reason Suricata thinks it's suspicious is because that is
the output you see when you check your user ID on a Unix machine and you're running as root. Except,
this has been spat across the network unencrypted by a website. That's normal output if you're
operating a server as root. It's not normal for a website to respond with, and could indicate that
this website has been breached and the attacker is exploiting it to run commands with root privileges.
Except in this case it doesn't. It's literally just the response the website gives any time you
visit this page, in order to trigger Suricata. To find your alerts there are two log files we need
to check. These are located in /var/log/suricata. The first is called eve.json and the second is called
fast.log. fast.log is the easiest for a human to read, and the most concise. It outputs a single line
of text every time an alert is generated. eve.json isn't quite so readable as it's JSON-based and
outputs a lot more noise because it includes more events than just alerts; but, really, this
log is intended to be fed to an automated system to be ingested and analysed. Remember if you want
a follow-up where we ingest these logs and do something with them, let me know in the comments!
Let's show this in action by tailing fast.log and using this test website to trigger an alert.
There you go. That's your alert so you know Suricata is working. Suricata may be working,
but if you leave it like this then chances are it's going to generate a ton of spam because it
will alert you to a lot of things you won't actually care about. You therefore need to
tweak the detections by disabling rules you don't care about and suppressing alerts for legitimate
traffic. Let's look at how to disable rules first. You need to create a file called "disable.conf" in
/etc/suricata. This file won't exist until you create it. You can disable rules individually by
adding their signature ID to this file, one per line. You can find the signature by looking at
the alerts in fast.log. It's this number between the colons, inside the square brackets. The first
number is the generator ID and you can include that too, but it's not required. If we add that
signature ID to disable.conf we will no longer get alerts for this test website. You can also disable
groups of rules. If you want to turn off a whole bunch at once the syntax is "group:", and
then the name of the file containing the rules you want to disable. You can use the full file name or
a wildcard if you want to disable multiple. You'll find the rules files under /usr/share/suricata/rules.
The "stream-events" rules tend to generate a ton of noise so we'll add that in here
to disable all of the rules in that file. Most of the alerts it generates are from incomplete
TCP sessions. There are network scanning tools that perform incomplete TCP handshakes to try
and avoid detection, but on most networks you'll typically find a pile of incomplete sessions from
misbehaving hardware or software. In a perfect world we wouldn't have any imperfect software
and network transmissions would be 100% reliable, but in the real world this doesn't happen and
most of these alerts will be rubbish. One final method you can use to disable rules are regular
expressions. This can help if you want to get rid of a bunch of similar alerts without listing the
signatures individually, but don't want to disable an entire rules file. Have a look in faster.log and
if there are any patterns in the text that you can build a regular expression from, and you can
add it to disable.conf using the format "re:", then the regular expression. Once we've done this
then we need to run "suricata-update" to rebuild our rules, and then tell Suricata to reload its rules.
This is because when we run "suricata-update" it reads in rules from all of the configured sources
and then merges them all together into a single file that it uses for detecting suspicious traffic.
As it does this it will check the rules against disabled.conf, and if it finds a match that rule
won't get included in the live rules file. So until we run a rules update the changes to disable.conf
have no immediate effect. That's how to disable rules, but sometimes you'll come across alerts
that are legitimate in certain circumstances and you want to prevent alerts when those legitimate
circumstances apply but still get alerted the rest of the time. In this case disabling the rules won't
meet your needs because that will disable them all of the time. An example of this is my Veeam
backup server. During a normal backup run it will connect to the Windows Virtual machines it backs up
and it will remotely create a service within the operating system to run some application quiescing
tasks. This is perfectly normal but Suricata sees one IP address remotely connecting to and
executing code on a bunch of other servers, and it thinks that looks suspicious. We don't want
a pile of alerts every time the backups run, but this could be a sign of lateral movement
by an attacker across our network so we don't want to disable the rules altogether. Instead, we can
add a suppression rule that will prevent alerts if the suspicious traffic originates at the IP
address of our backup server. These suppression rules are set in the file thresholds.config, also
in the /etc/suricata directory. The syntax these rules is "suppress gen_id" then
the generator ID number, "sig_id" then the signature ID number, "track" then either "by_src", "by dst", or
"by_either" (depending on whether you want to suppress based
on the source IP address, the destination IP address, or either of them), then "ip" and the IP
address or subnets you want to suppress. Again, you can find the generator and signature IDs by
looking at the alerts in fast.log. The generator ID is usually 1. Between the disable and suppression
rules you should be able to tune Suricata to filter out the noise and leave you with just
meaningful alerts. It can be quite enlightening to see what pops up. For example, running it on my
home network showed me that a media streaming app was sending unencrypted information over port 443,
which is supposed to be reserved for encrypted HTTPS traffic. Just because an application uses
a supposedly secure port doesn't mean it's actually secure, and Suricata can alert you
to such misbehaviors. One last thing you should check before we leave Suricata's logs behind is
that you have the logrotate tool installed. If not, in my case it's "dnf install logrotate"
to get it installed. Those Suricata log files will grow very large over time. Suricata creates
a configuration for logrotate automatically to keep them under control, but that only works
if logrotate is actually installed. That's you set up with a basic functioning Suricata install.
Whilst it is functional, reading text files is kind of a boring way to use it; so comment if
this interests you and I'll put the next video up here where we integrate it with something shiny.
Please remember that whilst intrusion detection is a really good thing to be doing, most breaches
come about due to compromised passwords; so the best thing you can do to protect yourself is to
stop using passwords! Watch this video to learn about how you can actually do that, then once
you've secured your accounts you can come back and learn more about intrusion detection.