PAMSignal is a lightweight, real-time login monitor for Linux servers. It watches the systemd journal for PAM authentication events and writes structured events back to the journal when someone logs in, logs out, or tries to brute-force their way in. Optionally sends alerts to Telegram, Slack, Teams, WhatsApp, or Discord.
Don't use a sledgehammer to crack a nut. If you manage 1-10 Linux servers and just want to know when someone touches your box — without deploying Wazuh, EDR, or reading 200 pages of documentation — this is for you.
graph LR
sshd["sshd / sudo / su"]
journald[("systemd-journald")]
pamsignal["PAMSignal"]
admin["🧑💻 Admin"]
platforms["Telegram / Slack<br/>Teams / WhatsApp / Discord"]
sshd -- "PAM auth events" --> journald
pamsignal -- "reads & writes<br/>structured events" --> journald
admin -- "journalctl -t pamsignal" --> journald
pamsignal -. "fork+exec curl<br/>(best-effort)" .-> platforms
platforms -. "alerts" .-> admin
style pamsignal fill:#2d6a4f,stroke:#1b4332,color:#fff
style journald fill:#264653,stroke:#1d3557,color:#fff
style sshd fill:#6c757d,stroke:#495057,color:#fff
style platforms fill:#6c757d,stroke:#495057,color:#fff,stroke-dasharray: 5 5
style admin fill:#e9c46a,stroke:#f4a261,color:#000
# Install dependencies
sudo apt install libsystemd-dev pkg-config build-essential meson ninja-build
# Build
meson setup build && meson compile -C build
# Create service user
sudo useradd -r -s /usr/sbin/nologin pamsignal
sudo usermod -aG systemd-journal pamsignal
# Run
sudo -u pamsignal ./build/pamsignal --foregroundMonitor events in another terminal:
journalctl -t pamsignal -fSee Deployment for production setup with systemd.
- Real-time monitoring of PAM events (sshd, sudo, su, login)
- Structured journal events with custom
PAMSIGNAL_*fields - Brute-force detection (configurable threshold and time window)
- Best-effort alerts to Telegram, Slack, Teams, WhatsApp, Discord, and custom webhooks
- Alert failures cannot break the core monitoring (fork+exec isolation)
- INI-style config with live reload via SIGHUP
- Runs as unprivileged user with 15+ systemd security directives
- Build hardened: stack protector, FORTIFY_SOURCE, PIE, full RELRO
- Single binary. Single config file. Single dependency:
libsystemd
| Doc | What's in it |
|---|---|
| Architecture | C4 diagrams, alert isolation model, structured journal fields, design decisions |
| Configuration | Config file reference, alert channels, CLI flags, reload |
| Alerts | Channel setup guides, message formats, webhook payload reference |
| Development | Build, test environment, e2e testing |
| Deployment | systemd service, production setup, security hardening |
| Changelog | What's done, what's next, task tracking |
- I manage a number of Linux servers with limited resources and needed a monitoring tool that didn't exist the way I wanted.
- I wanted to learn C, Linux internals, and security by building something real.
- I wanted to create an open-source project Made in Vietnam.
This project is built with AI assistance (Claude Code). I want to be straightforward about what that means.
I'm not a senior C programmer. I don't have years of Linux systems experience. AI doesn't just write boilerplate for me — it teaches me, catches mistakes I wouldn't know to look for, and helps me make decisions I couldn't make alone yet. The OWASP ASVS 5.0 security review that hardened this project? That was an AI-assisted audit using a custom skill I built for exactly this purpose.
I don't claim full control over every detail. What I do is: read what AI produces, ask questions when I don't understand, test it on real systems, and take responsibility for shipping it. The .claude/ directory is committed to this repo — you can see exactly how AI is used in this project. I hide nothing.
This is how I believe software will increasingly be built: humans and AI collaborating openly. If that bothers you, this project probably isn't for you. If you're curious about the workflow, everything is here to inspect.
See CHANGELOG.md for the full task tracking.
Done: Core observer, structured journal output, config with SIGHUP reload, alert dispatch (Telegram, Slack, Teams, WhatsApp, Discord, webhook), security hardening, documentation.
Next up:
- End-to-end test with real alert channels
- Per-IP alert cooldown (current cooldown is global)
- Curl availability check at startup
Ideas (no promises): GeoIP/ASN lookup, event forwarding, package distribution, IPv6 context, message templates.
Technical notes I wrote while building this: