# vps-audit: A Single Bash Script for Auditing a Debian or Ubuntu VPS

> The nuver-labs/vps-audit script checks SSH configuration, firewalls, fail2ban jails, open ports and resource usage, then writes a timestamped report. It is a quick first pass for a Debian or Ubuntu box, not a substitute for a real audit.

**nuver-labs/vps-audit** — lightweight, dependency-free bash script for security, performance auditing and infrastructure monitoring of Linux servers.

- Repository: https://github.com/nuver-labs/vps-audit
- Website: https://nuverlabs.com/vps-audit?ref=github
- Stars: 3,149 · Forks: 306
- Language: Shell
- License: MIT
- Published: 2026-09-24 · Updated: 2026-09-24 · Language: en
- Canonical page: https://hysenlabs.com/projects/nuver-labs-vps-audit

## What vps-audit checks, and who it is written for

vps-audit is a single Bash file that walks a Linux server through a fixed list of checks and prints a colour-coded result for each one. The scope is deliberately narrow: SSH configuration (root login, password authentication, whether the daemon is on a non-default port), firewall state across UFW, firewalld, iptables and nftables, intrusion prevention via Fail2ban or CrowdSec, failed login attempts, pending system updates, running services, listening ports, sudo logging, password policy in pwquality.conf, and SUID files. A second group covers disk, memory, CPU and active internet connections.

The audience is the person who has just provisioned a VPS and wants to know what is exposed before putting anything on it. That is a real gap. A fresh Debian image ships with root SSH login possible, no firewall rules, and a service list you did not choose. The script's own README frames the goal as producing "a detailed report with recommendations for improvements", so the output is meant to be read, not just counted.

The design choice that matters most is what is absent: no package manager, no Python, no agent, no daemon. The requirements list is Ubuntu or Debian, root or sudo, and tools that are effectively always present (ufw, systemd, netstat/ss, grep, awk). That means you can pipe it over SSH into a machine you do not want to install anything on, which is the correct constraint for a host you are still assessing.

## How the checks are wired: thresholds, config paths and the report file

The script is not a framework. It is a linear sequence of checks whose behaviour is controlled by variables in a Configuration block at the top of the file, and the README documents that block in full. Two groups of variables matter.

The first group sets the numeric bands that decide PASS, WARN and FAIL. Resource usage warns between 50 and 80 percent and fails above 80. Running services warn between 20 and 40 and fail above 40. Failed logins warn between 10 and 50 and fail above 50. Open ports warn between 10 and 20 and fail above 20. Password policy passes when minlen in pwquality.conf is at least 12. These are fixed defaults, not adaptive ones, and the README is explicit that they are adjustable, which is the honest way to present them.

The second group is file paths. OS_RELEASE_FILE, REBOOT_REQUIRED_FILE, SSH_CONFIG_FILE, AUTH_LOG_FILE, SUDOERS_FILE, PASSWORD_QUALITY_CONF and FAIL2BAN_CONFIG_DIR all default to the standard Debian locations (/etc/ssh/sshd_config, /var/log/auth.log, /etc/security/pwquality.conf, /etc/fail2ban). Output goes to DEFAULT_REPORT_DIR, which defaults to the current directory, under the name vps-audit-report-[TIMESTAMP].txt. Ownership is handled by ENABLE_CHOWN, off by default; when switched on, REPORT_CHOWN_OWNER defaults to the user who invoked sudo, which avoids leaving a root-owned report in a normal user's home directory.

One check deserves attention because it catches a class of bug rather than a missing package: Fail2ban SSH jail port alignment. A jail watching port 22 while sshd listens elsewhere bans nobody, and nothing in the logs says so. That check is the most specific thing in the tool.

## Installing vps-audit and running the first audit

There is no package and no installer. The README gives two download commands against the raw file on the main branch, then a chmod. Run these on the server you want to audit, or download locally and copy the file across.

```bash
wget https://raw.githubusercontent.com/Nuver-Labs/vps-audit/main/vps-audit.sh
# or
curl -O https://raw.githubusercontent.com/Nuver-Labs/vps-audit/main/vps-audit.sh
```

After that, mark it executable. The README uses exactly this line:

```bash
chmod +x vps-audit.sh
```

Then run it with sudo. Most checks read files under /etc and /var/log, and the failed-login check reads /var/log/auth.log, so a non-root run will silently under-report rather than fail loudly.

```bash
sudo ./vps-audit.sh
```

What you should see is live console output with three statuses: [PASS] in green, [WARN] in yellow, [FAIL] in red. The README's own example lines look like this: "[PASS] SSH Root Login - Root login is properly disabled in SSH configuration", "[WARN] SSH Port - Using default port 22 - consider changing to a non-standard port", and "[FAIL] Firewall Status - UFW firewall is not active - your system is exposed". When the run finishes, a file named vps-audit-report-[TIMESTAMP].txt is written to the current directory, containing every result, recommendations for the failed checks, resource statistics and the audit timestamp.

If you want the report somewhere else, open the script and change DEFAULT_REPORT_DIR in the Configuration block before running it. To keep the report owned by your login user rather than root, set ENABLE_CHOWN to true.

## Where vps-audit gets it wrong, or cannot see at all

The hard boundary is the platform. The README states the script is designed for Debian and Ubuntu based systems, and the defaults confirm it: /var/log/auth.log is a Debian convention, and RHEL-family distributions log authentication to /var/log/secure. Copy the script to AlmaLinux or Rocky and the failed-login check reads a file that does not exist. You can point AUTH_LOG_FILE elsewhere, but you are then testing an untested path.

The thresholds are the second problem, and they are a design trade-off rather than a bug. A WARN at 50 percent memory is reasonable on a small VPS and noise on a build host that runs at 70 percent by design. Twenty running services is generous on a minimal web server and tight on a machine running a container runtime. The README treats these as starting points to be edited, which is fair, but it means the default PASS/WARN/FAIL line is a generic opinion about servers, not a judgement about yours.

The check list is also entirely local and configuration-shaped. Nothing verifies that a firewall rule is reachable from outside, that certificates are valid, or that a service is doing what its unit file claims. It reads files and counts things. A host can pass every check while running an unpatched application exposed on port 443, because application-level exposure is outside the scope.

Finally, the README does not document rollback, and there is nothing to roll back: the script only reads and writes its own report. The risk is the opposite one, that a clean report is read as a clean bill of health. The README says plainly that the script should not be your only security measure.

## How vps-audit differs from Lynis and from configuration management

The obvious comparison is Lynis, the long-standing Unix auditing tool. The difference is packaging and depth. Lynis is a larger system with its own test library, a hardening index, plugins and a suggestion engine; you install it and it keeps state between runs. vps-audit is one shell file with a fixed set of checks and a flat report. If you need a scored hardening baseline that you can track over time, Lynis is the more developed instrument. If you want to read the whole tool before you run it, vps-audit is small enough to do that in one sitting, which matters when the machine is one you do not yet trust.

The other alternative is not a scanner at all: Ansible, or a cloud-init script, that asserts the desired state rather than reporting the current one. That approach prevents drift instead of detecting it, and it scales to a fleet. vps-audit does not manage anything, so it cannot fix the firewall rule it just flagged. The two are complementary, and the sensible split is to encode known-good configuration in your provisioning tool and use vps-audit to check whether a running host still matches it.

## Maintenance, licence and the cost of keeping it current

The repository is not archived. The last push was on 2026-08-10, which is roughly six weeks before this article, and the two releases, v0.1.0 and v0.2.0, both landed on 2026-08-10. That is a young project with a short release history, and the version numbers say so: v0.2.0 is a second minor release, not a stabilised tool.

Upgrade cost is close to zero by construction. There is no dependency graph, no lockfile and no service to restart. Replacing the file with a newer one from the repository is the whole upgrade, and because the behaviour lives in a Configuration block at the top of that same file, a local edit to a threshold will be overwritten by a straight copy. If you tune RESOURCE_FAIL or AUTH_LOG_FILE, keep your version under revision control or reapply the edit after each update.

The licence is MIT, which permits commercial use, modification and redistribution provided the copyright notice and permission notice are included. That is permissive enough for internal use on client servers. This is a description of the licence text, not legal advice; if you redistribute the script inside a product, read the LICENSE file in the repository and take your own counsel.

## Conclusion

Adopt vps-audit if you run Debian or Ubuntu servers and want a repeatable first pass over SSH configuration, firewall state, fail2ban jails, open ports and resource usage, with a report file you can diff between runs. Do not adopt it as your only security control: the README itself says it is not a replacement for a professional security audit, and it will not run usefully on RHEL-family systems or read logs at paths other than /var/log/auth.log without editing the Configuration block. Before trusting a FAIL line, open vps-audit.sh and check the thresholds (RESOURCE_WARN=50, RESOURCE_FAIL=80, LOGINS_FAIL=50, OPEN_PORTS_FAIL=20) against your own workload, and confirm which AUTH_LOG_FILE and SSH_CONFIG_FILE the script is actually reading on your host.

## FAQ

### What is vps-audit and what does it check?

It is a dependency-free Bash script that audits a Linux VPS for security and performance issues. The checks cover SSH configuration, firewall status across UFW, firewalld, iptables and nftables, Fail2ban or CrowdSec configuration, failed logins, pending updates, running services, open ports, sudo logging, password policy and SUID files, plus disk, memory, CPU and active connections.

### Which Linux distributions does vps-audit support?

The README states it is designed for Ubuntu and Debian based systems, and the default file paths confirm that, since AUTH_LOG_FILE points at /var/log/auth.log. RHEL-family distributions log authentication elsewhere, so the failed-login check would need AUTH_LOG_FILE changed before it reads anything useful.

### Does vps-audit need root access to run?

Yes. The requirements list root access or sudo privileges, and the usage section shows the script being run as sudo ./vps-audit.sh. Most of the checks read files under /etc and /var/log, including SSH_CONFIG_FILE and AUTH_LOG_FILE.

### How do I install vps-audit on my server?

There is no package. The README downloads the raw script from the main branch with wget or curl, then runs chmod +x vps-audit.sh, then executes it with sudo. It writes a report file named vps-audit-report-[TIMESTAMP].txt into the current directory by default.

### Can I change the thresholds that decide PASS, WARN and FAIL?

Yes. The README documents a Configuration block at the top of the script where RESOURCE_WARN, RESOURCE_FAIL, SERVICES_WARN, SERVICES_FAIL, LOGINS_WARN, LOGINS_FAIL, OPEN_PORTS_WARN, OPEN_PORTS_FAIL and PASSWORD_MINLEN can all be edited. Because they live in the script file, a straight copy of a newer version will overwrite the edits.

### Is vps-audit a replacement for a professional security audit?

No. The README states directly that it is not a replacement for a professional security audit and that it should not be your only security measure. The checks are local and configuration-shaped, so application-level exposure is outside what the script can see.

## Sources

- [License: MIT](https://github.com/nuver-labs/vps-audit/blob/main/LICENSE)
- [nuver-labs/vps-audit on GitHub](https://github.com/nuver-labs/vps-audit)
- [Project website](https://nuverlabs.com/vps-audit?ref=github)
- [README](https://github.com/nuver-labs/vps-audit/blob/main/README.md)
- [Releases](https://github.com/nuver-labs/vps-audit/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/nuver-labs-vps-audit
