first
This commit is contained in:
29
Dockerfile
Normal file
29
Dockerfile
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
# Použití základního Python image
|
||||||
|
FROM python:3.14-rc-slim
|
||||||
|
|
||||||
|
# Instalace Tini
|
||||||
|
RUN apt-get update && apt-get install -y tini
|
||||||
|
|
||||||
|
# Nastavení Tini jako init procesu
|
||||||
|
ENTRYPOINT ["/usr/bin/tini", "--"]
|
||||||
|
|
||||||
|
# Nastavení pracovního adresáře
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Zkopírování požadavků
|
||||||
|
COPY requirements.txt requirements.txt
|
||||||
|
|
||||||
|
# Instalace Python knihoven
|
||||||
|
RUN pip install --upgrade pip
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
# Zkopírování Python skriptu do pracovního adresáře
|
||||||
|
COPY ipscan-v2.py ipscan-v2.py
|
||||||
|
|
||||||
|
# Instalace nmap
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y nmap && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Spuštění Python skriptu
|
||||||
|
CMD ["python", "ipscan.py"]
|
||||||
6
docker-compose.yml
Normal file
6
docker-compose.yml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
version: '3'
|
||||||
|
services:
|
||||||
|
netbox-importer:
|
||||||
|
build: .
|
||||||
|
container_name: netbox_importer
|
||||||
|
tty: true
|
||||||
99
ipscan-v2.py
Normal file
99
ipscan-v2.py
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
import os
|
||||||
|
import nmap
|
||||||
|
import pynetbox
|
||||||
|
import requests
|
||||||
|
import socket
|
||||||
|
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||||
|
|
||||||
|
# Disable SSL Warnings
|
||||||
|
requests.packages.urllib3.disable_warnings()
|
||||||
|
|
||||||
|
# Disable SSL Verification
|
||||||
|
os.environ['PYTHONHTTPSVERIFY'] = '0'
|
||||||
|
|
||||||
|
# Initiate the port scanner
|
||||||
|
nm = nmap.PortScanner()
|
||||||
|
|
||||||
|
# Scan the subnet for hosts (replace with your networks)
|
||||||
|
networks = [
|
||||||
|
"192.168.85.0/24",
|
||||||
|
"192.168.86.0/24"
|
||||||
|
]
|
||||||
|
|
||||||
|
# NetBox configuration
|
||||||
|
netbox = pynetbox.api(url='https://netbox.xxxxx.xx/', token='xxxxx')
|
||||||
|
|
||||||
|
tenant = "Xxxxx Praha"
|
||||||
|
|
||||||
|
def scan_network(network):
|
||||||
|
print(f"Scanning network: {network}")
|
||||||
|
nm.scan(hosts=network, arguments='-p 1-32768 -T4 --host-timeout 2m') # Adding a host-timeout of 2 minutes
|
||||||
|
host_results = []
|
||||||
|
for host in nm.all_hosts():
|
||||||
|
if 'tcp' in nm[host]:
|
||||||
|
ports = [port for port in nm[host]['tcp'] if nm[host]['tcp'][port]['state'] == 'open']
|
||||||
|
ports_str = ' '.join(str(port) for port in ports)
|
||||||
|
else:
|
||||||
|
ports_str = ''
|
||||||
|
host_results.append((host, nm[host]['status']['state'], ports_str))
|
||||||
|
print(f"Host: {host}, Status: {nm[host]['status']['state']}, Open Ports: {ports_str}")
|
||||||
|
return host_results
|
||||||
|
|
||||||
|
def add_ip_to_netbox(host, status, ports):
|
||||||
|
if status == 'up':
|
||||||
|
try:
|
||||||
|
hostname = socket.gethostbyaddr(host)[0]
|
||||||
|
except socket.herror:
|
||||||
|
hostname = host # Use the IP if the hostname couldn't be resolved
|
||||||
|
|
||||||
|
ip_data = {
|
||||||
|
"address": f"{host}/24",
|
||||||
|
"dns_name": hostname,
|
||||||
|
"status": "active",
|
||||||
|
"tenant": tenant,
|
||||||
|
"comments": f"Open ports: {ports}",
|
||||||
|
# Add other fields as needed
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create or update the IP address in NetBox
|
||||||
|
print(f"Adding IP address: {ip_data['address']}, Hostname: {hostname}, Open Ports: {ports}")
|
||||||
|
netbox.ipam.ip_addresses.create(ip_data)
|
||||||
|
|
||||||
|
# Create a thread pool and scan networks in parallel
|
||||||
|
hosts_list = []
|
||||||
|
with ThreadPoolExecutor(max_workers=5) as executor: # Adjust number of workers as needed
|
||||||
|
future_to_network = {executor.submit(scan_network, network): network for network in networks}
|
||||||
|
for future in as_completed(future_to_network):
|
||||||
|
network = future_to_network[future]
|
||||||
|
try:
|
||||||
|
data = future.result()
|
||||||
|
hosts_list.extend(data)
|
||||||
|
except Exception as exc:
|
||||||
|
print(f"{network} generated an exception: {exc}")
|
||||||
|
|
||||||
|
# Add each IP address to NetBox
|
||||||
|
with ThreadPoolExecutor(max_workers=5) as executor: # Adjust number of workers as needed
|
||||||
|
futures = [executor.submit(add_ip_to_netbox, host, status, ports) for host, status, ports in hosts_list]
|
||||||
|
for future in as_completed(futures):
|
||||||
|
future.result()
|
||||||
|
|
||||||
|
# Get all IP addresses from NetBox
|
||||||
|
all_ip_addresses = netbox.ipam.ip_addresses.all()
|
||||||
|
|
||||||
|
# Create a list of hostnames from the scanned hosts
|
||||||
|
scanned_hosts = []
|
||||||
|
for host, status, ports in hosts_list:
|
||||||
|
if status == 'up':
|
||||||
|
try:
|
||||||
|
hostname = socket.gethostbyaddr(host)[0]
|
||||||
|
except socket.herror:
|
||||||
|
hostname = host # Use the IP if the hostname couldn't be resolved
|
||||||
|
scanned_hosts.append(hostname)
|
||||||
|
|
||||||
|
# Check each IP address in NetBox
|
||||||
|
for ip_address in all_ip_addresses:
|
||||||
|
# If the IP address's hostname was not found in the scan results, mark it as offline
|
||||||
|
if ip_address.description not in scanned_hosts:
|
||||||
|
ip_address.status = 'offline'
|
||||||
|
ip_address.save()
|
||||||
|
print(f"Marked IP address {ip_address.address} as offline in NetBox.")
|
||||||
3
requirements.txt
Normal file
3
requirements.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
python-nmap==0.7.1
|
||||||
|
pynetbox==7.4.1
|
||||||
|
requests==2.32.3
|
||||||
72
scanner.py
Normal file
72
scanner.py
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
import os
|
||||||
|
import nmap
|
||||||
|
import pynetbox
|
||||||
|
import requests
|
||||||
|
import socket
|
||||||
|
|
||||||
|
# Disable SSL Warnings
|
||||||
|
requests.packages.urllib3.disable_warnings()
|
||||||
|
|
||||||
|
# Disable SSL Verification
|
||||||
|
os.environ['PYTHONHTTPSVERIFY'] = '0'
|
||||||
|
|
||||||
|
# Initiate the port scanner
|
||||||
|
nm = nmap.PortScanner()
|
||||||
|
|
||||||
|
# Scan the subnet for hosts for example 192.168.1.0/24
|
||||||
|
nm.scan(hosts='192.168.1.0/24', arguments='-sn')
|
||||||
|
|
||||||
|
# Get a list of all hosts that are up
|
||||||
|
hosts_list = [(x, nm[x]['status']['state']) for x in nm.all_hosts()]
|
||||||
|
for host, status in hosts_list:
|
||||||
|
print(f'{host} is {status}')
|
||||||
|
|
||||||
|
# Enter your Netbox url and token
|
||||||
|
netbox = pynetbox.api(url='https://example.com', token='TOKENHERE', ssl_verify=False)
|
||||||
|
|
||||||
|
# Add each host to NetBox
|
||||||
|
for host, status in hosts_list:
|
||||||
|
if status == 'up':
|
||||||
|
try:
|
||||||
|
hostname = socket.gethostbyaddr(host)[0]
|
||||||
|
except socket.herror:
|
||||||
|
hostname = host # Use the IP if the hostname couldn't be resolved
|
||||||
|
|
||||||
|
device_data = {
|
||||||
|
"name": hostname,
|
||||||
|
"device_type": 1, # device type ID
|
||||||
|
"device_role": 1, # device role ID
|
||||||
|
"site": 1, # site ID
|
||||||
|
"status": "active",
|
||||||
|
# Add other fields as needed
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get all the devices from NetBox
|
||||||
|
all_devices = netbox.dcim.devices.all()
|
||||||
|
|
||||||
|
# Create a list of hostnames from the scanned hosts
|
||||||
|
scanned_hosts = []
|
||||||
|
for host, status in hosts_list:
|
||||||
|
if status == 'up':
|
||||||
|
try:
|
||||||
|
hostname = socket.gethostbyaddr(host)[0]
|
||||||
|
except socket.herror:
|
||||||
|
hostname = host # Use the IP if the hostname couldn't be resolved
|
||||||
|
scanned_hosts.append(hostname)
|
||||||
|
|
||||||
|
# Check each device in NetBox
|
||||||
|
for device in all_devices:
|
||||||
|
# If the device was not found in the scan results, mark it as offline
|
||||||
|
if device.name not in scanned_hosts:
|
||||||
|
device.status = 'offline'
|
||||||
|
device.save()
|
||||||
|
print(f"Marked {device.name} as offline in NetBox.")
|
||||||
|
|
||||||
|
# Remove the IP address of the offline device from NetBox
|
||||||
|
try:
|
||||||
|
ip_address = netbox.ipam.ip_addresses.get(address=f"{device.name}/24")
|
||||||
|
if ip_address:
|
||||||
|
ip_address.delete()
|
||||||
|
print(f"Deleted IP address {device.name} from NetBox.")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Failed to delete IP address {device.name} from NetBox: {e}")
|
||||||
Reference in New Issue
Block a user