@heywoodlh

heywoodlh thoughts

Lightweight security stack (SIEM, vulnerabilities, logging) for homelab

As someone with a career orbiting around security, I deeply enjoy finding effective security tools that are minimal. This post will serve as a index of what I’m doing for security monitoring at home at the time of writing. These tools are mostly all running in Kubernetes.

Notification Infrastructure #

It’s important for significant security events to be made visible to administrators.

NTFY #

I use NTFY to receive push notifications – although, as described below, I mirror those notifications to Signal.

NTFY deployment in Kubernetes: ntfy.yaml

As an example, here is how I monitor all SSH login attempts on my NixOS servers with NTFY: sshd-monitor.nix

NTFY Signal Mirror #

I wrote the following tool to mirror notifications I get in specific ntfy topics to Signal: github:heywoodlh/signal-ntfy-mirror

I won’t describe how it all works, but here’s the NixOS implementation for those willing to figure it out themselves: ntfy-signal.nix

The resulting Signal alert messages look like this:

signal-ntfy

Logging #

Good logging infrastructure is a critical security component.

Syslog-ng #

Syslog-ng, in my opinion, is the underrated GOAT of logging. It’s minimal, yet can do so much.

Syslog-ng deployment in Kubernetes: syslog.yaml

The deployment also contains configurations for the following two tools to quickly search the logs:

Here is how looking up failed SSH login attempts with my logbash deployment looks:

❯ logbash linux ssh-failed-login
/logs/linux/2025_07_23.log:Jul 23 21:30:56 ts-syslog-6d6kv-0 <86>1 2025-07-23T15:30:56-06:00 nix-nvidia sshd-session 2354768 - - Failed keyboard-interactive/pam for invalid user fakeuser from 192.168.1.48 port 63139 ssh2
/logs/linux/2025_07_23.log:Jul 23 21:30:56 ts-syslog-6d6kv-0 <86>1 2025-07-23T15:30:56-06:00 nix-nvidia sshd-session 2354768 - - Connection closed by invalid user fakeuser 192.168.1.48 port 63139 [preauth]
/logs/linux/2025_07_23.log:Jul 23 21:30:56 ts-syslog-6d6kv-0 <30>1 2025-07-23T15:30:56-06:00 nix-nvidia s7wypw6qzlva5z7m58zl2szjq7p0c1ks-sshd-monitor 2354781 - - {"id":"xvFYOYQpzn53","time":1753306256,"expires":1753349456,"event":"message","topic":"ssh-notifications","message":"Jul 23 15:30:56 nix-nvidia sshd-session[2354768]: Failed keyboard-interactive/pam for invalid user fakeuser from 192.168.1.48 port 63139 ssh2"}
/logs/linux/2025_07_23.log:Jul 23 21:30:56 ts-syslog-6d6kv-0 <30>1 2025-07-23T15:30:56-06:00 nix-nvidia s7wypw6qzlva5z7m58zl2szjq7p0c1ks-sshd-monitor 2354785 - - {"id":"hOCAbts9lJ6X","time":1753306256,"expires":1753349456,"event":"message","topic":"ssh-notifications","message":"Jul 23 15:30:56 nix-nvidia sshd-session[2354768]: Connection closed by invalid user fakeuser 192.168.1.48 port 63139 [preauth]"}

Syslog-ng to NTFY alert/notification #

I want to draw special attention to the fact that syslog-ng can run actions on specific matches. This is especially powerful when you want certain log messages to trigger events.

In my case, I want specific logs to trigger NTFY alerts. I couldn’t find any reference examples when trying to set this up, so I hope this saves anybody wanting to do this some time.

Here’s a snippet from my syslog-ng configuration that triggers an NTFY notification on a match:

source unifi_remote {
  udp(ip(0.0.0.0) port(514));
};

destination ntfy {
  http(
    url("http://ntfy.default.svc.cluster.local/security-notifications")
    method("POST")
    user-agent("syslog-ng User Agent")
    headers("Title: syslog-ng alert ${HOST}")
    body("${ISODATE} ${MESSAGE}")
  );
};

# All noteworthy ssh events
filter ssh_events {
  message("(Failed password|Invalid verification code|Invalid user|Accepted publickey|Accepted password|Accepted keyboard-interactive|Failed keyboard-interactive).*");
};

# unifi ssh notifications
log {
  source(unifi_remote);
  filter(ssh_events);
  destination(ntfy);
};

Endpoint monitoring #

I use a handful of tools for monitoring my servers and workstations.

Using FleetDM Policies for determining endpoint posture #

FleetDM is an open source endpoint monitoring solution built around OSQuery. OSQuery is perhaps the only solution I know of wherein one can get the state of a machine without administrative shell access and with minimal invasion of privacy.

FleetDM deployment in Kubernetes: fleetdm.yaml

MacOS FleetDM configuration #

Installation of the fleetctl-generated installer for MacOS, hosted on a web server in my Tailnet: base.nix

As a Nix-Darwin and Home-Manager here’s where I configure my Mac relevant to Fleet:

And, here’s how the Macs show up on Fleet after they are configured:

fleetdm-macos

Linux configuration #

NixOS configuration for OSQuery: osquery.nix

Ubuntu servers installing the FleetDM generated package with Ansible: security.yml

Vulnerability scanning #

I have at least two solutions for vulnerability scanning at the time of writing.

Nuclei for web scanning #

I use Nuclei from Project Discovery for automated vulnerability scanning in my cluster.

Nuclei deployment in Kubernetes: nuclei.yaml

The features in my deployment are the following:

  • Automatic enumeration of Kubernetes services as targets for Nuclei to scan
  • Upload of results to projectdiscovery.io’s dashboard

Project Discovery Dashboard

Flan Scan (nmap + vulners) for network vulnerability scanning #

For a simple, less web-focused vulnerability scan, I use Cloudflare’s Flan scanner which is as a wrapper around nmap and the vulners script that produces a report of the findings.

Flan scan deployment in Kubernetes: flan-scan.yaml

Flan Scan Results

Written on July 23, 2025

linux syslog siem security logs osquery