Skip to content

Docker

A small Alpine image bundles the full recon toolchain so you can run scans and generate reports without installing nmap, bash, jq, and the rest on the host, and so you can run a versioned image instead of building from source.

  • Base: alpine:3.21, single stage (netvuln-tool has no compiled dependencies, so there is nothing to build).
  • Platforms: linux/amd64 and linux/arm64, both covered by docker buildx build --platform linux/amd64,linux/arm64, so you can build multi-arch locally for ARM edge devices as well as x86 hosts.
  • Contents: the whole source tree (netvuln/ scripts/ lib/ templates/ assets/) plus the runtime tools listed below. The Python netvuln CLI drives the bash modules, which it resolves relative to the repo root, so a bare pip wheel would not work; the tree ships intact.
  • Entry point: the netvuln CLI (recon, scan, upload, push, diff, status, daemon).
  • User: non-root (netvuln).

Bundled tools

Required core: python3, bash, coreutils, gawk, grep, sed, jq, nmap + nmap-scripts (NSE).

Full recon: bind-tools (dig/host), whois, openssl, samba-client (smbclient), net-snmp-tools (snmpwalk/snmpget), curl, ca-certificates, tzdata.

Deliberately excluded: wkhtmltopdf (PDF export is broken on Alpine/musl; HTML reports are unaffected) and mail/sendmail (optional email delivery). If you need PDF export or email, run from a glibc-based host install instead (see Installation).

Build

From the repo root:

bash
docker build -t netvuln-tool:dev .

A plain docker build targets your host's native architecture. docker buildx supports both linux/amd64 and linux/arm64, so to build locally for a specific target (for example an amd64 image from an Apple Silicon Mac), pass --platform explicitly:

bash
docker buildx build --platform linux/amd64 -t netvuln-tool:dev --load .

Check the size:

bash
docker images netvuln-tool:dev

Run

Show CLI help (default command):

bash
docker run --rm netvuln-tool:dev --help

Run a recon scan. Scan sessions and generated reports land in /opt/netvuln-tool/sessions inside the container, so mount a volume to keep them:

bash
docker run --rm \
  --network host \
  -v "$PWD/out:/opt/netvuln-tool/sessions" \
  netvuln-tool:dev recon -t 192.0.2.0/24

--network host gives the container the host's network interfaces so it can see and scan the LAN. The default bridge network NATs the container onto its own subnet (for example 172.17.0.0/16), out of reach of your real targets, so for anything other than scanning the container host itself, use --network host.

Docker Desktop networking

--network host is a Linux Docker feature. On Docker Desktop (macOS/Windows) "host" is the Linux VM, not your laptop's LAN. Run scans from a Linux host (the fleet) for real LAN reach. Only scan networks and hosts you are authorized to assess.

Scan privileges: works out of the box (no --cap-add)

Privileged nmap phases (SYN scan, -O OS detection, -sU UDP for SNMP, and raw-socket host discovery) need raw sockets. This image runs as the non-root netvuln user, and there is a subtlety that trips up most containerized nmap setups:

Adding a capability to the container (--cap-add=NET_RAW) puts it in the bounding set, but that is not effective for a non-root process. And nmap decides "am I privileged?" from euid==0, so it does not automatically use a capability even when one is present.

The image handles both halves so you do not have to:

  1. File capability on nmap: setcap cap_net_raw+eip /usr/bin/nmap (baked at build time). NET_RAW is in Docker's default capability set, so the non-root user gets effective raw sockets with a plain docker run, no --cap-add required.
  2. NMAP_PRIVILEGED=1 (baked env): tells nmap to use raw scans despite euid != 0; the file capability makes that actually succeed.

Result: docker run --network host netvuln-tool:<v> recon -t <lan> performs full privileged scans as the non-root user, with no capability flags.

Capability caveats

  • Do not --cap-drop NET_RAW. The file capability carries the effective bit, so if NET_RAW is removed from the bounding set the kernel refuses to exec nmap at all (Operation not permitted). Docker grants NET_RAW by default, so this only bites if you deliberately drop it. If you must scan with all capabilities dropped, use a host install instead.
  • A few exotic nmap features (for example --send-eth on some interfaces) also want NET_ADMIN, which is not a Docker default. Add it only if you hit such a case: --cap-add=NET_ADMIN. It is intentionally not baked into the nmap file caps, as doing so would break exec under Docker's default cap set.
  • --user root remains the blunt fallback if capabilities are unavailable in your environment.

One command with Compose

docker-compose.yml wires up the frictionless path (network_mode: host, the sessions volume, and the image tag), so a scan is a single command:

bash
docker compose run --rm scan recon -t 192.168.1.0/24

# pin a version instead of :latest
IMAGE_TAG=v4.3.3 docker compose run --rm scan recon -t 10.0.0.0/24

Reports and session data land in ./out. Build the image locally by uncommenting build: . in the compose file. If Bullium has provided a prebuilt image through a licensed registry (<registry-host>/netvuln-tool), reference that tag instead.

Portal upload / license

Portal upload, push, CVE lookup, and license validation use curl over HTTPS. Pass the config and license via environment or a mounted config file, for example:

bash
docker run --rm \
  -e NV_API_KEY="$NV_API_KEY" \
  -v "$PWD/report_config.conf:/opt/netvuln-tool/report_config.conf:ro" \
  netvuln-tool:dev upload -c report_config.conf --latest

The license soft gate reads ~/.netvuln/license.key (that is, /home/netvuln/.netvuln/license.key) or the NV_API_KEY / NV_LICENSE_KEY environment variables. It never blocks core scanning. See License Provisioning.

Bash entry points

The bash pipeline is still available directly if you prefer it over the Python CLI:

bash
docker run --rm netvuln-tool:dev bash scripts/vulnscan_recon.sh -t 192.0.2.10

Smoke test

tests/docker_smoke.sh builds nothing; it exercises an already-built image and asserts the required tools are present and netvuln --help runs:

bash
tests/docker_smoke.sh netvuln-tool:dev

See also

  • Installation: host install (install.sh) and developer setup (setup.sh).
  • Raspberry Pi: running the container or a host install on ARM edge devices.
  • License Provisioning: key formats, tiers, and the soft gate.
  • Daemon Troubleshooting: failure modes for container scans (LAN reach, raw-socket capability, portal upload) alongside the systemd daemon path.

Apache-2.0 licensed (appliance subtree proprietary)