Audit your stack
Overview
The four scripts under audit/ are read-only checks. None of them mutate
state — no config rewrites, no service restarts, no package installs. They
inspect the running system, print a summary, and exit with a status code you
can wire into cron, monitoring, or a pre-deploy gate. Every script accepts
--help and can be run standalone:
sudo bash audit/audit-wp-health.sh --help
If you only remember one thing: read the table at the bottom of each text report. That’s the answer.
audit-wp-health.sh
Probes WordPress sites for core/plugin updates, DB reachability, file permissions, disk usage, error log size, and TLS expiry.
Useful flags
--domain=example.com— audit just one site instead of every site under/home/*/webapps/--user=alice— narrow to one system user (rare; only when two users own a same-named domain)--dry-run— list discovered sites without probing them
Try it
sudo bash audit/audit-wp-health.sh --domain=example.com
You get one block per site with seven lines (core, plugins, db, disk, perms,
tls, errlog), each prefixed OK:, WARN:, or CRIT:. If tls says
WARN: TLS expires in 12d, you have your weekend renewal task. If perms
says wp-config.php mode 644 is world-readable, fix it before lunch — that
file holds the DB password.
Exit codes
0— every site healthy1— at least one site raised warnings (outdated plugin, big log, cert in 30-day window)2— at least one critical (DB unreachable, cert expired, wp-cli missing) or script error
audit-system-metrics.sh
Snapshots load, memory, per-mount disk, network sockets, and the live state of Apache / PHP-FPM / MariaDB / Redis. Designed to run cheaply and produce either a glanceable table or one JSON object.
Useful flags
--format=text|json— pick the renderer (defaulttext)--watch=N— refresh every N seconds;Ctrl-Cto stop.textmode clears the screen each tick.--dry-run— print which sources it would read, without touching them
Try it
sudo bash audit/audit-system-metrics.sh --watch=5
That’s the “something’s slow, watch it live” command. The [Disk] section
flags any mount over 85% used with HIGH. The [PHP-FPM] section shows
active/idle workers per pool — if idle=0 everywhere, your fleet is
saturated and pages are queueing. The [MariaDB] line surfaces
threads_connected and slow_queries_last_hour.
Exit code
This script always exits 0 after a successful run — it’s a reporter, not
a pass/fail check. Use audit-performance.sh if you want a non-zero exit
when something’s outside recommended bands.
audit-wp-vulnerabilities.sh
Enumerates installed plugins, themes, and (optionally) WordPress core via wp-cli, then cross-references each against the free wpvulnerability.net API. No API key required.
Useful flags
--domain=example.com— scan only one site--format=text|json— JSON for log shippers, text for humans--plugins-only/--themes-only— narrow scope--include-core— also check the WordPress core version (off by default)--dry-run— enumerate components but skip outbound API calls (safe for offline CI)
Try it
sudo bash audit/audit-wp-vulnerabilities.sh --domain=example.com --include-core
You get a one-line summary like found 3 vulnerabilities (critical=1,
high=2) followed by indented blocks with the CVE id, CVSS score, and the
component that’s exposed. The note: no fix available upstream line means
no patched version exists — your only options are removal, isolation, or
WAF rules.
Exit codes
0— no known vulnerabilities matched1— at least one matched (any severity)64— bad arguments65— no WordPress sites found
audit-performance.sh
Compares your live Apache, PHP-FPM, OPcache, MariaDB, and Redis settings
against the recommended values for the server’s RAM tier
(small < 2 GiB, medium 2–8 GiB, large >= 8 GiB). Same tier mapping the
installer uses, so you can tell when a host has drifted off-spec.
Useful flags
--service=apache|php-fpm|opcache|mariadb|redis|all— limit to one subsystem (defaultall)--format=text|json--dry-run— show what it would query
Try it
sudo bash audit/audit-performance.sh --service=opcache
The output is a table: Service | Tunable | Current | Recommended | Stat |
Note. Stat is OK, WARN (current is more than 2x or less than 0.5x the
recommended value), or CRIT. The most common CRIT you’ll see is
opcache.validate_timestamps=1 in production — that re-stats every PHP
include on every request. Fix it and the audit goes green.
Exit codes
0— every checked tunable OK1— at least one WARN2— at least one CRIT (e.g.validate_timestamps=1, redis unbounded, mariadb unreachable)
Common workflows
Quick site health check — what most operators run first thing:
sudo bash audit/audit-wp-health.sh --domain=example.com
Pre-upgrade vuln scan — run before bumping plugin versions or pushing new code so you know which CVEs the deploy clears:
sudo bash audit/audit-wp-vulnerabilities.sh
Find why the server’s slow — start with a live dashboard, then drill into config drift if the metrics look weird:
sudo bash audit/audit-system-metrics.sh --watch=5
# (Ctrl-C, then:)
sudo bash audit/audit-performance.sh
The first one shows you what is over budget right now. The second tells
you whether the config explains it — e.g. PHP-FPM max_children=5 on a
medium-tier box means you’re hitting the worker ceiling, not a real load
problem.
JSON output for monitoring
Both audit-system-metrics.sh --format=json and audit-performance.sh
--format=json emit a single JSON document per run, suitable for cron jobs
and log shippers (Vector, Fluent Bit, Promtail).
Example /etc/cron.d/litesoup-audit snippet:
*/5 * * * * root /usr/local/bin/litesoup-audit/audit-system-metrics.sh --format=json >> /var/log/litesoup/metrics.jsonl
0 * * * * root /usr/local/bin/litesoup-audit/audit-performance.sh --format=json >> /var/log/litesoup/perf.jsonl
That’s metrics every 5 minutes and a config-drift check every hour. Point
your shipper at /var/log/litesoup/*.jsonl and you have a free monitoring
pipeline. The performance script’s exit code (0/1/2) also means you can wrap
it in any alerting that watches process exits — e.g. systemd OnFailure=
or a simple || mail-on-fail in the cron line.