LinuxXXXII · Vulnerability and Patch ManagementScanning
Scanning and detecting vulnerabilities
What you'll learn
- Scan a host for known CVEs
- Use package-level CVE matching
- Schedule regular scans
- Interpret scan results
Prerequisites
Verified against Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL 9.x · Rocky Linux 9.x · AlmaLinux 9.x · Linux kernel 6.1 LTS / 6.6 LTS · systemd 255+ · OpenSSH 8.7p1 (RHEL 9) / 9.6p1 (Ubuntu 24.04) · nftables 1.0.x · chrony 4.x · Pacemaker 2.1.x · Corosync 3.1.x · 2026-08-09
Vulnerability scanning matches installed packages against known CVEs. The tools and techniques vary by distribution and scanner.
Distribution-native scanning
Debian / Ubuntu
# Rough first look: which pending updates came from a security pocket
sudo apt list --upgradable 2>/dev/null | grep -i security
That grep is a string match on a repository name, not a CVE match. It tells you an update exists; it does not tell you which CVEs you are exposed to, which are already fixed by a backport, or which have no fix yet. For that you need a tool that correlates installed package versions against the security tracker data.
On Debian, that tool is debsecan:
sudo apt install debsecan
# Every CVE affecting installed packages, with severity and fix state
debsecan --suite bookworm --format detail
# Only the ones you can actually act on today
debsecan --suite bookworm --only-fixed --format packages
--suite must name the Debian release you are running
(bookworm, trixie), because the fix state of a CVE is
per-suite. --only-fixed is the difference between a
list you can work and a list you can only stare at.
On Ubuntu, debsecan reads Debian data, so its results do
not reflect Ubuntu’s own backports. Use Canonical’s OVAL feed
of Ubuntu Security Notices instead:
sudo apt install openscap-scanner # libopenscap8 on releases before 24.04
wget https://security-metadata.canonical.com/oval/com.ubuntu.noble.usn.oval.xml.bz2
bunzip2 com.ubuntu.noble.usn.oval.xml.bz2
oscap oval eval --results usn-results.xml com.ubuntu.noble.usn.oval.xml
Substitute the codename of the release you are scanning.
For a quick summary without OVAL, pro security-status
(formerly ubuntu-security-status) reports how many
installed packages are covered by which support stream.
RHEL family
# List security updates
sudo dnf check-update --security
# OpenSCAP scanning
sudo oscap xccdf eval \
--profile xccdf_org.ssgproject.content_profile_standard \
--results scan.xml \
--report scan.html \
/usr/share/xml/scap/content/ssg-rhel9-ds.xml
Vulnerability scanners
Trivy
# Install
sudo apt install wget gnupg lsb-release
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo gpg --dearmor -o /usr/share/keyrings/trivy.gpg
echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb generic main" | sudo tee /etc/apt/sources.list.d/trivy.list
sudo apt update && sudo apt install trivy
# Scan the host filesystem
sudo trivy fs /
# Scan a container image
sudo trivy image nginx:latest
# Output as JSON
sudo trivy fs --format json /
Vulners
Vulners is a hosted vulnerability database. There is no
vulners package in the Debian or Ubuntu archives; the
agent is a Python client that queries the Vulners API and
needs a key.
# Installed from PyPI, not from apt
pip install --user vulners
export VULNERS_API_KEY=... # required; the scanner is useless without it
# The audit ships the OS name, version, and installed package list to the API
python3 -m vulners.scanner
Read that last point before running it: the scan sends your
full package inventory to a third party. In a regulated
environment that is a data-transfer decision, not a tooling
decision. debsecan and the OVAL feeds do the same
correlation locally and need no key.
OpenSCAP
OpenSCAP answers two different questions with two different subcommands, and they are easy to confuse.
# COMPLIANCE: does this host conform to the benchmark? (CIS/STIG, not CVEs)
# `eval` evaluates the host. `generate guide` only renders the benchmark as
# HTML for a human to read - it inspects nothing and reports no findings.
sudo oscap xccdf eval \
--profile xccdf_org.ssgproject.content_profile_cis_level1_server \
--results xccdf-results.xml --report xccdf-report.html \
/usr/share/xml/scap/content/ssg-ubuntu2404-ds.xml
# VULNERABILITIES: which published CVEs affect the installed packages?
# This is OVAL against the distribution's advisory feed, not XCCDF.
wget -O ubuntu.oval.xml.bz2 \
https://security-metadata.canonical.com/oval/com.ubuntu.$(lsb_release -cs).usn.oval.xml.bz2
bunzip2 -f ubuntu.oval.xml.bz2
oscap oval eval --results oval-results.xml --report oval-report.html ubuntu.oval.xml
Continuous scanning
Schedule scans via cron / systemd timer:
# /etc/cron.d/vuln-scan
0 2 * * * root /usr/bin/trivy fs --quiet / > /var/log/trivy-scan.log 2>&1
For container images, scan in CI:
- name: Trivy scan
uses: aquasecurity/trivy-action@master
with:
image-ref: 'myapp:${{ github.sha }}'
format: 'table'
exit-code: '1'
ignore-unfixed: true
Interpret results
A scan report lists each CVE:
CVE-2024-12345 (Critical)
Package: openssl
Installed: 3.0.2-1
Fixed: 3.0.13-1
For each finding:
- Confirm the package version.
- Confirm the CVE is real and applies.
- Apply the fix or document the exception.
- Re-scan to verify.
False positives
Scanners produce false positives. Common causes:
- Patched version that the scanner does not recognise.
- Backported fix in a version that does not match the CVE.
- Distribution-specific patches.
- Kernel module or library not actually loaded.
Verify before acting on a finding.
Knowledge check
Knowledge check · 4 questions
Q1. Which command lists security updates on RHEL family?
Q2. A distribution that backports security fixes will make a version-matching scanner report vulnerabilities that are already closed.
Q3. Which of the following are valid vulnerability scanners? Select all that apply.
Q4. An auditor asks for evidence that a Debian fleet has been scanned for known CVEs. Your current evidence is the output of `apt list --upgradable | grep -i security`. Why is that not sufficient?
Passing score: 75%. Answers are checked in this browser.