OpenVAS Wrapper
Fully automated vulnerability scanner wrapper for OpenVAS/GVM with zero-config subnet detection, idempotent scan targets, PDF reporting, and SMTP delivery — designed to run unattended via cron for continuous security monitoring.
Overview
A Python-based automation layer that transforms OpenVAS/GVM from an interactive vulnerability scanner into a hands-off, cron-schedulable security monitoring system. The core innovation is **automatic runtime subnet detection** using `netifaces` to discover the active non-loopback interface and its CIDR range, eliminating hardcoded network configuration. The workflow is fully orchestrated: authenticate to GVM via Unix socket (`/run/gvmd/gvmd.sock`), create or reuse idempotent scan targets for the detected subnet, launch a **Full and Fast** scan using GVM's default scan configuration and port list, poll until completion (async task monitoring), extract the PDF report via GMP protocol, and deliver it as an email attachment through SMTP (defaults to Office 365 with STARTTLS). Includes the `scanner_app.sh` wrapper script that manages GVM daemon lifecycle (gvm-start → scan → gvm-stop) and logs every step to a timestamped log file for auditing. All credentials are passed via CLI arguments—no secrets in source code. Features graceful error handling with non-zero exit codes, structured logging for debugging scheduled runs, and a comprehensive `pytest` test suite with `unittest.mock` to simulate GVM socket and SMTP interactions without requiring a live OpenVAS installation. Built for SOC teams and DevSecOps pipelines that need scheduled vulnerability assessments without manual OpenVAS GUI interaction.
Key Highlights
- ✓Zero-config subnet detection with netifaces runtime discovery
- ✓Idempotent GVM targets (reuses existing if subnet matches)
- ✓Full and Fast scan automation via python-gvm / GMP protocol
- ✓PDF report extraction and SMTP delivery with attachments
- ✓Cron-ready with gvm-start/gvm-stop lifecycle management
- ✓Structured timestamped logging for audit trails
- ✓CLI-only credential passing (no hardcoded secrets)
- ✓pytest test suite with mocked GVM/SMTP for CI/CD
Technical Deep Dive
Zero-Config Subnet Detection & Idempotent Targets
The scanner eliminates manual network configuration by using `netifaces` to automatically detect the active non-loopback interface at runtime (e.g., eth0, wlan0) and extract its CIDR subnet (e.g., 192.168.1.0/24). This enables the same codebase to work across different network environments without hardcoded IPs. When communicating with GVM via the Unix socket (`/run/gvmd/gvmd.sock`), it queries existing scan targets and reuses one if the subnet already exists—ensuring idempotency and avoiding duplicate target creation on repeated cron runs. This design allows daily/weekly scans to be fire-and-forget without requiring operator intervention to adjust IP ranges.
Orchestrated GVM Workflow: Target → Task → Report
After authenticating to GVM, the wrapper orchestrates a complete scan lifecycle using the python-gvm library (GMP protocol over Unix socket): (1) **Get or Create Target** — checks for existing targets matching the subnet CIDR; if none exist, creates a new one with the detected subnet and the default All IANA TCP port list. (2) **Create and Start Task** — creates a scan task using the Full and Fast scan configuration (comprehensive CVE checks with balanced performance) and links it to the target. (3) **Poll for Completion** — asynchronously monitors task status until it reaches 'Done' state, with structured logging at each polling interval. (4) **Extract PDF Report** — once complete, retrieves the report in PDF format using GVM's built-in PDF export format ID and saves it locally. This entire process runs without user interaction, making it perfect for scheduled security audits.
SMTP Report Delivery with PDF Attachments
After the scan completes, the wrapper automatically emails the PDF report to one or more configured recipients using Python's `smtplib` with STARTTLS encryption. Defaults to Office 365 SMTP server (`smtp.office365.com:587`) but supports any STARTTLS-capable server via CLI arguments. The email includes a plain-text summary (scan timestamp, subnet scanned, vulnerabilities detected) and the full PDF report as a MIME attachment. Credentials (sender email, sender password, recipient addresses) are all passed via command-line flags, ensuring no secrets are committed to source control. This design enables immediate report distribution to SOC teams, compliance officers, or ticketing systems without requiring manual OpenVAS GUI access or report downloads.
Cron-Ready Architecture with Daemon Lifecycle Management
The `scanner_app.sh` shell wrapper provides a cron-safe entry point that manages the entire GVM daemon lifecycle: (1) **Start GVM** — executes `gvm-start` to ensure OpenVAS services are running before the scan. (2) **Execute Scan** — calls `main.py` with all necessary CLI arguments (GVM credentials, SMTP config, recipients). (3) **Stop GVM** — runs `gvm-stop` to cleanly shut down services after completion. All output is redirected to a configurable log file (`/var/log/openvas-wrapper.log`) with timestamped entries for audit trails and debugging. This approach ensures scans run unattended via cron (e.g., daily at 02:00) without requiring persistent GVM daemons or manual cleanup. Errors are logged with non-zero exit codes for monitoring integrations.
Test Coverage & CI/CD Integration
Includes a comprehensive `pytest` test suite (`tests/test_main.py`) that uses `unittest.mock` to simulate GVM socket interactions, SMTP server responses, and network interface detection—allowing full end-to-end functional testing without requiring a live OpenVAS installation. Tests verify: authentication flow, target creation/reuse logic, task creation and polling, PDF report extraction, and email delivery with attachments. This mocked approach makes the test suite CI/CD-friendly for continuous integration pipelines. The modular architecture separates concerns into distinct `Scan` (GVM operations) and `Mail` (SMTP delivery) classes, enabling unit tests for each component independently. All dependencies are pinned in `requirements.txt` (python-gvm, netifaces) and `requirements-dev.txt` (pytest) for reproducible builds.