There's a certain kind of quiet that settles over the house late at night — the kind where the world feels smaller, softer, and every little blinking LED suddenly has a story to tell. That's the quiet I was sitting in when this whole Raspberry Pi 3 journey started to feel real.

What began as a gift from a friend and a way to keep my skills sharp between SOC roles has turned into something more: a little, low-powered box on my network that now watches, listens, and speaks up when it sees something worth talking about. This post is the end of the build, but not the end of the story. The next chapter is all about what this thing is seeing in my logs — and I'm going to bring you along for that ride too.

Listening to the Pi Before Asking It to Work

Now, where I come from, you don't hand a man a shovel and tell him to dig before you've walked the land with him. Same thing with this Pi. Before I ever asked it to inspect a single packet, I took its pulse.

A quick check showed I had about 19 gigabytes free on disk — plenty of room to stretch out. Memory sat just under a gig total, with a good 600 megabytes left open and ready. Not a powerhouse, but not weak either — just like an old pickup that'll treat you right if you don't ask it to tow a house.

My main path to the world was wlan0, the WiFi interface, tucked neatly inside a little /24 home network. That was the neighborhood this Pi would be watching—the digital front porch it'd be sitting on. Once I knew who it was and where it lived, I pulled Suricata down, waited out the slow install like a pot you don't want to rush, and watched it introduce itself as Suricata 7.0.10. Fresh and ready. Or so I thought.

When Greed for Rules Nearly Broke the Box

Here's where I got ahead of myself.

Instead of easing Suricata in with a small set of rules, I went straight for the full Emerging Threats ruleset. Thirty thousand-plus rules. On a Pi 3 with 1GB of RAM. That's like trying to feed a whole family reunion out of one little cast-iron skillet.

I tuned HOME_NET to my actual range, pointed Suricata at wlan0, and set up af-packet with all the trimmings—threads, cluster IDs, defrag, the works. The config test passed smooth as butter. The service started clean. Systemd smiled and told me Suricata was "active (running)."

But a couple minutes later, when I checked memory, the truth came out:

  • RAM had gone from a comfortable 609MB free to around 92MB.
  • Swap had blown up from a light touch to more than 700MB used.
  • Suricata alone was lounging on over half a gig of RAM like it owned the place.

Soon enough, my SSH session froze up, spit out a disconnect, and left me standing outside my own Pi. When I finally got back in and ran uptime, it was clear the poor thing had quietly rebooted from the strain. No big dramatic error, no grand failure monologue—just a little board that had been asked to carry too much.

Trimming the Rules, Keeping the Purpose

So I did what any sensible man does when the pot is boiling over: I turned down the heat and changed the recipe.

First thing, I stopped Suricata and let the Pi breathe. Memory relaxed back into the 600MB free range, swap came down, and the system felt responsive again. That's when I decided: this wasn't going to be about bragging rights or running "all the rules." It was going to be about running the right rules for this little board.

I built a minimal ruleset — just five lines, but each one chosen with intention:

  • One rule to see HTTP traffic, so I know when the web is flowing.
  • One for DNS queries, the quiet backbone of almost everything.
  • One to catch a simple port scan pattern, a classic sign someone's rattling your windows.
  • One special TESTMYNIDS rule to light up when a known test payload shows up.
  • One to watch SSH attempts hitting port 22, because you always watch the door where the keys live.

Then I told Suricata to forget the big global file and use minimal.rules instead. I left the default rule path alone since it was already where I needed it, and dropped the flow and stream memory caps down to something that matched the Pi's size—32MB and 16MB.

Same tool. Same machine. Just a different kind of respect.

YAML: Proof That One Space Can Ruin Your Night

Of course, nothing worth building ever comes without a little extra drama.

When I tested the new config, Suricata complained about a problem at line 1531. The error was vague, the kind that makes you lean in closer at the screen like that'll help. When I pulled up the lines around it, the issue stared back at me: a single leading space in front of stream:.

One space. That was it.

YAML doesn't care about your intentions — it cares about your indentation. I cleaned up that stray space, tested again, and this time Suricata spoke calmly:

  • 5 rules loaded.
  • 0 failed.
  • Config successfully validated.

It was like finally getting a nod from an old head in the room who'd been side-eyeing you until you got it right.

From Drowning to Floating: The Numbers That Matter

When I started Suricata with the minimal ruleset and let it settle, the difference was the kind you feel in your shoulders.

Instead of hogging half a gig of RAM, Suricata was sipping around 68MB — about 7% of the total. The system as a whole was using under a third of memory, with over 500MB still free. Swap was back to being a gentle safety net instead of a crutch.

In plain terms:

  • Before: crashing, gasping, and rebooting.
  • After: calm, stable, and ready to watch the network without breaking a sweat.

Same Pi. Same Suricata. New attitude.

Teaching WiFi to Listen Like a Wire

Even then, there was one more lesson waiting for me.

I fired off some test traffic using testmynids.org, waited a few seconds, and checked fast.log—nothing. Suricata was running, stats showed it was polling packets, but the alerts stayed silent like a radio with the volume turned down.

That's when I had to remember something a lot of folks forget: WiFi is picky. In managed mode, wlan0 only sees traffic meant for its own MAC address. But an IDS, a true watcher, has to see the whole conversation, not just what's addressed to it.

So I switched wlan0 into promiscuous mode. Once I did that and ran the test again, the logs lit up:

  • DNS queries logged as they flew by.
  • HTTP hits recorded loud and clear.
  • SSH connection attempts flagged like someone tugging at a locked door.
  • The TESTMYNIDS alert firing off, announcing that the test payload had been spotted.

Right then, the Pi stopped being just a host. It became a watchman.

Where We Stand Now — and Where We're Heading

So here's where things stand today:

  • This Raspberry Pi 3 is running Suricata 7.0.10 as a lean IDS.
  • It uses a 5-rule minimal ruleset, tuned for visibility without overloading the hardware.
  • Memory usage is sane, swap is under control, and the system stays responsive.
  • Promiscuous mode on wlan0 gives it a wide view of my home network traffic.
  • Logs are rolling in: HTTP, DNS, SSH, port scan attempts, and test payloads are all being recorded.

I set out to turn a gifted Raspberry Pi 3 into a threat detection tool, and I did that. But if I stopped here, I'd be leaving the best part untouched. Because an IDS that only logs and never gets read is just a very busy diary sitting on a shelf.

So here's what comes next — and what I want you to know as I close this build series:

I'm going to start peeling back the layers of these logs. I'll be:

  • Reading fast.log, eve.json, and stats.log like stories instead of just files.
  • Learning what "normal" really looks like on my own network.
  • Calling out the strange, the noisy, and the suspicious.
  • Walking through real alerts, one by one — what fired, why it matters, and how I'd respond if this were a production environment.

And I'm not keeping that to myself.

I'll be sharing what I find — patterns, oddities, lessons learned from real traffic, not lab-perfect examples. We're going to move from "how I built this thing" to "what this thing is telling me," from tool setup to signal interpretation.

The build is done. The pot's off the stove. But the flavors? They're just starting to come through.

Stick around — we're about to let this Raspberry Pi tell on everything it's been seeing.