При наличии большого количества подсетей зачастую требуется аудит и мониторинг адресного пространства в них, для этого прекрасно подходит такой инструмент, как IPAM.
В качестве инструмента будем использовать Netbox и nmap.
Установка
Для установки нам потребуется скачать уже готовый скрипт от пользователя @lckrspirit с gitlab.
Для удобства его можно разместить где ни будь в каталоге c NetBox.
Качаем nmap, устанавливаем зависимости:
---Активируем виртуальное окружение (например в venv Netbox)--
$ cd/usr/local/share/netbox/
$ .venv/bin/activate
(venv)$ cd /usr/local/share/netbox/scripts
(venv)$ git clone https://gitlab.com/lckrspirit/netbox-ipam-auto-discovery.git
(venv)$ cd netbox-ipam-auto-discovery/
(venv)$ pip install python-nmap pynetbox
Так же его можно скачать
Заходим в NetBox в меню "Аутентификация" и получаем токен для обращения к API:

Генерируем токен (под суперпользователем это лучше не делать, а создать отдельного)

Открываем скрипт текстовым редактором и вводим адрес NetBox и сгенерированный Token

P.S. В netbox_url должны быть указаны адреса перечисленные в блоке "ALLOWED HOSTS" файла конфигурации Netbox configuration.py.
Запуск скрипта
Для запуска сканирования сети достаточно выполнить:
Теперь можно идти в меню IPAM и мы увидим отсканированные IP адреса.

Если мы еще добавим сеть в меню "Диапазоны IP- адресов мы сможем увидеть статистику использование адресного пространства в данном сегменте сети.

Скрипт сам обновляет и удаляет адреса, его можно назначить в задания cron на выполнение к примеру каждые 3 часа.
Дополнительно мы можем создать VLAN, группы и назначения, после чего связать с существующим диапазоном адресов.
Что бы мы могли видеть еще и свободные адреса, необходимо добавить префикс для нашей сети:

Указываем нашу сеть в поле префикс, статус, и ставим флаг, что данная сеть является пулом.
Синхронизация DNS записей.
Если в качестве DNS сервера используется роль Windows Server, то можно при помощи powershell-скрипта сопоставить найденные nmap ip адреса с записями DNS.
Пример скрипта:
$netboxUrl = "https://netbox.example.com/api"
$netboxToken = "ce9b6897b23e6fadd70649628e9e86aa1af48b72"
# Параметры DNS-сервера
$dnsServer = "dc01.example.com" # Или IP-адрес DNS-сервера
$dnsZone = "example.com" # Зона, которую нужно обработать
# 1. Проверка подключения
function Test-NetBoxConnection {
try {
$uri = "$netboxBaseUrl/api/status/"
Write-Host "Проверка подключения к $uri"
$request = [System.Net.WebRequest]::Create($uri)
$request.Method = "GET"
$request.Headers.Add("Authorization", "Token $netboxToken")
$request.Timeout = 5000 # 5 секунд таймаут
$response = $request.GetResponse()
$reader = New-Object System.IO.StreamReader($response.GetResponseStream())
$content = $reader.ReadToEnd()
if ($content) {
$status = $content | ConvertFrom-Json
Write-Host "Подключение успешно. Версия NetBox: $($status.netbox_version)" -ForegroundColor Green
return $true
}
}
catch {
Write-Error "Ошибка подключения: $($_.Exception.Message)"
return $false
}
}
if (-not (Test-NetBoxConnection)) {
exit 1
}
# 2. Функция для запросов к API
function Invoke-NetBoxRequest {
param(
[string]$Endpoint,
[string]$Method = "GET",
[object]$Body = $null
)
# Формируем абсолютный URL
$uri = "$netboxBaseUrl/api/$($Endpoint.TrimStart('/'))"
try {
$request = [System.Net.WebRequest]::Create($uri)
$request.Method = $Method
$request.Headers.Add("Authorization", "Token $netboxToken")
$request.Accept = "application/json"
$request.ContentType = "application/json"
$request.Timeout = 10000 # 10 секунд таймаут
if ($Body -ne $null) {
$jsonBody = $Body | ConvertTo-Json -Depth 3
$bytes = [System.Text.Encoding]::UTF8.GetBytes($jsonBody)
$request.ContentLength = $bytes.Length
$stream = $request.GetRequestStream()
$stream.Write($bytes, 0, $bytes.Length)
$stream.Close()
}
$response = $request.GetResponse()
$reader = New-Object System.IO.StreamReader($response.GetResponseStream())
return $reader.ReadToEnd() | ConvertFrom-Json
}
catch {
Write-Warning "Ошибка запроса к $uri : $($_.Exception.Message)"
return $null
}
}
# 3. Поиск IP в NetBox
function Get-NetBoxIpRecord {
param([string]$ipAddress)
$response = Invoke-NetBoxRequest "ipam/ip-addresses/?address=$ipAddress"
if (-not $response) { return $null }
foreach ($record in $response.results) {
$recordIp = ($record.address -split '/')[0]
if ($recordIp -eq $ipAddress) {
return $record
}
}
return $null
}
# 4. Основной процесс
try {
$dnsRecords = Get-DnsServerResourceRecord -ZoneName $dnsZone -ComputerName $dnsServer -ErrorAction Stop |
Where-Object { $_.RecordType -eq "A" }
foreach ($record in $dnsRecords) {
$ip = $record.RecordData.IPv4Address.IPAddressToString
$name = $record.HostName
$nbRecord = Get-NetBoxIpRecord -ipAddress $ip
if (-not $nbRecord) {
Write-Warning "IP $ip не найден в NetBox"
continue
}
$cleanName = $name -replace '[^a-zA-Z0-9*\-\._]', '' -replace '\.+', '.' -replace '^\.|\.$', ''
if (-not [string]::IsNullOrWhiteSpace($cleanName) -and $nbRecord.dns_name -ne $cleanName) {
$result = Invoke-NetBoxRequest "ipam/ip-addresses/$($nbRecord.id)/" -Method PATCH -Body @{dns_name = $cleanName}
if ($result) {
Write-Host "Обновлено: $ip → $cleanName" -ForegroundColor Green
}
}
}
}
catch {
Write-Error "Критическая ошибка: $_"
exit 1
}
Write-Host "Синхронизация завершена" -ForegroundColor Cyan
Данный скрипт можно закинуть в планировщик задач и запускать его по расписанию