Log monitors¶
Six monitors tail well-known Linux log files. They are the bread and butter of Fenrir — everything else builds on what they emit.
auth_monitor¶
Source: /var/log/auth.log
Detects SSH and sudo activity. Pattern-matches the standard sshd[] and sudo[] log lines.
Event types it produces:
parsed_data.type |
Meaning | Default severity |
|---|---|---|
failed_password |
Wrong password for known or invalid user | LOW (escalates with rate) |
invalid_user |
Login attempt for nonexistent user | LOW |
max_auth_exceeded |
Too many auth attempts in one connection | MEDIUM |
sudo_failure |
Wrong sudo password | LOW |
accepted_key |
Successful publickey login | INFO |
Brute-force detection. The rule engine tracks failed_password per IP in a sliding window. Crossing the rate threshold escalates severity to HIGH and triggers an investigation. Window size and threshold are tunable defaults — for production hardening, see the Hardening checklist.
Successful login from suspicious IP. If an accepted_key arrives from an IP that recently triggered a brute-force pattern, severity is CRITICAL — possible account compromise.
honeypot_monitor¶
Source: /var/log/nginx/honeypot.log
This file is populated by nginx configured to catch requests to fake admin paths and route them to a dedicated log channel. See the bundled nginx site config in deploy/fenrirsoc/nginx-fenrirsoc.conf for the patterns we ship as a starting point.
Every honeypot hit is by definition suspicious — these paths don't exist on a real site. Severity defaults to HIGH; paths that match higher-risk signatures (common shell-upload artefacts, RCE-style URL encodings, sensitive system file references) escalate to CRITICAL. The exact pattern list and severity escalation rules live in p3guardian/analyzers/rule_engine.py; they're kept out of the public docs for the obvious reason.
The parser supports both IPv4 and IPv6 clients.
fail2ban_monitor¶
Source: /var/log/fail2ban.log
Watches fail2ban's own log for ban/unban events. This serves two purposes:
- Suppression. When fail2ban bans an IP, Fenrir adds it to an in-memory set so subsequent honeypot hits from the same IP don't generate duplicate "attack in progress" alerts.
- Repeat offender escalation. If the same IP triggers fail2ban in multiple jails (recidive), Fenrir escalates to CRITICAL and creates a GDPR breach notification record (configurable).
nginx_monitor¶
Source: /var/log/nginx/access.log
The "everything else" of HTTP traffic. Produces events for:
- Suspicious paths on real vhosts that aren't part of the honeypot but match common scanner targets — MEDIUM
- Profile-page enumeration in burst (forum user pages, admin panels) — MEDIUM, escalates with rate
- Known offensive-tool user-agents — HIGH (full list in source)
- High HTTP error rates from a single IP — MEDIUM
ufw_monitor¶
Source: /var/log/ufw.log
Reads firewall drop logs. Useful primarily for port scan detection:
- Single IP hitting many ports in short window → HIGH
- Pattern of common scan ports (22, 23, 80, 443, 3306, 5432, 6379, ...) → MEDIUM with category
port_scan
kernel_monitor¶
Source: /var/log/kern.log
The kernel log catches several physical/process events that Fenrir treats as security-relevant:
| Event | Severity | Why |
|---|---|---|
usb_device_connected |
CRITICAL | Could be a malicious USB on an unattended server |
usb_device_info |
HIGH | Identifies vendor/product of the connected device |
usb_device_disconnected |
MEDIUM | Track when a device left |
oom_kill |
CRITICAL | OS killed a process for memory — could be DoS or genuine pressure |
disk_error |
CRITICAL | Failing disk hardware |
segfault |
HIGH | Crashing process can indicate exploit attempts |
apparmor_denied |
HIGH | A profile blocked something — usually a misbehaving binary |
USB detection in particular is a low-effort win: physical access attacks (e.g. an admin's laptop being plugged into a server it shouldn't be) get flagged in real time.
Whitelisting¶
For all monitors, IPs in IP_WHITELIST (default 192.168.1.0/24, 127.0.0.1) get severity demoted to INFO or LOW. This prevents "the dev who SSH'd from the office" from showing up as a failed_password HIGH event.