Appearance
Raspberry Pi / ARM Deployment
NetVuln Tool is fully compatible with Raspberry Pi OS and other Debian-based ARM distributions, which makes a Raspberry Pi an excellent always-on network scanner. Combined with the scheduling daemon and portal auto-upload, you get a low-cost, low-power scanning appliance you can drop on any network segment.
Compatibility
- ARM-compatible: all scan logic is Bash with no compiled binaries; the
netvulnPython CLI is pure Python. - Tested on Raspberry Pi 3B+, Pi 4, and Pi 5 running Raspberry Pi OS (Debian-based).
- Recommended hardware: Pi 4+ with 2GB+ RAM for large-subnet scans.
Install
The recommended path on a Pi is the deployment installer, install.sh, which auto-installs the full scanner toolchain via apt-get (pass --minimal to opt out), installs the netvuln CLI, writes the license key, scaffolds a per-engagement config, installs and enables the systemd daemon, and verifies portal connectivity.
On a Raspberry Pi, install.sh 4.9.0+ automatically creates and uses a dedicated nvt service account (no prompt): the daemon installs to /opt/netvuln-tool owned nvt:nvt, nvt is added to the adm group, and a scoped NOPASSWD sudoers file (/etc/sudoers.d/netvuln-nvt) grants exactly the commands the daemon and its capability maintenance need. This is Pi-only; a non-Pi Linux install can opt into the same nvt account with --service-user nvt, but does not get adm or the sudoers file.
As an unattended agent:
bash
bash install.sh --non-interactive \
--license-key nvt_pro_<hex> \
--api-url https://portal.netvulntool.com/api/upload \
--client-id acme \
--targets 192.168.1.0/24The daemon is installed but stays idle until a config sets DAEMON_ENABLED="true" with TARGETS and a SCAN_SCHEDULE.
The netvuln CLI on Raspberry Pi OS
Raspberry Pi OS has marked its system Python as externally managed since Bookworm, so a plain pip install refuses to run:
error: externally-managed-environmentinstall.sh handles this for you: it detects the marker, builds a virtualenv at ~/.netvuln/venv, and links the console script to ~/.local/bin/netvuln, with no sudo and no manual preparation on a stock image. If ~/.local/bin is not yet on your PATH the installer prints the export line to add.
Debian ships the venv module as its own package. If virtualenv creation fails, install it and re-run the installer:
bash
sudo apt-get install -y python3-venvThe CLI is optional. Scanning is pure Bash, so a Pi where the Python install fails still scans normally and only lacks the netvuln command.
If you prefer to install dependencies by hand (for example, for a developer checkout on the Pi), a one-liner covers the common set before running the developer setup.sh:
bash
sudo apt-get install -y nmap jq dnsutils whois curl snmp python3-venv && bash setup.shScheduling options
Daemon mode (recommended)
For production deployments, the persistent daemon provides multi-config support, retry with exponential backoff, and portal heartbeats. On Linux it installs as a systemd service, so it starts on boot and restarts on failure. A unit template ships at templates/netvuln_daemon.service.
bash
# Install as a systemd service (also done by install.sh unless --no-daemon)
./scripts/netvuln_daemon_ctl.sh install-service
# Start the daemon
./scripts/netvuln_daemon_ctl.sh start
# Check status
./scripts/netvuln_daemon_ctl.sh statusAs of 4.9.0, install-service always renders the unit from explicit flags (install.sh supplies them), so no manual sudo workaround is needed even if you invoke it by hand: run it as the service account (nvt on a Pi), not as root.
On an /opt-layout install, running netvuln_daemon_ctl.sh status/stop/ start directly (outside systemd) needs NVD_BASE_DIR=/opt/netvuln-tool set in your own shell, since the script computes its status/stop/start paths from the environment it runs in, independent of what the systemd unit sets for the daemon process itself: sudo -u nvt NVD_BASE_DIR=/opt/netvuln-tool scripts/netvuln_daemon_ctl.sh status.
Enable scanning for a config by setting DAEMON_ENABLED="true", a SCAN_SCHEDULE cron expression, and TARGETS, then reloading the daemon (netvuln_daemon_ctl.sh reload). See Daemon Mode and Scheduling for the full lifecycle.
Cron-based scheduling
For simpler setups without the daemon, scheduled_scan.sh manages recurring scans via cron. Point -c at your config: ~/netvuln-tool/configs/client.conf by default, or /opt/netvuln-tool/configs/client.conf on the nvt path (see Where things live):
bash
./scripts/scheduled_scan.sh --install-cron -c ~/netvuln-tool/configs/client.confPlatform validation
Before deploying, run the platform validation script to verify readiness:
bash
bash scripts/pi_validate.sh # Run the deployment checks
bash scripts/pi_validate.sh --json # JSON output for monitoring integration
bash scripts/pi_validate.sh --fix # Auto-install missing dependencies where possibleIt checks disk space, available memory, required tools, file permissions, and portal (/api/health) reachability. Flags combine, for example pi_validate.sh --fix --json.
Field appliance (proprietary hardware)
The repository's appliance/ directory holds a purpose-built field-enclosure design: a 3D-printed Raspberry Pi 5 + RTL-SDR case with an open dongle cradle and the Bullium logo on the lid (OpenSCAD source, print-ready STLs, renders, and a print guide).
Not Apache-2.0
The appliance/ subtree is proprietary to Bullium Consulting and All Rights Reserved. It is not covered by the repository's Apache-2.0 license and is excluded from the container image. See Open Source Boundary for the exact split.
Performance considerations
- Large subnet scans (for example a
/16) may need increased memory or scan segmentation. - Use the
quick_reconprofile to reduce resource usage:-P quick_recon. - Schedule scans during off-peak hours to minimize network impact.
- The daemon's exponential backoff prevents resource exhaustion on repeated failures.
Containerized alternative
If you would rather not install the toolchain on the Pi at all, the Alpine image runs the full recon stack in a container. Note that --network host (needed for LAN reach) is a Linux Docker feature and works on a Pi running Docker Engine. See the Docker guide for build, run, and privilege details.
