Skip to content

AurevLan/NetLanVentory

Repository files navigation

NetLanVentory

Latest release CI Tests Python License Docker Security

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
  • Security-first — ANSSI-compliant password policy, CSP nonce, HSTS, non-root Docker, encrypted credential storage
  • Fully dockerized — single docker compose up deploys everything (PostgreSQL, ZAP, Nuclei, Trivy, testssl.sh)

Screenshots

Login Asset list
Login Assets
Asset — Details tab Asset — Ports tab
Details Ports
Asset — Overview (CVE histogram) Asset — Sécurité tab (DAST + SSH CVE)
Overview Sécurité
Scans Modules
Scans Modules
Admin — Users Admin — ZAP Auto-scan
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)
    • Port 53 → DNS resolver scan
    • FTP, SMTP, SMB, MySQL, PostgreSQL, Redis, MongoDB, RDP → service-specific 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)
  • CVE lookup — OSV.dev (primary, no key needed, batch 1 000 pkgs/req) + NVD NIST (fallback, requires NVD_API_KEY)
  • 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 IDsUBUNTU-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 trackingfixed_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 viewGET /api/v1/cves/{id} returns CVSS score, severity, description, published date, and the full list of affected assets

Vision 360° RSSI

  • Executive dashboard — risk score gauge, MTTR, velocity (CVEs/week), burndown chart, 30-day trends, severity × criticality heatmap, remediation funnel, coverage bars, SLA metrics, forecast to zero
  • 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
  • ANSSI R22 password policy — 12+ characters, uppercase, lowercase, digit, special character; bcrypt 14 rounds
  • Role-based accessadmin role required for user management and global settings
  • OIDC / SSO — optional OpenID Connect provider configured via the admin panel
  • User management — create, activate/deactivate and delete users from the dashboard
  • HTTP security headers — HSTS, X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy, Content-Security-Policy, Cross-Origin-Opener-Policy
  • Rate limiting — 10 req/min on login, 20 req/min on ZAP trigger, 10 req/min on Nuclei trigger, 5 req/min on SSH trigger, 200 req/min global default
  • Input validation — IP addresses, host/port regex, Docker image names, FQDNs validated at the API boundary
  • Docker hardened — non-root user, cap_drop ALL, mandatory secrets, no-new-privileges

Infrastructure

  • REST API — FastAPI with OpenAPI docs at /docs
  • Web dashboard — SOC Nightwatch dark-theme SPA at http://localhost:8443
  • Hash routing — browser back/forward buttons work, URLs are shareable (/#/assets, /#/topology)
  • CLInetlv command with Rich-formatted tables and live progress

Requirements

  • Docker + Docker Compose (recommended)
  • or Python 3.11+, PostgreSQL 14+, nmap, libpcap, OWASP ZAP (for ZAP features)

Quick start with Docker

git clone https://github.com/AurevLan/NetLanVentory.git
cd NetLanVentory
cp .env.example .env          # edit passwords / SECRET_KEY as needed
docker compose up --build
Service URL
Dashboard http://localhost:8443
API docs (Swagger) http://localhost:8443/docs
ReDoc http://localhost:8443/redoc

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-password
JWT_SECRET_KEY=<openssl rand -hex 32>
SECRET_KEY=<openssl rand -hex 32>        # also used to derive the SSH credential encryption key
ZAP_API_KEY=<your-zap-api-key>           # leave empty to disable ZAP API key
NVD_API_KEY=<your-nvd-api-key>           # optional — enables NVD fallback for SSH CVE lookup
NUCLEI_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
GET /api/v1/assets/{id} Get asset by UUID
GET /api/v1/assets/by-ip/{ip} Get asset by IP address
POST /api/v1/assets Create asset manually
PATCH /api/v1/assets/{id} Update asset fields (hostname, os_family, os_version, device_type, ssh_password, ssh_private_key, zap_auto_scan_enabled, …)
DELETE /api/v1/assets/{id} Delete asset

DNS entries

Method Endpoint Description
GET /api/v1/assets/{id}/dns List DNS entries for an asset
POST /api/v1/assets/{id}/dns Add a DNS entry ({ "fqdn": "host.example.com" })
DELETE /api/v1/assets/{id}/dns/{dns_id} Remove a DNS entry

Scans & modules

Method Endpoint Description
GET /api/v1/scans List scans
POST /api/v1/scans Start a new scan (async, 202 Accepted)
GET /api/v1/scans/{id} Get scan status and results
DELETE /api/v1/scans/{id} Delete scan
GET /api/v1/modules List registered modules
GET /api/v1/modules/{name} Get module metadata + options schema

SSH CVE scan

Method Endpoint Description
POST /api/v1/assets/{id}/ssh-scan Trigger an SSH package audit + CVE lookup (async, 202 Accepted)
GET /api/v1/assets/{id}/ssh-scan List SSH scan reports (newest first)
GET /api/v1/assets/{id}/ssh-scan/{report_id} Get a specific SSH scan report

Nuclei

Method Endpoint Description
POST /api/v1/assets/{id}/nuclei Trigger a Nuclei scan (targets auto-determined from open ports, async, 202 Accepted)
GET /api/v1/assets/{id}/nuclei List Nuclei reports for an asset (newest first)
GET /api/v1/assets/{id}/nuclei/{report_id} Get a specific Nuclei report with full findings list

ZAP

Method Endpoint Description
POST /api/v1/zap/scan Launch a ZAP scan against a target URL
GET /api/v1/zap/reports List ZAP reports (supports ?asset_id)
GET /api/v1/zap/reports/{id} Get full ZAP report with alerts and CVE count
DELETE /api/v1/zap/reports/{id} Delete a ZAP report

CVE library

Method Endpoint Description
GET /api/v1/cves List all CVEs (?severity, ?search, ?skip, ?limit)
GET /api/v1/cves/{cve_id} Get CVE detail with list of affected assets
POST /api/v1/cves/enrich Trigger global CVE enrichment (OSV + NVD, background)

Admin

Method Endpoint Description
GET /api/v1/admin/zap-settings Get global ZAP auto-scan settings
PUT /api/v1/admin/zap-settings Update global ZAP auto-scan settings
GET /api/v1/admin/oidc Get OIDC provider configuration
PUT /api/v1/admin/oidc Update OIDC provider configuration

Authentication & users

Method Endpoint Description
POST /api/v1/auth/login Obtain JWT token (application/x-www-form-urlencoded)
GET /api/v1/users/me Current user profile
GET /api/v1/users List users (admin only)
POST /api/v1/users Create user (admin only)
PATCH /api/v1/users/{id} Update user (admin only)
DELETE /api/v1/users/{id} Delete user (admin only)

Start a scan via API

curl -s -X POST http://localhost:8000/api/v1/auth/login \
  -d 'username=admin@localhost&password=changeme' | jq -r .access_token
# → <TOKEN>

curl -X POST http://localhost:8000/api/v1/scans \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
    "target": "192.168.1.0/24",
    "modules": ["arp_sweep", "port_scanner", "service_detector", "os_fingerprint"]
  }'

ZAP auto-scan configuration

  1. Open the dashboard → AdminZAP Auto-scan
  2. Enable the global master switch and set a default interval (1–10 080 minutes)
  3. 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.

Adding a module

Create netlanventory/modules/my_module.py:

from netlanventory.modules.base import BaseModule, ModuleCategory, ModuleMetadata

class MyModule(BaseModule):
    metadata = ModuleMetadata(
        name="my_module",
        display_name="My Module",
        version="1.0.0",
        category=ModuleCategory.SERVICE,
        description="Does something useful.",
        author="You",
        requires_root=False,
        options_schema={
            "type": "object",
            "properties": {
                "target": {"type": "string"},
            },
            "required": ["target"],
        },
    )

    async def run(self, session, options):
        # ... your logic here ...
        return {
            "module": self.metadata.name,
            "status": "success",
            "assets_found": 0,
            "details": {},
        }

Restart the server — the module is auto-discovered and immediately available via netlv modules list and the API.

Project structure

NetLanVentory/
├── netlanventory/
│   ├── core/          # config, crypto (Fernet), cve_enrichment, async DB engine, structlog, module registry, scheduler
│   ├── models/        # SQLAlchemy ORM (Asset, Scan, Port, ScanResult, AssetDns, GlobalSettings, ZapReport, SshScanReport, NucleiReport, …)
│   ├── schemas/       # Pydantic request/response schemas
│   ├── modules/       # BaseModule ABC + built-in scanners
│   ├── api/
│   │   ├── routers/   # assets, scans, modules, zap, dns, ssh_scan, nuclei, cves, auth, users, admin
│   │   └── static/    # Single-page dashboard (HTML + JS + CSS, no build step)
│   └── cli/           # Click commands, Rich output helpers
├── alembic/           # Database migrations
├── tests/             # pytest-asyncio test suite (SQLite in-memory)
├── Dockerfile
└── docker-compose.yml

Running tests

# 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:

  • Security regression (CSP, HSTS, CORS, auth enforcement, input validation, JWT, crypto)
  • RSSI 360° vision (executive KPIs, remediation workflow, SLA, compliance, timeline)
  • All 180+ API endpoints (CRUD, scans, admin, compliance)
  • Unit tests (auth, passwords, scoring, compliance, circuit breaker)
  • Integration tests (assets, CVE enrichment, caching)

Tech stack

Layer Technology
Language Python 3.11+
API framework FastAPI 0.135+ / Uvicorn 0.42+
Database PostgreSQL 16 (asyncpg / SQLAlchemy 2.0.48+)
Migrations Alembic
Network scanning scapy (ARP), python-nmap (ports/services/OS)
Web vulnerability scanning OWASP ZAP (DAST)
Multi-protocol scanning ProjectDiscovery Nuclei
Docker image scanning Aquasec Trivy
SSL/TLS analysis testssl.sh
SSH configuration audit ssh-audit
Rate limiting slowapi
Authentication JWT (PyJWT) + bcrypt (14 rounds)
Encryption Fernet (AES-128-CBC + HMAC-SHA256)
CLI Click + Rich
Logging structlog
Linting Ruff (with bandit security rules)
Type checking MyPy (strict mode)
Testing pytest-asyncio (288 tests)
Container Docker Compose (multi-stage build)

Contributing

Contributions are welcome! Here are some areas where help is appreciated:

  • Frontend modernization — migrate from vanilla JS to a component framework (Vue/Svelte) with TypeScript
  • E2E testing — Playwright/Cypress tests for the dashboard
  • Scan plugins — new scanner modules (Nessus integration, cloud security scanning)
  • Alerting — Slack/Teams/email notifications on critical CVE discovery
  • RBAC granularity — per-asset or per-subnet access control
  • API rate limiting — per-user quotas instead of global IP-based limits
  • Internationalization — French/English toggle for the dashboard

Please see SECURITY.md for responsible disclosure of vulnerabilities.

Changelog

See CHANGELOG.md for the full version history.

License

MIT

About

Open-source network inventory & vulnerability scanning platform — ARP discovery, port scanning, ZAP DAST, Nuclei, Trivy, testssl.sh, SSH CVE audit, compliance (ISO 27001/NIS2/ANSSI). Tactical dark-theme dashboard. 180+ API endpoints. Docker-ready.

Topics

Resources

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors