You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Open-source network inventory, vulnerability scanning, and compliance platform.
Discover hosts, scan ports, fingerprint services, audit CVEs via SSH/ZAP/Nuclei/Trivy, and manage your entire fleet through a tactical dark-theme dashboard.
Why NetLanVentory?
All-in-one — ARP discovery, port scanning, DAST (ZAP), SAST (Nuclei), SSH CVE audit, Docker image scanning (Trivy), SSL/TLS analysis (testssl.sh), SSH config audit (ssh-audit), default credential testing, and HTTP header auditing in a single platform
Zero config scanning — auto-detects open ports and services, builds scan targets automatically
Compliance ready — ISO 27001, NIS2, and ANSSI framework evaluation built-in
Fully dockerized — single docker compose up deploys everything (PostgreSQL, ZAP, Nuclei, Trivy, testssl.sh)
Screenshots
Login
Asset list
Asset — Details tab
Asset — Ports tab
Asset — Overview (CVE histogram)
Asset — Sécurité tab (DAST + SSH CVE)
Scans
Modules
Admin — Users
Admin — ZAP Auto-scan
Features
Network discovery & scanning
ARP sweep — Layer 2 host discovery via scapy, with async ICMP ping fallback
Port scanner — TCP SYN/connect scan powered by nmap
Service detector — async banner grabbing + nmap -sV version detection
OS fingerprinting — nmap -O with heuristic fallback based on open ports
Modular architecture — add a new scanner by dropping a single file in netlanventory/modules/
Asset management
Editable asset fields — hostname, OS family/version, device type, editable directly from the dashboard with evolving autocomplete suggestions (<datalist>) populated from existing values in the database
DNS association — attach multiple FQDN/DNS names to each asset; names are used by ZAP scans as additional scan targets
ZAP web vulnerability scanning
On-demand ZAP scans — trigger a ZAP spider + active scan against any asset directly from the dashboard
CVE tracking — each ZAP report counts the CVEs found in the alerts; tracked per scan
CVE evolution histogram — Overview tab in the asset modal shows a mixed Chart.js chart: stacked bars (High / Medium / Low / Info alerts) + a purple line (CVE count) per scan, with a right-hand Y-axis; single-scan view shows the traditional horizontal bar chart
ZAP auto-scan scheduler — server-side asyncio loop (checks every 60 s) automatically triggers ZAP scans against all active assets that have web ports open (80, 443, 8080, 8443, 8000, 3000, 4443); scan targets include the asset IP and all associated DNS names
ZAP auto-scan settings
Global master switch — enable/disable auto-scan and set a default interval (minutes) from the admin panel → ZAP Auto-scan tab
Per-asset override — each asset can individually enable/disable auto-scan and override the global interval; NULL on an asset means "use global value"
Target visibility — the asset Details tab shows all computed scan targets (IP × DNS names × web ports) and the countdown to the next scheduled scan
Nuclei multi-protocol scanning
Auto-target detection — scan targets are determined automatically from the asset's open ports and services; no manual URL needed
HTTP/HTTPS ports → web scan targets (IP + all associated FQDNs for virtual-host templates)
Template tags — Nuclei template tags are selected to match detected services (e.g. http, smb, dns); always includes cve, misconfig, exposure
Multi-source CVE deduplication — a CVE found by both ZAP and Nuclei appears as a single row in the CVE table with source shown as zap + nuclei
Bundled binary — the Nuclei binary is copied into the Docker image at build time (projectdiscovery/nuclei:latest); templates are persisted in a named Docker volume to avoid re-downloading on restart
Results — findings stored as NucleiReport with JSONL output, risk summary (critical/high/medium/low/info), and CVE count
SSH CVE scanning
Encrypted credentials — store a password or PEM private key per asset; values are Fernet-encrypted at rest (key derived from SECRET_KEY) and never returned in plain text
Package audit — connects via asyncssh, detects the Linux distro, and lists installed packages (Debian/Ubuntu dpkg, RHEL/CentOS rpm, Alpine apk)
Results — CVEs persisted as AssetCve rows with source="ssh", visible in the unified CVE table alongside ZAP and Nuclei findings
CVE library
Cross-asset CVE view — sidebar navigation panel listing all known CVEs across the fleet, with severity filter (Critical / High / Medium / Low / Unknown) and free-text search
Non-standard advisory IDs — UBUNTU-CVE-*, USN-*, and GHSA-* IDs are fully supported; each ID links to its canonical upstream advisory source (NVD, ubuntu.com, GitHub Security Advisories, OSV.dev)
Fix version tracking — fixed_version column in asset_cves records the version that patches each CVE; shown as a "Version corrigée" column in the dashboard
On-demand enrichment — "Enrichir" button triggers a global background enrichment pass via OSV.dev and NVD for any CVE still missing CVSS score or description
CVE detail view — GET /api/v1/cves/{id} returns CVSS score, severity, description, published date, and the full list of affected assets
Remediation workflow — track CVE lifecycle (open → planned → in_progress → resolved | blocked), assign to team members, set due dates, Kanban board view
KPI snapshots — daily automated snapshots of all metrics for long-term trend analysis
Persistent SLA — configurable per severity (critical 3d, high 7d, medium 30d, low 90d), stored in database
Compliance — ISO 27001, NIS2, ANSSI framework evaluation with control scoring
Scan planification & automation
Planifier un rescan — any completed scan can be set to auto-repeat at a configurable interval (hourly, 6h, 12h, daily, weekly, monthly) directly from the Scans tab
Re-run in place — re-running a scan updates the same row instead of creating duplicates
Inline controls — dropdown interval selector + "Planifier" button, green badge when active with countdown to next run
Scheduler — checks every 60 seconds; auto-triggers ZAP, SSH, Trivy, and network rescans when intervals elapse
Security & authentication
JWT authentication — all API endpoints require a valid Bearer token (except /api/v1/auth/login); sub, exp, and iss claims required; issuer verified as netlanventory
Security note: The app container runs as a non-root user (netlv) with cap_drop: ALL + only NET_RAW and NET_ADMIN capabilities (required for ARP scans). All secrets must be set in .env — the app refuses to start with default values in production mode.
Default admin account
On first startup, a default admin account is automatically created if no users exist in the database:
Field
Default value
Email
admin@localhost
Password
changeme
Change these before exposing the app on a network. Edit .env before the first docker compose up:
ADMIN_EMAIL=[email protected]ADMIN_PASSWORD=a-strong-passwordJWT_SECRET_KEY=<openssl rand -hex 32>SECRET_KEY=<openssl rand -hex 32># also used to derive the SSH credential encryption keyZAP_API_KEY=<your-zap-api-key># leave empty to disable ZAP API keyNVD_API_KEY=<your-nvd-api-key># optional — enables NVD fallback for SSH CVE lookupNUCLEI_RATE_LIMIT=150# optional — Nuclei requests/s (default 150)NUCLEI_TIMEOUT=30# optional — Nuclei per-host timeout in seconds (default 30)MAX_CONCURRENT_NUCLEI_SCANS=2# optional — max simultaneous Nuclei scans (default 2)
The bootstrap only runs once (when the users table is empty). If the stack is already running, change the password via the dashboard → Users tab, or recreate the database volume (docker compose down -v && docker compose up --build) to trigger a fresh bootstrap.
Local development
python3 -m venv .venv &&source .venv/bin/activate
pip install -e ".[dev]"# Start PostgreSQL (or point DATABASE_URL at an existing instance)
cp .env.example .env
# Run migrations
alembic upgrade head
# Start the API server
netlv serve --reload
CLI usage
# List available scanning modules
netlv modules list
# Run a full scan (requires root for SYN scan + ARP)
sudo netlv scan run \
--target 192.168.1.0/24 \
--modules arp_sweep,port_scanner,service_detector,os_fingerprint
# Browse results
netlv assets list
netlv assets list --active-only --filter 192.168.1
# Show full detail for a host
netlv assets show 192.168.1.1
# List past scans
netlv scan list
# Point the CLI at a remote API server
netlv --api-url http://my-server:8000 assets list
REST API
Assets
Method
Endpoint
Description
GET
/api/v1/assets
List assets (?active_only, ?limit, ?skip)
GET
/api/v1/assets/vocabulary
Distinct OS families and device types for autocomplete
Enable the global master switch and set a default interval (1–10 080 minutes)
For each asset that needs a different schedule (or to opt out), open the asset modal → Details tab → toggle ZAP auto-scan and optionally set a per-asset interval
The scheduler wakes every 60 seconds and launches a scan whenever:
auto-scan is enabled for an asset (asset toggle, or global if asset toggle is unset), and
the configured interval has elapsed since the last auto-scan, and
the asset has at least one open web port (80, 443, 8080, 8443, 8000, 3000, 4443)
Scan targets are built automatically: {scheme}://{ip} + {scheme}://{fqdn} for every DNS name attached to the asset.
# Via Docker (recommended — no local Python needed)
docker compose --profile test up --build tests
# Or run the full recette script
./scripts/recette.sh
# Quick smoke tests only
./scripts/recette.sh --quick
# Security regression tests only
./scripts/recette.sh --security
# With Makefile
make recette # lint + types + tests + coverage
make test-security # security tests only
make test-coverage # with HTML coverage report
Tests use SQLite in-memory — no PostgreSQL required. 288 tests across 20 test files covering: