IDS/IPS on OpenWRT using Snort3

IDS/IPS on OpenWRT using Snort3
Anime Anything with Prompt "Samurai holding shield and sword"

If you've configured networks or read about network security, you're probably familiar with IDS and IPS. In short IDS (Instrusion Detection System) allows you to know something strange is happening in your network, while IPS (Instrusion Prevention System) helps you in preventing it. You can find out more here.

If you're on OpenWRT like me, most recommended solution is to use Snort3. Snort3 is better in some ways (mostly performance design) than Snort2 a comparison can be found here. However Snort3 installation at least on the current release required 2 quirks for me (keeping aside the high performance requirements.):

  1. Storage required for rules
  2. Configuration mixup

To solve the first issue, since I did not want to change the default partition table to allow in place upgrades, I added another USB stick and followed this guide. After this, my persistence was mapped to /dev/sda1 and mounted on /mnt/sda1. The other issue was the rules themselves. I got a more exhaustive ruleset after logging into the portal. I downloaded the latest snapshot, under the Registered column.

Download page after logging in.

On second point, I ran into trouble while trying to install Snort3 using opkg install snort3 . After some research I judged that it was fine to use following command on this openwrt build: opkg install --force-overwrite --force-depends snort3

With the above steps done, we can now stick to this guide, adjusting for the mount path mentioned above. And since we've changes how the rules look in our download, we'll modify the detection block in /etc/snort/snort.lua as:

ips =
{
    -- use this to enable decoder and inspector alerts
    --enable_builtin_rules = true

    -- use include for rules files; be sure to set your path
    -- note that rules files can include other rules files
    -- (see also related path vars at the top of snort_defaults.lua)

    mode = tap,
    variables = default_variables,
    rules = [[
    include $RULE_PATH/includes.rules
    ]]
}

You can also change to specific rules if you want, as specified in the guide. Immediately after following the last step, I got the following logs.

A lot of correctly identified traffic!

I'd read a lot of blogs on the high performance penalty that Snort imposes, but since I am using Pi4 as my device, the performance hit wasn't there and finally I saw some memory and CPU usage of my device!

Load increased every time rules are loaded but drops down after that.
Memory usage ballooned to 0.5G though we're well below any issues.

In future, I'll try and transition to an IPS after tuning my rules further. Hope you found it interesting. One thing to note however is my single connection speed did suffer by almost 50%, but overall throughput is similar. I'll try to tune this more in future as well.


Further update on performance.

By tuning the rules, I was able to saturate my connection with everything including SQM enabled. Here are the results.


Update: I got the IPS working as well. In the documentation provided by Openwrt here, the line following line belongs in the ipssection:

action_override = 'drop', 
Inline mode works!