Suricata IDS/IPS on Ubuntu 20.04

No network security setup would be complete without a network-based Intrusion Detection System and Intrusion Prevention System (IPS/IDS). For many businesses, network-based IDS/IPS is a key component of maintaining a PCI-compliant environment. PCI compliance is mandated for any business that handles credit card-holder data in any way. Other businesses handle such sensitive information that literally every packet needs to be inspected for any kind of malicious activity. Financial institutions, healthcare providers and government bodies usually fall into this category.

Whatever the business need, IDS/IPS (from this point forward, I mean network-based. Host-based is another topic entirely) is yet another necessary security tool for keeping a network environment safe. Today we’ll take a look at suricata, an open-source IDS/IPS system that you can install on Ubuntu 20.04. You can even get free, regularly-updated rule lists for staying up-to-date on the latest threats. Some ruleset providers charge for their lists, but many are provided without charge. Let’s get the basics setup and see how it works!

Topology

Topology in GNS3

We’ll install Suricata on Ubuntu20.04-1, which is acting as a router between the hapless workstation and the Internet. We’ll configure Suricata to listen for threats on the “outside”, or Internet-facing interface, ens3.

Installation

Installation requires setting up the Ubuntu PPA for recent, prebuilt packages. We can add it with this command:

add-apt-repository ppa:oisf/suricata-stable

Then update apt, and install:

apt-get update
apt-get install suricata

Configuration

Now that it’s installed, we need to make a couple of configurations in text files. The first is in /etc/default/suricata, which holds the configuration mode and default interface. You’ll want to change the following lines:

LISTENMODE=nfqueue

IFACE=ens3

LISTENMODE sets whether you want suricata to be in IDS or IPS mode. IDS will passively listen and write an alert to a log file. IPS does that too, but with the option to drop detected threats. In order to perform the drop, packets needs to be sent to the nfqueue processing queue. IFACE is whatever network interface you want suricata to listen on.

Next we need to update our rules with the suricata-update command. You can see what lists are enabled by running suricata-update list-sources, but the default ones will do just fine.

suricata-update

Now we should have a set of rules at /var/lib/suricata/rules/suricata.rules. We’ll use the sed tool to mark some of the rules to drop traffic, with these commands:

sed -i -e '/ATTACK_RESPONSE/ s/^alert/drop/' /var/lib/suricata/rules/suricata.rules 
sed -i -e '/USER_AGENTS/ s/^alert/drop/' /var/lib/suricata/rules/suricata.rules 

Finally, we need to send all packets to the NFQUEUE processing queue so they can be dropped if determined to be malicious. These iptables commands will send all packets to that queue with the exception of port 22, which is usually SSH traffic. That way our SSH session to the server isn’t interrupted:

iptables -I INPUT 1 -p tcp --dport 22 -j NFQUEUE --queue-bypass
iptables -I OUTPUT 1 -p tcp --sport 22 -j NFQUEUE --queue-bypass
iptables -I FORWARD -j NFQUEUE
iptables -I INPUT 2 -j NFQUEUE
iptables -I OUTPUT 2 -j NFQUEUE

And finally reload suricata:

systemctl restart suricata

Verification

Quick note: With the way we set suricata up, you can run these tests either from the Ubuntu server where suricata is installed, or from anything behind it. Either will work. Also please rest assured neither of these tests actually does anything close to malicious.

If we send a normal HTTP request to google.com from the hapless workstation at 192.168.0.2, it should work:

curl http://www.google.com
---
<a bunch of web nonsense output here>

But if we change the HTTP user-agent string to “BlackSun”, suricata will detect this as a malware attack. Apparently BlackSun is some kind of ransomware, but just changing the user-agent string to “BlackSun” isn’t going to do anything at all, other than test whether suricata is working or not. The below command will achieve this goal:

curl -A "BlackSun" http://www.google.com
---
<no response>

Suricata is dropping these packets! Our IPS is working. Let’s check if IDS is working too. Activity is logged at /var/log/suricata/fast.log:

cat /var/log/suricata/fast.log
---
01/20/2022-13:40:00.339281  [Drop] [**] [1:2008983:8] ET USER_AGENTS Suspicious User Agent (BlackSun) [**] [Classification: A Network Trojan was detected] [Priority: 1] {TCP} 192.168.122.142:35444 -> 142.250.207.4:80

Success! We’ve been notified of a network attack. Let’s try another one. The website testmynids.com has a nice test we can run with this command:

curl http://testmynids.org/uid/index.html
---
<no response>

This well send an index.html file containing the output of the id root command, a common way for remote command-and-control servers to execute attacks. Let’s check the log:

cat /var/log/suricata/fast.log
---
01/20/2022-13:44:40.778197  [Drop] [**] [1:2100498:7] GPL ATTACK_RESPONSE id check returned root [**] [Classification: Potentially Bad Traffic] [Priority: 2] {TCP} 13.226.78.68:80 -> 192.168.122.142:37444

Success!