# NetBox Scanner A Dockerized network scanner that discovers hosts with Nmap and imports them into [NetBox](https://netbox.dev/) as IP address records. ## How it works 1. **Scanner** (`scan.py`) — performs an Nmap sweep of configured networks and writes results to `output/network.txt`. 2. **NetBox Importer** (`ipscan-v2.py`) — scans networks directly with Nmap, resolves hostnames via DNS, then creates or updates IP address records in NetBox. IPs not found during the scan are marked as `offline`. Networks to scan can come from the environment variable `NETWORKS`, from NetBox IPAM prefixes, or both — controlled by `SCAN_SOURCE`. ## Requirements - Docker and Docker Compose ## Setup 1. Copy the example environment file and fill in your values: ```bash cp .env.example .env ``` 2. Edit `.env`: ```env NETBOX_URL=https://netbox.example.com/ NETBOX_TOKEN=your_token_here SSL_VERIFY=false SCAN_SOURCE=env NETWORKS=192.168.1.0/24,192.168.2.0/24 NETBOX_PREFIX_STATUS=active TENANT=Your Tenant Name ``` 3. Build the image: ```bash docker compose build ``` ## Usage ### Run the NetBox importer Scans all configured networks and imports results into NetBox: ```bash docker compose up netbox-importer ``` ### Run the standalone scanner Scans networks and writes results to `./output/network.txt`: ```bash docker compose up scanner ``` ### Run both services ```bash docker compose up scanner netbox-importer ``` ## Configuration All configuration is done via environment variables. Copy `.env.example` to `.env` and set the values there. ### NetBox importer (`ipscan-v2.py`) | Variable | Default | Description | |---|---|---| | `NETBOX_URL` | — | NetBox instance URL | | `NETBOX_TOKEN` | — | NetBox API token | | `SSL_VERIFY` | `false` | Set to `true` to verify SSL certificates | | `SCAN_SOURCE` | `env` | Where to get networks: `env`, `netbox`, or `mixed` | | `NETWORKS` | — | Comma-separated CIDR networks (used when `SCAN_SOURCE=env` or `mixed`) | | `NETBOX_PREFIX_STATUS` | _(all)_ | Filter NetBox prefixes by status, e.g. `active`, `reserved` (used when `SCAN_SOURCE=netbox` or `mixed`) | | `TENANT` | — | NetBox tenant name to assign to imported IPs | **`SCAN_SOURCE` values:** - `env` — scan only networks from `NETWORKS` - `netbox` — scan only prefixes fetched from NetBox IPAM - `mixed` — combine both sources ### Scanner service (`scan.py`) | Variable | Default | Description | |---|---|---| | `OUTPUT_PATH` | `/app/output/network.txt` | Path inside the container to write results | ## Scan behaviour - Port range scanned: `1–32768` (TCP) - Timing template: `-T4` (aggressive) - Per-host timeout: 2 minutes - Up to 5 networks and 5 hosts are processed in parallel (thread pool) - Hosts that were previously in NetBox but not found in the current scan are set to status `offline` ## Output format (`network.txt`) ```text 192.168.1.1 up 22 80 443 192.168.1.2 down ``` ## Project structure ``` . ├── ipscan-v2.py # NetBox importer script ├── scan.py # Standalone Nmap scanner ├── Dockerfile # Python 3.14-slim + Nmap + Tini ├── docker-compose.yml # Defines scanner and netbox-importer services ├── requirements.txt # python-nmap, pynetbox, requests ├── .env # Local environment config (gitignored) └── .env.example # Template — safe to commit ``` ## Dependencies | Package | Version | |---|---| | `python-nmap` | 0.7.1 | | `pynetbox` | 7.4.1 | | `requests` | 2.32.3 |