using paramiko to get hostnames

This commit is contained in:
José Lopes 2018-09-27 11:34:43 -03:00
parent c4a78cf5ab
commit 5c97c3dfdd
4 changed files with 41 additions and 10 deletions

View File

@ -1,14 +1,22 @@
# netbox-scanner configuration file.
TAG = 'auto'
UNKNOWN = 'UNKNOWN HOST'
LOG = '.' # path to logfile
NETBOX = {
'ADDRESS': 'https://',
'TOKEN': '',
'TLS_VERIFY': True
}
TAG = 'auto'
UNKNOWN = 'UNKNOWN HOST'
LOG = '.' # path to logfile
DEVICE_AUTH = {
'CISCO': {
'USER': '',
'PASSWORD': '',
'COMMAND': 'show run | inc hostname'
}
}
# These are the networks to be scanned.
# Example: ['192.168.40.0/20', '10.2.50.0/24']

View File

@ -1,26 +1,47 @@
import re
import logging
from ipaddress import IPv4Network
from nmap import PortScanner
from cpe import CPE
from pynetbox import api
from paramiko import SSHClient, AutoAddPolicy
from paramiko.ssh_exception import AuthenticationException, SSHException, NoValidConnectionsError
# paramiko is too noisy
logging.getLogger('paramiko').setLevel(logging.CRITICAL)
class NetBoxScanner(object):
def __init__(self, address, token, tls_verify, tag, unknown):
def __init__(self, address, token, tls_verify, devs_auth, tag, unknown):
self.netbox = api(address, token=token, ssl_verify=tls_verify)
self.devs = devs_auth
self.tag = tag
self.unknown = unknown
def get_description(self, name, cpe):
def get_description(self, address, name, cpe):
'''Define a description based on hostname and CPE'''
if name:
return name
else:
c = CPE(cpe[0], CPE.VERSION_2_3)
return '{}.{}.{}'.format(c.get_vendor()[0],
c.get_product()[0], c.get_version()[0])
vendor = c.get_vendor()[0].upper()
if vendor in self.devs:
try:
client = SSHClient()
client.set_missing_host_key_policy(AutoAddPolicy())
client.connect(address, username=self.devs[vendor]['USER'],
password=self.devs[vendor]['PASSWORD'])
stdin, stdout, stderr = client.exec_command(self.devs[vendor]['COMMAND'])
return '{}: {}'.format(vendor.lower(),
re.search(r'hostname ([A-Z|a-z|0-9|\-|_]+)',
str(stdout.read().decode('utf-8'))).group(1))
except (AuthenticationException, SSHException, NoValidConnectionsError):
pass
return '{}.{}.{}'.format(c.get_vendor()[0], c.get_product()[0],
c.get_version()[0])
def nbhandler(self, command, **kwargs):
'''Handles NetBox integration'''
@ -53,7 +74,7 @@ class NetBoxScanner(object):
address = nm[host]['addresses']['ipv4']
try:
description = self.get_description(
nm[host]['hostnames'][0]['name'],
address, nm[host]['hostnames'][0]['name'],
nm[host]['osmatch'][0]['osclass'][0]['cpe'])
except (KeyError, AttributeError, IndexError):
description = self.unknown

View File

@ -19,6 +19,8 @@ argp.add_argument('-t', '--token', help='netbox access token',
default=config.NETBOX['TOKEN'])
argp.add_argument('-v', '--verify', help='tls verify',
action='store_true', default=config.NETBOX['TLS_VERIFY'])
argp.add_argument('-d', '--devices', help='device authentication crendentials',
default=config.DEVICE_AUTH)
argp.add_argument('-g', '--tag', help='netbox-scanner tag',
default=config.TAG)
argp.add_argument('-u', '--unknown', help='netbox-scanner unknown host',
@ -34,7 +36,7 @@ logging.basicConfig(filename='{}/netbox-scanner-{}.log'.format(args.log,
disable_warnings(InsecureRequestWarning)
nbs = NetBoxScanner(args.address, args.token, args.verify, args.tag, args.unknown)
nbs = NetBoxScanner(args.address, args.token, args.verify, args.devices, args.tag, args.unknown)
logging.info('started: {} networks'.format(len(args.networks)))
stats = nbs.sync(args.networks)
logging.info('finished: +{} ~{} -{} ?{} !{}'.format(stats[0], stats[1],

View File

@ -7,7 +7,7 @@ with open('README.md', 'r') as fh:
setuptools.setup(
name='netbox-scanner',
version='0.3.2',
version='0.4.0',
author='José Lopes de Oliveira Jr.',
author_email='jlojunior@gmail.com',
description='A scanner util for NetBox',