Get started

Download.
Verify. Run.

One static binary, no installation. Copy it to the host, run it with sudo, and read the results in the terminal UI or as JSON. Commands below follow the architecture you pick.

01Requirements

Ubuntu 18.04, 20.04, 22.04, 24.04, 26.04, on amd64 or arm64. Run dpkg --print-architecture on the host to see which binary it needs. Other architectures, including 32-bit armhf, are not supported.

OutputHostBinary
amd64x86-64ubuntu-sys-audit-linux-amd64
arm6464-bit ARMubuntu-sys-audit-linux-arm64

Run it with sudo for full coverage. Without root it still runs, but items it cannot read are marked “Not checked” and the report warns you. The host needs no agent, compiler or extra packages.

02Download and run

Download the binary and the checksums from the latest release, check them, and run.

install · amd64
curl -fsSLO https://github.com/guanting112/ubuntu-sys-audit/releases/latest/download/ubuntu-sys-audit-linux-amd64curl -fsSLO https://github.com/guanting112/ubuntu-sys-audit/releases/latest/download/SHA256SUMSsha256sum --ignore-missing -c SHA256SUMSchmod +x ubuntu-sys-audit-linux-amd64sudo ./ubuntu-sys-audit-linux-amd64

The opening screen disappears on its own after a moment, or on any key. The scan is already running behind it, so it costs no time.

03Verify the binary

SHA256SUMS only catches a corrupted download, because it sits next to the binaries. To confirm a binary was built by this repository’s workflow (releases after v0.1.3), check its build provenance attestation:

verify with a GitHub login
gh attestation verify ubuntu-sys-audit-linux-amd64 -R guanting112/ubuntu-sys-audit

Releases from v0.1.4 on also carry the attestation as ubuntu-sys-audit.sigstore.json, one file for both binaries. With it, gh needs no GitHub login, so you can verify on the host itself:

verify offline with the Sigstore bundle
curl -fsSLO https://github.com/guanting112/ubuntu-sys-audit/releases/latest/download/ubuntu-sys-audit.sigstore.jsongh attestation verify ubuntu-sys-audit-linux-amd64 -R guanting112/ubuntu-sys-audit --bundle ubuntu-sys-audit.sigstore.json

04Read the results

On a terminal it opens the TUI: categories on the left, findings in the middle, and the selected finding’s detail, remediation and evidence on the right.

KeysAction
↑↓ or j kMove
tabSwitch pane
fFilter by severity
/Search
sSave JSON to the current directory
qQuit

Not checked never means passed. Items that lacked permission, timed out or could not reach the network are shown as “Not checked” (skipped in JSON) and make the exit code 3 unless there are critical or high findings.

05Scan a fleet over SSH

The tool writes JSON automatically when there is no TTY, so you can collect reports over SSH:

collect reports
for h in web-01 web-02 db-01; do  ssh "$h" 'sudo "./ubuntu-sys-audit-linux-$(dpkg --print-architecture)"' > "audit-$h.json"  echo "$h exit=$?"done

The loop requires passwordless sudo on the host. If sudo asks for a password, allocate a TTY and save the report to a file, then fetch it. A TTY would otherwise mix the password prompt into stdout:

when sudo needs a password
ssh -t "$h" 'sudo "./ubuntu-sys-audit-linux-$(dpkg --print-architecture)" --json -o audit.json > /dev/null'scp "$h:audit.json" "audit-$h.json"

The report has mode 0600 and its owner is set back to the user who ran sudo, so scp can fetch it directly. -o only creates new files, so remove an old report first.

Exit codes

CodeMeaning
0Nothing to act on.
1Medium findings.
2Critical or high findings.
3Some items could not be checked, so do not treat the host as clean.
130The scan was aborted.

06Check a specific CVE

When a CVE is announced, ask each host about it directly:

CVE lookup
sudo ./ubuntu-sys-audit-linux-amd64 --cve CVE-2026-98432,CVE-2024-6387

This runs only the lookup. It reads Canonical’s CVE data for the release, which also lists CVEs with no fix released yet, and answers each CVE: affected with a fix available, affected with no fix released, fixed in the installed version, or not affected. An affected host gets the CVE’s own priority as the severity, so exit code 2 marks the hosts a high or critical CVE reaches.

The normal scan does not list unfixed CVEs, because every host has hundreds of them in the kernel alone. Ubuntu’s data does not tell a fix in progress from a CVE still being triaged, so “no fix released” may turn out not to apply.

07Hosts without internet access

On a machine with internet access, download the OVAL file for the host’s release, copy it over and point the tool at it. The report warns you when the data is more than 14 days old.

ReleaseCodenameUSN feed
18.04bioniccom.ubuntu.bionic.usn.oval.xml.bz2
20.04focalcom.ubuntu.focal.usn.oval.xml.bz2
22.04jammycom.ubuntu.jammy.usn.oval.xml.bz2
24.04noblecom.ubuntu.noble.usn.oval.xml.bz2
26.04resolutecom.ubuntu.resolute.usn.oval.xml.bz2
offline scan (22.04 example)
# bionic=18.04  focal=20.04  jammy=22.04  noble=24.04  resolute=26.04curl -fsSLO https://security-metadata.canonical.com/oval/com.ubuntu.jammy.usn.oval.xml.bz2sudo ./ubuntu-sys-audit-linux-amd64 --offline --oval-file com.ubuntu.jammy.usn.oval.xml.bz2 # --cve reads the CVE feed insteadcurl -fsSLO https://security-metadata.canonical.com/oval/com.ubuntu.jammy.cve.oval.xml.bz2sudo ./ubuntu-sys-audit-linux-amd64 --offline --oval-file com.ubuntu.jammy.cve.oval.xml.bz2 --cve CVE-2026-98432

08Output formats

Without a TTY the output is JSON. With one, the TUI opens unless you ask for --json or --text. -o saves a JSON copy alongside any of them, and never overwrites an existing file.

formats
sudo ./ubuntu-sys-audit-linux-amd64 --json > report.json            # JSON to stdoutsudo ./ubuntu-sys-audit-linux-amd64 --text --min-severity high     # plain text, high and abovesudo ./ubuntu-sys-audit-linux-amd64 -o audit.json                  # TUI, and also save JSON

Common forms of credentials in command lines and configuration are masked, but this cannot catch every form. Treat reports as sensitive.

09All options

OptionDescription
--json Write JSON to stdout without opening the TUI.
--text Write plain text to stdout without opening the TUI.
--min-severity LVIn text mode, list only this level and above: critical, high, medium, info, ok (default medium). Items that could not be checked are always listed.
--cve LISTOnly look up these CVEs, separated by commas, including ones with no fix released yet. Downloads Canonical’s CVE data for this release (5 to 15 MB).
-o, --output FILEAlso save the JSON report to a new FILE (mode 0600). An existing file is never overwritten.
--offline Do not use the network. CVEs are not checked unless --oval-file is given.
--oval-file PATHUse a local OVAL file (.xml or .xml.bz2). With --cve, this is the CVE feed.
--proxy URLHTTP proxy for downloading advisory data.
--skip-fs Skip the full filesystem scan (SUID, capabilities, temp directories).
--fs-timeout TIMETime limit for the full filesystem scan (default 5m).
--no-netlink Do not read BPF filters, which keeps the kernel from loading af_packet_diag.
--version Show the version.