This guide outlines the process for conducting regular monthly vulnerability scans using Vuls in a containerized environment. The process ensures consistent, automated vulnerability assessments across your infrastructure.
- Docker and Docker Compose installed
- Vuls container with AWS CLI and GCP CLI
- SSH access to target systems (direct or via AWS Session Manager)
- Vulnerability databases configured
Frequency: Monthly (or weekly for high-security environments)
IMPORTANT - OS Version Limitations:
- Ubuntu OVAL: Only covers currently supported LTS versions (20.04, 22.04, 24.04)
- Debian OVAL: Only covers currently supported versions (10, 11, 12)
- End-of-Life (EOL) systems: Cannot be properly scanned due to missing OVAL data
- Recently released versions: May show 0 vulnerabilities if well-patched
Supported OS Versions for Vulnerability Scanning:
- ✅ Ubuntu: 20.04 LTS (Focal), 22.04 LTS (Jammy), 24.04 LTS (Noble)
- ✅ Debian: 10 (Buster), 11 (Bullseye), 12 (Bookworm)
- ✅ RHEL/CentOS: 7, 8, 9
- ✅ Amazon Linux: 1, 2, 2023
- ❌ Ubuntu 16.04/18.04: EOL - Limited or no OVAL data available
- ❌ Debian 8/9: EOL - Limited or no OVAL data available
# Navigate to your Vuls directory
cd ~/docker/vuls
# Update NVD (CVE) database - most critical
docker compose --profile fetch up vuls-nvd
# Update OS-specific databases (only supported versions)
docker compose --profile fetch up vuls-ubuntu # Ubuntu 20.04, 22.04, 24.04
docker compose --profile fetch up vuls-debian # Debian 10, 11, 12
docker compose --profile fetch up vuls-redhat # RHEL/CentOS 7, 8, 9
docker compose --profile fetch up vuls-amazon # Amazon Linux 1, 2, 2023
# Verify database updates
ls -la ./db/
du -sh ./db/*Expected Database Sizes:
cve.sqlite3: 1-2GB (NVD database - ~280K CVEs)oval.sqlite3: 200-400MB (OS-specific vulnerabilities - ~200K definitions)
Database Coverage Verification:
# Check which OS versions are covered
docker compose run --rm --entrypoint sqlite3 vuls /vuls/db/oval.sqlite3 "SELECT DISTINCT substr(title, instr(title, 'Ubuntu'), 20) FROM definitions WHERE title LIKE '%Ubuntu%' LIMIT 5;"
# Check total definitions count
docker compose run --rm --entrypoint sqlite3 vuls /vuls/db/oval.sqlite3 "SELECT COUNT(*) FROM definitions;"# Check database timestamps
stat ./db/*.sqlite3
# Test database connectivity
docker-compose run --rm vuls configtestReview and update your config/config.toml:
[cveDict]
type = "sqlite3"
SQLite3Path = "/vuls/db/cve.sqlite3"
[ovalDict]
type = "sqlite3"
SQLite3Path = "/vuls/db/oval.sqlite3"
[gost]
type = "sqlite3"
SQLite3Path = "/vuls/db/gost.sqlite3"
[exploit]
type = "sqlite3"
SQLite3Path = "/vuls/db/go-exploitdb.sqlite3"
[metasploit]
type = "sqlite3"
SQLite3Path = "/vuls/db/go-msfdb.sqlite3"
[kevuln]
type = "sqlite3"
SQLite3Path = "/vuls/db/go-kev.sqlite3"
[cti]
type = "sqlite3"
SQLite3Path = "/vuls/db/go-cti.sqlite3"
[servers]
[servers.icinga2]
host = "icinga2"
port = "22"
user = "admin"
keypath = "/root/.ssh/id_aws"
[servers.anisette-v3]
host = "anisette-v3"
port = "22"
user = "ubuntu"
keypath = "/root/.ssh/id_aws"
[servers.retailaware-u16tbpe]
host = "retailaware-u16tbpe"# Test configuration for all systems
docker compose run --rm vuls configtest
# Test SSH connectivity to each system
docker compose run --rm --entrypoint ssh vuls admin@target-system
# Enter container for manual testing if needed
docker compose run --rm --entrypoint /bin/sh vuls
# Inside container:
# ssh -vvv admin@target-system
# aws sts get-caller-identity
# gcloud auth list
# exitWhen scanning multiple systems with different SSH keys, use SSH agent for seamless key management:
On Host System (before scanning):
# Start SSH agent
eval $(ssh-agent)
# Add specific keys for different systems
ssh-add ~/.ssh/id_aws # AWS EC2 instances
ssh-add ~/.ssh/id_gcp # GCP instances
ssh-add ~/.ssh/id_ed25519 # On-premise systems
ssh-add ~/.ssh/id_rsa # Legacy systems
# Verify keys are loaded
ssh-add -l
# Test connectivity with agent
ssh your-target-system # Should work without specifying key
# Configure SSH agent forwarding in your SSH config
cat >> ~/.ssh/config << 'EOF'
host *
IdentityFile ~/.ssh/id_aws
IdentitiesOnly yes
host icinga2
User admin
Hostname i-0a1347a614cf7cea5
ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
ControlPersist 72h
host anisette-v3
User ubuntu
HostName i-022d1ec1b8c62660b
ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
Host retailaware-u16tbpe
User paulb
IdentityFile ~/.ssh/id_gcp
IdentitiesOnly yes
ProxyCommand gcloud compute ssh %h --tunnel-through-iap --zone=us-east1-b --project=thingsboard-210800 -- -W %h:%p
EOFIn Container (SSH agent forwarding): Update your docker-compose.yml to enable SSH agent forwarding:
services:
vuls:
build: build/vuls
container_name: vuls-scanner
volumes:
- ./config:/vuls/config
# SSH agent socket forwarding
- $SSH_AUTH_SOCK:/ssh-agent
environment:
- SSH_AUTH_SOCK=/ssh-agent
# ... other environment variablesAlternative: Multiple SSH configs:
# Create separate SSH configs for different key types
mkdir -p ./ssh-configs
# AWS systems config
cat > ./ssh-configs/aws_config << 'EOF'
Host aws-*
IdentityFile /root/.ssh/id_aws
User admin
StrictHostKeyChecking no
Host i-*
ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p' --region eu-west-2"
User admin
IdentityFile /root/.ssh/id_aws
EOF
# GCP systems config
cat > ./ssh-configs/gcp_config << 'EOF'
Host gcp-*
IdentityFile /root/.ssh/id_gcp
User ubuntu
StrictHostKeyChecking no
EOF
# Mount configs in container
# - ./ssh-configs:/root/.ssh/config.d:roSSH Agent Workflow:
# Monthly scanning workflow with SSH agent
cd ~/docker/vuls
# 1. Start SSH agent and load keys
eval $(ssh-agent)
ssh-add ~/.ssh/id_aws ~/.ssh/id_gcp ~/.ssh/id_ed25519
# 2. Test connectivity
ssh incing2
ssh anisette-v3
ssh retailaware-u16tbpe
# 3. Run Vuls scan (will use agent keys)
docker compose run --rm vuls scan
# 4. Generate reports
docker compose run --rm vuls report
# 5. Clean up agent when done
ssh-agent -kTroubleshooting SSH Agent Issues:
# Check if agent is running
echo $SSH_AUTH_SOCK
ps aux | grep ssh-agent
# List loaded keys
ssh-add -l
# Remove all keys and reload
ssh-add -D
ssh-add ~/.ssh/id_aws ~/.ssh/id_gcp
# Test specific key
ssh -i ~/.ssh/id_aws admin@target-system
# Debug SSH connection
ssh -vvv target-system- Vulnerability databases updated
- All target systems accessible
- SSH keys properly mounted
- AWS/GCP credentials configured
- Previous scan results backed up
# Create monthly results directory
SCAN_DATE=$(date +%Y-%m)
mkdir -p ./results/monthly-scans/$SCAN_DATE
# Run comprehensive scan
docker compose run --rm vuls scan
# Generate detailed reports
docker compose run --rm vuls report -format-json
docker compose run --rm vuls report -format-full-text
docker compose run --rm vuls report -format-csv# Check scan completed successfully
ls -la ./results/$(date +%Y-%m-%d)*
# Verify all systems were scanned
docker-compose run --rm vuls report -format-one-line-text# Create executive summary
docker compose run --rm vuls report -format-list > ./results/monthly-scans/$SCAN_DATE/executive-summary.txt
# Generate detailed CSV for tracking
docker compose run --rm vuls report -format-csv > ./results/monthly-scans/$SCAN_DATE/detailed-vulnerabilities.csv
# Create system-by-system breakdown
docker compose run --rm vuls report -format-full-text > ./results/monthly-scans/$SCAN_DATE/full-report.txtCritical Actions Required:
- Critical/High vulnerabilities: Immediate action required
- Medium vulnerabilities: Plan remediation within 30 days
- Low vulnerabilities: Include in next maintenance window
- 0 vulnerabilities: Verify interpretation (see below)
Understanding Zero Vulnerability Results:
✅ Legitimate Zero Vulnerabilities (Good):
- Recent LTS systems: Ubuntu 24.04, Debian 12 (well-patched)
- Actively maintained systems: Regular security updates applied
- Container images: Recent base images with security patches
- EOL systems: Ubuntu 16.04/18.04, Debian 8/9 showing 0 CVEs
- Scan errors: "Skip OVAL" messages in logs
- Database issues: Missing OVAL data for target OS version
Validation Steps for Zero Vulnerability Results:
# Check if OVAL database covers your OS version
docker compose run --rm --entrypoint sqlite3 vuls /vuls/db/oval.sqlite3 "SELECT COUNT(*) FROM definitions WHERE title LIKE '%Ubuntu 18.04%';"
# Look for OVAL skip messages in scan logs
docker compose run --rm vuls scan -debug 2>&1 | grep -i "skip.*oval"
# Verify system is actually supported
docker compose run --rm vuls configtest -debug | grep -i "detected"Priority Matrix:
- CVSS 9.0-10.0 (Critical) → Patch within 72 hours
- CVSS 7.0-8.9 (High) → Patch within 7 days
- CVSS 4.0-6.9 (Medium) → Patch within 30 days
- CVSS 0.1-3.9 (Low) → Next maintenance cycle
- 0 CVEs on EOL systems → Urgent OS upgrade required
# Compare with previous month
diff ./results/monthly-scans/$(date -d "last month" +%Y-%m)/executive-summary.txt \
./results/monthly-scans/$SCAN_DATE/executive-summary.txt
# Track vulnerability counts over time
echo "$(date +%Y-%m): $(grep -c 'CVE-' ./results/monthly-scans/$SCAN_DATE/detailed-vulnerabilities.csv)" >> vulnerability-trends.log# Extract high-priority vulnerabilities
grep -E "(Critical|High)" ./results/monthly-scans/$SCAN_DATE/detailed-vulnerabilities.csv > high-priority-vulns.csv
# Create remediation tickets/tasks
# (Integrate with your ticketing system)Create a tracking spreadsheet with:
- CVE ID
- Affected System
- Severity
- Discovery Date
- Assigned Owner
- Target Remediation Date
- Status
- Verification Date
# Generate compliance report
cat > ./results/monthly-scans/$SCAN_DATE/compliance-report.md << EOF
# Monthly Vulnerability Assessment Report - $SCAN_DATE
## Executive Summary
- Systems Scanned: $(grep -c "\[servers\." config/config.toml)
- Total Vulnerabilities: $(grep -c "CVE-" ./results/monthly-scans/$SCAN_DATE/detailed-vulnerabilities.csv)
- Critical: $(grep -c "Critical" ./results/monthly-scans/$SCAN_DATE/detailed-vulnerabilities.csv)
- High: $(grep -c "High" ./results/monthly-scans/$SCAN_DATE/detailed-vulnerabilities.csv)
- Medium: $(grep -c "Medium" ./results/monthly-scans/$SCAN_DATE/detailed-vulnerabilities.csv)
- Low: $(grep -c "Low" ./results/monthly-scans/$SCAN_DATE/detailed-vulnerabilities.csv)
## Remediation Status
- Patched This Month: [To be filled]
- In Progress: [To be filled]
- Scheduled: [To be filled]
## Next Month Actions
- [List planned remediation activities]
EOF# Compress monthly results
tar -czf ./archive/vulnerability-scan-$SCAN_DATE.tar.gz ./results/monthly-scans/$SCAN_DATE/
# Clean up old detailed results (keep last 6 months)
find ./results/ -type d -name "20*" -mtime +180 -exec rm -rf {} \;#!/bin/bash
# monthly-vuln-scan.sh
set -e
SCAN_DATE=$(date +%Y-%m)
LOG_FILE="./logs/monthly-scan-$SCAN_DATE.log"
echo "Starting monthly vulnerability scan for $SCAN_DATE" | tee -a $LOG_FILE
# Update databases
echo "Updating vulnerability databases..." | tee -a $LOG_FILE
docker compose --profile fetch up vuls-nvd vuls-ubuntu vuls-debian
# Validate configuration
echo "Validating configuration..." | tee -a $LOG_FILE
docker compose run --rm vuls configtest
# Run scan
echo "Executing vulnerability scan..." | tee -a $LOG_FILE
docker compose run --rm vuls scan
# Generate reports
echo "Generating reports..." | tee -a $LOG_FILE
mkdir -p ./results/monthly-scans/$SCAN_DATE
docker compose run --rm vuls report -format-csv > ./results/monthly-scans/$SCAN_DATE/vulnerabilities.csv
docker compose run --rm vuls report -format-list > ./results/monthly-scans/$SCAN_DATE/summary.txt
echo "Monthly scan completed successfully" | tee -a $LOG_FILE#!/bin/bash
# update-vuln-databases.sh
echo "Updating Vuls vulnerability databases..."
# Update all databases
docker compose --profile fetch up vuls-nvd
docker compose --profile fetch up vuls-ubuntu
docker compose --profile fetch up vuls-debian
docker compose --profile fetch up vuls-redhat
# Log update completion
echo "$(date): Database update completed" >> ./logs/database-updates.log
# Check database sizes
du -sh ./db/* >> ./logs/database-sizes.logFor troubleshooting, manual testing, or detailed inspection:
# Enter container with shell access
docker compose run --rm --entrypoint /bin/sh vuls
# Alternative: Enter with bash if available
docker compose run --rm --entrypoint /bin/bash vulsOnce inside the container, you can:
# Check Vuls version and help
vuls --version
vuls help
# Inspect configuration
cat /vuls/config.toml
# Check database files
ls -la /vuls/db/
du -sh /vuls/db/*
# Test connectivity
ping target-system
ssh -T admin@target-system
# AWS/GCP commands
aws sts get-caller-identity
aws ssm describe-instance-information
gcloud auth list
gcloud config list
# Manual scan commands
vuls configtest
vuls scan -debug
vuls report -format-list
# Check logs
tail -f /vuls/logs/vuls.log
cat /var/log/vuls/vuls.log
# Exit container
exit# Start an interactive session for debugging
docker compose run --rm --entrypoint /bin/sh vuls
# Inside container - comprehensive system check:
echo "=== Vuls Environment Check ==="
echo "Vuls version: $(vuls --version)"
echo "Config file: $(ls -la /vuls/config.toml)"
echo "Databases: $(ls -la /vuls/db/)"
echo "SSH keys: $(ls -la /root/.ssh/)"
echo "AWS CLI: $(aws --version 2>/dev/null || echo 'Not available')"
echo "GCloud CLI: $(gcloud --version 2>/dev/null || echo 'Not available')"
echo "Session Manager: $(session-manager-plugin --version 2>/dev/null || echo 'Not available')"
# Test database connectivity
sqlite3 /vuls/db/cve.sqlite3 "SELECT COUNT(*) AS cve_count FROM cves;" 2>/dev/null || echo "CVE database not accessible"
# Test configuration
vuls configtest
exit- Rotate SSH keys regularly
- Use dedicated service accounts for scanning
- Implement least-privilege access
- Encrypt scan results at rest
- Secure database files
- Schedule scans during off-peak hours
- Use fast scan mode for regular scans
- Implement parallel scanning for large environments
- Monitor resource usage
- Keep vulnerability databases current
- Validate scan results manually
- Maintain accurate asset inventory
- Regular false positive analysis
- Integrate with ticketing systems
- Automate report distribution
- Connect to SIEM/logging systems
- Link with patch management tools
If you see this message in your Vuls output, it indicates that OVAL (Open Vulnerability and Assessment Language) scanning has been programmatically disabled. This is not a configuration or database issue.
Root Cause: Vuls automatically skips OVAL scanning for End-of-Life (EOL) operating systems, even when the OVAL database contains vulnerability definitions for those systems.
Affected Systems:
- ❌ Ubuntu 16.04 (Xenial): EOL April 2021 - OVAL scanning skipped
- ❌ Ubuntu 18.04 (Bionic): EOL May 2023 - OVAL scanning skipped
- ❌ Debian 8 (Jessie): EOL June 2020 - OVAL scanning skipped
- ❌ Debian 9 (Stretch): EOL July 2022 - OVAL scanning skipped
- ❌ CentOS 6: EOL November 2020 - OVAL scanning skipped
- ❌ CentOS 7: EOL June 2024 - OVAL scanning skipped
What This Means:
- Database is OK: Your OVAL database may contain 30,000+ vulnerability definitions for the EOL system
- Configuration is OK: Vuls correctly detects the target OS version
- Intentional Behavior: Vuls skips OVAL scanning by design for EOL systems
- Limited Detection: Only GOST, CPE, and other detection methods are used
Diagnostic Commands:
# Verify OVAL database has data for your EOL system
sudo sqlite3 db/oval.sqlite3 "SELECT COUNT(*) FROM definitions WHERE title LIKE '%ubuntu%16.04%' OR title LIKE '%xenial%';"
# Result: 34227 (or similar large number)
# Check if OVAL scanning is being skipped
docker compose run --rm vuls report -debug 2>&1 | grep -i "skip.*oval"
# Result: "Skip OVAL and Scan with gost alone."
# Confirm OS detection is working
docker compose run --rm vuls configtest retailaware-u16tbpe
# Result: "Detected: retailaware-u16tbpe: ubuntu 16.04"Solutions:
- Recommended: Upgrade EOL systems to supported versions (Ubuntu 20.04+, Debian 10+)
- Temporary: Accept limited vulnerability detection and implement compensating controls
- Documentation: Note the limitation in security assessments and compliance reports
Compliance Impact:
- Document that EOL systems cannot receive full vulnerability scanning
- Implement additional manual security reviews for EOL systems
- Plan system upgrades to restore full vulnerability scanning capability
- Consider this a high-priority security risk requiring remediation
Problem: SSH connections fail despite correct keys
Diagnosis:
# Check SSH agent status
echo $SSH_AUTH_SOCK
ssh-add -l
# Test SSH agent forwarding in container
docker compose run --rm --entrypoint /bin/sh vuls
# Inside container:
# echo $SSH_AUTH_SOCK
# ssh-add -l
# exitSolutions:
# Restart SSH agent and reload keys
ssh-agent -k
eval $(ssh-agent)
ssh-add ~/.ssh/id_aws ~/.ssh/id_gcp ~/.ssh/id_ed25519
# Update docker-compose.yml for SSH agent forwarding
# Add to volumes:
# - $SSH_AUTH_SOCK:/ssh-agent
# Add to environment:
# - SSH_AUTH_SOCK=/ssh-agentProblem: Systems showing 0 vulnerabilities unexpectedly
Diagnosis:
# Check which OS versions have OVAL data
docker compose run --rm --entrypoint sqlite3 vuls /vuls/db/oval.sqlite3 "SELECT DISTINCT substr(title, instr(title, 'Ubuntu'), 20) FROM definitions WHERE title LIKE '%Ubuntu%';"
# Check for OVAL skip messages
docker compose run --rm vuls report -debug 2>&1 | grep -i "skip.*oval"
# Verify OS detection
docker compose run --rm vuls configtest -debug | grep -i "detected"Solutions:
- EOL systems: Upgrade to supported OS versions or accept limited scanning
- Missing OVAL data: Verify OS version is in supported list
- Recent systems: May legitimately have 0 vulnerabilities
# Test SSH connectivity
docker compose run --rm --entrypoint ssh vuls -vvv target-system
# Check SSH key permissions
ls -la ./.ssh/
# Enter container for manual debugging
docker compose run --rm --entrypoint /bin/sh vuls
# Inside container:
# ls -la /root/.ssh/
# cat /root/.ssh/config
# ssh -T [email protected] # test key loading
# ssh -vvv admin@target-system
# exit# Verify AWS credentials
docker compose run --rm --entrypoint aws vuls sts get-caller-identity
# Test Session Manager
docker compose run --rm --entrypoint aws vuls ssm describe-instance-information
# Enter container for AWS debugging
docker compose run --rm --entrypoint /bin/sh vuls
# Inside container:
# aws configure list
# aws sts get-caller-identity
# aws ssm describe-instance-information
# which session-manager-plugin
# session-manager-plugin --version
# exit# Verify database integrity
sqlite3 ./db/cve.sqlite3 "PRAGMA integrity_check;"
# Check database sizes
du -sh ./db/*
# Enter container for database inspection
docker compose run --rm --entrypoint /bin/sh vuls
# Inside container:
# ls -la /vuls/db/
# sqlite3 /vuls/db/cve.sqlite3 "SELECT COUNT(*) FROM cves;"
# sqlite3 /vuls/db/oval.sqlite3 "SELECT name FROM sqlite_master WHERE type='table';"
# exit- NIST Cybersecurity Framework: Identify, Protect, Detect, Respond, Recover
- ISO 27001: Risk assessment and treatment
- PCI DSS: Regular vulnerability assessments
- SOC 2: System monitoring and vulnerability management
- Scan frequency and coverage
- Vulnerability assessment procedures
- Remediation timelines and tracking
- Risk acceptance documentation
- Evidence of continuous monitoring
- OS version limitations and coverage gaps
Important Compliance Notes:
- EOL System Risk: Document that EOL systems (Ubuntu 16.04/18.04, Debian 8/9) cannot be properly scanned
- Coverage Gaps: Explicitly note OS versions not covered by vulnerability databases
- False Negatives: Acknowledge potential for missed vulnerabilities on unsupported systems
- Compensating Controls: Implement additional security measures for EOL systems
Sample Compliance Language:
"Vulnerability scanning covers all systems running supported operating system versions
(Ubuntu 20.04+, Debian 10+, RHEL 7+). End-of-life systems require additional manual
security review and compensating controls due to limited vulnerability database coverage."
Regular monthly vulnerability scanning with Vuls provides continuous visibility into your security posture. This systematic approach ensures vulnerabilities are identified, prioritized, and remediated in a timely manner, supporting your overall cybersecurity strategy and compliance requirements.
Key Takeaways:
- OS Version Awareness: Ensure target systems run supported OS versions for accurate scanning
- Zero Vulnerability Validation: Always verify whether 0 CVEs indicates good security or scanning limitations
- EOL System Management: Plan upgrades for end-of-life systems that cannot be properly scanned
- Database Coverage: Regularly verify vulnerability database coverage matches your environment
Critical Success Factors:
- Maintain supported OS versions across your infrastructure
- Validate scan results don't just accept zero vulnerability counts
- Document coverage limitations for compliance and risk management
- Plan EOL system transitions before vulnerability database support ends
Remember to adapt this process to your organization's specific needs, risk tolerance, compliance requirements, and the reality of OS version limitations in vulnerability scanning tools.