A Linux/VPS security auditing tool. It reads a server's live state — listening ports, SSH configuration, users and privileges, services, firewall, filesystem permissions, containers and the web stack — and reports misconfiguration and exposure as ranked, actionable findings.
Status: alpha. 15 checks are implemented and working, with a test suite that runs under ASan and UBSan. Interfaces and output may still change. Treat findings as informed advice to verify, not as verdicts.
A C++ implementation of the VPSentinel design.
A single binary you drop onto a server and run. No agent, no runtime dependencies, no
database, no network access. It inspects the host through /proc, /etc, /sys,
systemd and standard tooling, then prints findings you can act on, with machine-readable
modes for automation.
- Run it only on systems you own or are authorised to administer. This is a security-auditing tool; running it against machines you do not control may be unlawful.
- Scan output is sensitive. A report is effectively a map of a host's weaknesses —
exposed services, weak SSH, privilege paths. Keep it local. The
.gitignoredeliberately excludes reports, baselines, integrity databases and evidence so they are never committed. Do not relax it. - Detected secrets are never printed. The secrets module reports location and type only, never the value.
- The tool reports "no known issues found", never "secure". Absence of findings is not proof of safety — and when a check could not see everything, the report says so rather than staying silent.
- It never modifies the system. Read-only by design: no auto-fix, no writes outside
an explicit
--output, no network, no upload. It also never escalates its own privileges — nosudo, no setuid, no re-exec.
15 checks, all read-only. vpsentinel list-checks prints them; vpsentinel list-rules
prints every rule with its default severity.
| Check | What it looks at |
|---|---|
ports |
/proc/net/* listening sockets mapped to processes; public vs loopback; dual-stack exposure |
users |
/etc/passwd, /etc/group, shadow permissions; UID 0 duplicates; empty passwords |
ssh |
sshd_config with Include position and Match scope honoured; authorised keys; host-key permissions |
sudo |
sudoers and sudoers.d; NOPASSWD; GTFOBins grants; docker group; setuid binaries |
kernel |
sysctl hardening values under /proc/sys |
filesystem |
world-writable files and directories; permissions on sensitive paths |
secrets |
credential-shaped assignments in config files — type and location only, never the value |
packages |
dpkg state, pending security updates, unattended-upgrades, reboot-required |
nginx |
config with include globs followed; TLS protocols, security headers, autoindex, dotfiles |
php |
php.ini precedence through conf.d and pool php_admin_value; FPM, not CLI |
laravel |
APP_DEBUG, APP_ENV, APP_KEY presence, .env permissions and exposure |
tls |
certificate expiry and key size (needs make WITH_OPENSSL=1) |
services |
failed systemd units, weighted by whether they are security-relevant |
firewall |
ufw config, iptables-save, nftables; default inbound policy |
docker |
privileged containers, host namespaces, mounted docker.sock, dangerous capabilities, published ports |
Output formats: human-readable text, --json, --sarif (2.1.0, for CI code scanning),
and --html (one self-contained file, no external resources).
- Linux (the checks read Linux-specific interfaces such as
/proc) - g++ 11 or newer, GNU make
- Optionally
libssl-devfor the TLS/certificate module (make WITH_OPENSSL=1)
No third-party libraries. JSON writing, the test harness and the command runner are
small, deliberate, in-tree implementations — see
guides/GUIDE-01-foundations.md for why.
make # build ./vpsentinel
make test # build and run the test suite under ASan + UBSan
make dist # portable stripped binary to copy to a server
make help # all targetsSee RUNNING.md for how to test a check and how to run the result against a real server safely — including why the report should never be written to the server's disk.
vpsentinel scan # audit the local host
vpsentinel scan --json # machine-readable
vpsentinel scan --only ports,ssh # selected checks
vpsentinel list-checks
sudo vpsentinel scan # full coverageRun as root for complete results: mapping every listening socket to its process,
reading /etc/shadow permissions and evaluating sshd -T all need privilege. Without
root the tool degrades gracefully — it reports what it can see and marks the rest as
degraded, rather than failing or, worse, quietly reporting nothing.
Every check emits findings carrying a stable rule ID, a severity
(info < low < medium < high < critical), a confidence, the affected resource,
remediation advice and supporting evidence. Findings are sorted worst-first, and a
coverage summary is printed above them.
Coverage: 11 checks run, 2 degraded (rerun as root for full results)
[HIGH] Database exposed to the internet — tcp/0.0.0.0:3306 (mysqld)
Fix: bind MySQL to 127.0.0.1, or block port 3306 at the firewall.
[MEDIUM] Public listener — tcp/0.0.0.0:6379 (redis-server)
Fix: bind Redis to loopback; never expose it unauthenticated.
A modular monolith. Each module splits in two: a collector that reads the system and
produces plain facts, and an evaluator that is a pure function from those facts to
findings. Facts accumulate in an Inventory; findings accumulate in a Report.
That seam is the point. It makes the security logic unit-testable without touching the
host, and it means the later phases — baseline/drift detection, file-integrity
monitoring, attack-path analysis — are built over the Inventory rather than being
rewrites.
Adding a check means adding one module and one registry line; the core and the renderers do not change.
See ROADMAP.md. In short: the scan platform first (ports, SSH, users, sudo, firewall, services, filesystem, Docker, Nginx/PHP/Laravel, TLS, secrets, packages), then drift detection, file integrity, attack-path analysis and incident investigation.
Apache License 2.0 — see LICENSE.
You may use, modify and distribute this freely, including commercially. The licence includes an explicit patent grant, and requires that you keep the copyright and licence notices and state any significant changes you make.