Архив

Редактировал(а) Антон Волков 2024/11/18 00:41

Блог - Публикации блога October 2024

окт. 30 2024

Сбор конфигураций на сетевом оборудование средствами Netbox

Установка napalm

Для просмотра конфигурации устройств в netbox есть плагин, который называется netbox-napalm-plugin, он позволяет просматривать определенную информацию запрашиваемую у коммутатора или маршрутизатора, имеющего ssh или другой api через интерфейс netbox, про этом в самом netbox ничего не хранится.

Для начала необходимо установить сам napalm, плагин netbox-napalm-plugin и в нашем случае драйвер для RouterOS - napalm-ros.

При этом данные пакеты лучше добавить в зависимости самого netbox, что бы не было проблем при обновлении в будущем.

$ cd /usr/local/share/netbox/
---Воспользуемся виртуальным окружением Netbox---
$ . venv/bin/activate
---Добавляем зависимости---
(venv)$ echo netbox-napalm-plugin >> /usr/local/share/netbox/requirements.txt
(venv)$ echo napalm-ros >> /usr/local/share/netbox/requirements.txt
---Ставим плагины---
(venv)$ pip install netbox-napalm-plugin
(venv)$ pip install napalm-ros

napalm позволяет запрашивать с оборудования структурированные данные в формате json, что в свою очередь очень удобно при использовании с сторонними API.

После установки необходимо добавить записи в конфиг /usr/local/share/netbox/netbox/netbox/configuration.py

1
2
3
4
5
6
7
8
9
10
11
PLUGINS = ["netbox_napalm_plugin"]
PLUGINS_CONFIG = {
'netbox_napalm_plugin': {
       'NAPALM_USERNAME': '<ssh_user>',
       'NAPALM_PASSWORD': '<ssh_Password>',
       'NAPALM_ARGS': {
           'api_key': '<netbox-api>',
           'ssh_port': '22',
                 }
           }
}

Для например cisco требуются сообщать secret после ввода логина и пароля, для этого мы можем указывать дополнительные аргументы в конфигурационном файле:

NAPALM_ARGS = { 'secret': NAPALM_PASSWORD, # Include any additional args here }

---Выполняем миграцию и пополняем статическое содержимое---
(venv)$ python3.11 netbox/manage.py migrate
(venv)$ python3.11 netbox/manage.py collectstatic --no-input
---Перезапускаем службы---
# service netbox restart
# service netbox_rq restart

На примере микротиков, нам надо завести на всех устройствах учетку для napalm и разрешить подключаться с netbox к api и по ssh.

Добавление и настройка устройств в Netbox

После установки плагина у нас в меню появиться новый пункт: 

1731575594944-287.png

К данному меню вернемся позже.

Для начала проверим правильно ли мы настроили устройства и можно ли запросить у них информацию через napalm.

Для этого можно выполнить команду

(venv)$ napalm --user napalm --password 'P@ssw0rd' --vendor ros --debug 172.16.1.1 call get_interfaces

Мы увидим вывод:

{
   "uptime": 7331045.0,
   "vendor": "MikroTik",
   "model": "CCR1036-8G-2S+",
   "hostname": "CORE-MSK-ITSOFT",
   "fqdn": "",
   "os_version": "6.49.13 (long-term)",
   "serial_number": "C6CC0C33A2EA",
   "interface_list": [
.......

Теперь для того, что бы napalm мог запрашивать данные с устройств, нам необходимо добавить производителя:

1731576364910-819.png

платформу, где выберем ранее добавленного производителя:

1731576239344-294.png

И тип устройства, который можно добавить из шаблона или забить руками.

Далее в появившемся меню napalm, о котором говорилось в самом начале, создаем новую запись, где выбираем нашу платформу и указываем для нее драйвер napalm, в нашем случае "ros".

1731576601376-456.png

Теперь мы можем добавить устройство.

1731659226716-847.png

Заполняем все обязательные поля и платформу, которую мы ранее добавили.

1731659456693-430.png

1731659380401-366.png

После создания устройства переходим во вкладку интерфейсы и добавляем Ip адрес интерфейсу.

1731659505279-560.png

Вбиваем адрес с префиксом маски подсети и возвращаемся обратно в редактирование устройства, где в качестве основного адреса выбираем только что добавленный адрес.

1731659616566-752.png

Сохраняем и теперь мы можем увидеть, что у нас появились новые вкладки на странице устройства.

1731659670999-207.png

1731659694059-548.png

1731659748487-229.png

Еще раз напоминаю, данные получаемые по napalm не хранятся в netbox, а каждый раз запрашиваются с устройства.

окт. 15 2024

Создание кроссового журнала в Netbox

Подготовительные работы.

Для того чтобы использовать функционал кроссового журнала, нам необходимо:

1. Создать сайты к которым у нас будет привязано оборудование.

Сайты это сущности которые по сути могут приравниваться к зданию, помещению или фактическому месту нахождения оборудования.

2. Создать записи о производителях оборудования.

Тут мы заполняем только вендора (Dell, cisco и т.д.), при этом наименование производителя, которого мы завели должно совпадать с производителем в нашем шаблоне..

3. Добавить записи с типами устройств, которые являются шаблонами для непосредственно наших устройств.

Типы устройств могут заполняться вручную или быть загружены из шаблонов (большое количество готовых шаблонов можно найти на GitHuB или в архиве ).

Для загрузки шаблона, переходим в "Типы устройств" -> "типы устройств", жмем импорт и вставляем в поле Data текст шаблона из файла yaml, нажимаем кнопку отправить.

1728979776901-694.png

4. Добавляем наше устройство:

1728980035182-849.png

Если мы выбрали тип устройства, которое добавили из шаблона, то все необходимые интерфейсы будут уже добавлены автоматически, проверить это можно на вкладке interfaces внутри записи о самом устройстве:

1728980163888-744.pngЕсли нам нахватает каких то интерфейсов, мы можем добавить их руками в этой же вкладке.

При желании мы можем назначить на интерфейс оборудования уже имеющийся IP адрес из IPAM или добавить новый, после чего в основных настройках оборудования мы можем выбрать для него основной IP адрес:

1728982001114-363.png1728982045595-515.png

Создание кабельных соединений

После того как мы добавили все необходимые устройства и интерфейсы, можно начать создавать кабельные соединения:

1728982192557-822.png

Переходим в "Подключения" -> "Кабели" и добавляем новое соединение.

1728982287808-946.pngВыбираем устройства на стороне А и Б, интерфейсы и жмем добавить.

Так же новые соединения можно добавлять прямо из вкладки inerfaces внутри самого устройства:

1728982401203-309.png

После создания нового кабельного соединения мы можем посмотреть итоговую таблицу в разделе "Интерфейсные подключения", а также во вкладке Interfaces.

Отрисовка топологии

После создания всех соединений, можно установить плагин "NetBox Topology Views

--- Активируем виртуальное окружение --
$ . /usr/local/share/netbox/venv/bin/activate
--- Создаем каталог для изображений ---
(venv)$ mkdir -p /usr/local/share/netbox/netbox/static/netbox_topology_views/img
--- Ставим плагин ---
(venv)$ pip install netbox-topology-views
--- Добавляем плагин в зависимости Netbox что бы при обновлении он не слетел ---
(venv)$ echo netbox-topology-views >> /usr/local/share/netbox/requirements.txt

Подключаем плагин в файле configuration.py 

PLUGINS = ["netbox_topology_views"]

 Настройки плагина:

PLUGINS_CONFIG = {
   'netbox_topology_views': {
       'static_image_directory': 'netbox_topology_views/img',
       'allow_coordinates_saving': True,
       'always_save_coordinates': True
    }
}

 Теперь необходимо выполнить миграцию и наполнение статического содержимого и перезапустить службы:

(venv)$ cd /usr/local/share/netbox/netbox
(venv)$ python3.11 manage.py migrate
(venv)$ python3.11 manage.py collectstatic --no-input
# service netbox restart
# service netbox_rq restart

 Теперь в интерфейсе у нас должен появиться раздел Topology views 

1728998141323-355.png

Если мы перейдем в раздел Topology и на вкладке Filter поставим "Show cables", то увидим визуализацию всех наших соединений которые мы сделали в разделе "Подключения"

1728998431871-237.png1728998458792-336.png

окт. 01 2024

Инвентаризация хостов Esxi в NetBox

Иногда в организации есть хренова тьма хостов с еще большей хреновой тьмой виртуальных машин, а при отсутствии системы управления например Vcenter или VMM запутаеться где какая ВМ проще чем кажется на первый взгляд.

Так же NetBox можно использовать в качестве "Источника истины" для добавления хостов сети в системы мониторинга на подобии Zabbix через REST API.

Данный скрипт создает сайты, устройства, платформы, интерфейсы устройств и виртуальные машины, а так же привязывает ip адреса к интерфейсам.

Установка

Ставим необходимые пакеты, скачиваем скрипт с GitHub или здесь, проваливаемся в каталог со скриптом.

# pkg install libxml2 libxslt
--- Активируем виртуальное окружение для Python (Будем использовать venv Netbox)---
$ cd /usr/local/share/netbox-scripts/
$ python3.11 -m venv venv
$ . venv/bin/activate
(venv)$ git clone https://github.com/bb-Ricardo/netbox-sync.git
(venv)$ cd netbox-sync/
(venv)$ pip install --upgrade pip
(venv)$ pip install wheel
(venv)$ pip install -r requirements.txt

Тут уже при установке зависимостей у нас может выскочить проблема с разрешением зависимостей для модуля cython, есть два варианта решения:

1 вариант
(venv)$ echo "cython<3" > /tmp/constraint.txt
(venv)$ PIP_CONSTRAINT=/tmp/constraint.txt pip install -r requirements.txt
2 вариант
(venv)$ pip install "cython<3.0.0" wheel
(venv)$ pip install "pyyaml==5.4.1" --no-build-isolation
(venv)$ pip install -r requirements.txt

vsphere-automation-sdk должен быть так же установлен для синхронизации VCenter с Netbox.

Качам отсюда для локальной установки или с GitHub

(venv)$ pip install --upgrade git+https://github.com/vmware/vsphere-automation-sdk-python.git

 Получаем token

1727849741209-465.png

Редактируем settings.ini:

[netbox]
api_token = e34994b01df8ef81a57772336d2005d699118a02
host_fqdn = netbox.example.com
port = 443
validate_tls_certs = False
  

[source/Vcenter]
enabled = True
type = vmware
host_fqdn = 172.16.1.100
port = 443
username = netbox@example.com
password = P@ssw0rd
validate_tls_certs = False
permitted_subnets = 172.16.0.0/12, 10.0.0.0/8, 192.168.0.0/16, fd00::/8, !10.23.42.0/24

Указываем адрес сервера, token, порт и отключаем проверку сертификатов.

Данный скрипт работает как с Vcenter, так и с отдельными хостами ESXI.

Запускаем скрипт

(venv)$ python3.11 net-scan.py -c settings.ini

После выполнения скрипта можно удостовериться, что у нас все добавилось.

1727803773349-617.png1727803855005-821.png

окт. 01 2024

Настройка IPAM в Netbox

При наличии большого количества подсетей зачастую требуется аудит и мониторинг адресного пространства в них, для этого прекрасно подходит такой инструмент, как IPAM.

В качестве инструмента будем использовать Netbox и nmap.

Установка

Для установки нам потребуется скачать уже готовый скрипт от пользователя @lckrspirit с gitlab.

Для удобства его можно разместить где ни будь в каталоге c NetBox.

Качаем nmap, устанавливаем зависимости:

# pkg install 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:

1727787682970-767.png

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

1727787768863-340.png

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

1727787967381-531.png

P.S. В netbox_url должны быть указаны адреса перечисленные в блоке "ALLOWED HOSTS" файла конфигурации Netbox configuration.py.

Запуск скрипта

Для запуска сканирования сети достаточно выполнить:

(venv)$ python3.11 netbox_scan.py 172.16.1.0/24

Теперь можно идти в меню IPAM и мы увидим отсканированные IP адреса.

1728654692264-592.png

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

1727789872325-372.png

Скрипт сам обновляет и удаляет адреса, его можно назначить в задания cron на выполнение к примеру каждые 3 часа.

Дополнительно мы можем создать VLAN, группы и назначения, после чего связать с существующим диапазоном адресов.

Что бы мы могли видеть еще и свободные адреса, необходимо добавить префикс для нашей сети:

1728977476685-464.png

Указываем нашу сеть в поле префикс, статус, и ставим флаг, что данная сеть является пулом.

Синхронизация DNS записей.

Если в качестве DNS сервера используется роль Windows Server, то можно при помощи powershell-скрипта сопоставить найденные nmap ip адреса с записями DNS.

Пример скрипта:

<#
.SYNOPSIS
    Скрипт для синхронизации DNS записей с NetBox
.DESCRIPTION
    Получает A-записи из DNS и обновляет соответствующие IP-адреса в NetBox с DNS именами
.NOTES
    Требует модуля DnsServer для работы с DNS (устанавливается через Install-WindowsFeature RSAT-DNS-Server)
#>


#region Параметры
param (
   [string]$ConfigFile = "config.json"  # Файл конфигурации
)

# Загрузка конфигурации
try {
   if (-not (Test-Path $ConfigFile)) {
       throw "Конфигурационный файл не найден"
    }
   
   $config = Get-Content $ConfigFile | ConvertFrom-Json
   
   # Обязательные параметры
   $netboxUrl = $config.netboxUrl
   $netboxToken = $config.netboxToken
   $dnsServer = $config.dnsServer
   $dnsZone = $config.dnsZone
   
   # Проверка обязательных параметров
   if ([string]::IsNullOrEmpty($netboxUrl) -or
       [string]::IsNullOrEmpty($netboxToken) -or
       [string]::IsNullOrEmpty($dnsServer) -or
       [string]::IsNullOrEmpty($dnsZone)) {
       throw "Не все обязательные параметры указаны в конфигурации"
    }
}
catch {
   Write-Error "Ошибка загрузки конфигурации: $_"
    exit 1
}
#endregion

#region Вспомогательные функции
function Test-NetBoxConnection {
   try {
       $uri = "$netboxUrl/api/status/"
       Write-Host "Проверка подключения к NetBox..."
       
       $headers = @{
           "Authorization" = "Token $netboxToken"
           "Accept" = "application/json"
        }
       
       $response = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -TimeoutSec 5
       
       if ($response) {
           Write-Host "Подключение успешно. Версия NetBox: $($response.netbox_version)" -ForegroundColor Green
           return $true
        }
    }
   catch {
       Write-Error "Ошибка подключения к NetBox: $($_.Exception.Message)"
       return $false
    }
}

function Invoke-NetBoxRequest {
   param(
       [string]$Endpoint,
       [string]$Method = "GET",
       [object]$Body = $null
    )
   
   $uri = "$netboxUrl/api/$($Endpoint.TrimStart('/'))"
   
   try {
       $headers = @{
           "Authorization" = "Token $netboxToken"
           "Accept" = "application/json"
        }

       $params = @{
            Uri = $uri
            Method = $Method
            Headers = $headers
            TimeoutSec = 10
        }

       if ($Body -ne $null) {
           $params["ContentType"] = "application/json"
           $params["Body"] = $Body | ConvertTo-Json -Depth 3
        }

       return Invoke-RestMethod @params
    }
   catch {
       Write-Warning "Ошибка запроса к $uri : $($_.Exception.Message)"
       return $null
    }
}

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
}

function Test-DnsServerConnection {
   try {
       Write-Host "Проверка подключения к DNS серверу $dnsServer..."
       $test = Get-DnsServerZone -ComputerName $dnsServer -Name $dnsZone -ErrorAction Stop
       return $true
    }
   catch {
       Write-Error "Ошибка подключения к DNS серверу: $_"
       return $false
    }
}

function Clean-DnsName {
   param([string]$name)
   
   # Удаляем лишние символы и лишние точки
   $cleanName = $name -replace '[^a-zA-Z0-9\-\.]', '' -replace '\.+', '.' -replace '^\.|\.$', ''
   return $cleanName
}
#endregion

#region Основной процесс
try {
   # Проверка подключений
   if (-not (Test-NetBoxConnection)) { exit 1 }
   if (-not (Test-DnsServerConnection)) { exit 1 }

   Write-Host "Получение DNS записей из зоны $dnsZone..."
   $dnsRecords = Get-DnsServerResourceRecord -ZoneName $dnsZone -ComputerName $dnsServer -ErrorAction Stop |
                 Where-Object { $_.RecordType -eq "A" }

   $totalRecords = $dnsRecords.Count
   $processed = 0
   $updated = 0

   foreach ($record in $dnsRecords) {
       $processed++
       $ip = $record.RecordData.IPv4Address.IPAddressToString
       $name = $record.HostName
       $cleanName = Clean-DnsName -name $name

       Write-Progress -Activity "Синхронизация с NetBox" -Status "Обработка $processed из $totalRecords" -PercentComplete ($processed/$totalRecords*100)

       $nbRecord = Get-NetBoxIpRecord -ipAddress $ip
       if (-not $nbRecord) {
           Write-Warning "IP $ip ($cleanName) не найден в NetBox"
           continue
        }

       if ([string]::IsNullOrWhiteSpace($cleanName)) {
           Write-Warning "Не удалось получить корректное DNS имя для IP $ip"
           continue
        }

       if ($nbRecord.dns_name -ne $cleanName) {
           Write-Host "Обновление: $ip ($(if ($nbRecord.dns_name) { $nbRecord.dns_name } else { 'нет имени' }) → $cleanName)"
           $result = Invoke-NetBoxRequest "ipam/ip-addresses/$($nbRecord.id)/" -Method PATCH -Body @{dns_name = $cleanName}
           if ($result) {
               $updated++
               Write-Host "Успешно обновлено" -ForegroundColor Green
            }
        }
    }

   Write-Host "Синхронизация завершена. Обработано записей: $processed, обновлено: $updated" -ForegroundColor Cyan
}
catch {
   Write-Error "Критическая ошибка: $_"
    exit 1
}
#endregion

Конфигурационный файл в формате json (должен находиться в одном каталоге со скриптом при запуске через планировщик).

{
   "netboxUrl": "https://netbox.example.com",
   "netboxToken": "1234546789qaweasdzxc456789qwe456",
   "dnsServer":example.com"
}

Данный скрипт можно закинуть в планировщик задач и запускать его по расписанию.

$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-ExecutionPolicy Bypass -NoProfile -File `"C:\Scripts\sync-netbox-dns.ps1`""
$trigger = New-ScheduledTaskTrigger -Daily -At 3am
$settings = New-ScheduledTaskSettingsSet -StartWhenAvailable -DontStopOnIdleEnd -ExecutionTimeLimit (New-TimeSpan -Hours 1)
Register-ScheduledTask -TaskName "Sync NetBox DNS" -Action $action -Trigger $trigger -Settings $settings -RunLevel Highest -Description "Синхронизация A-записей DNS с NetBox"