131 lines
3.4 KiB
Markdown
131 lines
3.4 KiB
Markdown
# 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 |
|