Python 2.7.6 - цикл for не работает с модулем nmap

Я был в этом в течение нескольких часов, и я не могу понять это. Сценарий должен сканировать серверы на наличие порта 22. Однако самая последняя строка кода выдает ошибку «KeyError». Что сбивает с толку, так это то, что это происходит только тогда, когда я использую цикл FOR или создаю функцию и передаю ей значение.

Если код выходит из цикла, последняя строка работает, независимо от того, является ли это жестко запрограммированным IP-адресом или переменной.

Если в последней строке я ввожу loop_1 без одинарных кавычек, я получаю следующую ошибку: Неверный тип для [host], должна быть строка класса 'netaddr.ip.IPAddress'

Я преобразовал его в строку, добавив непосредственно перед последней строкой кода.

value = str(loop_1)

Это, в свою очередь, дает ошибку: KeyError: '10.0.0.0'

Вот сценарий.

import nmap
from netaddr import *

nm = nmap.PortScanner()

for loop_1 in IPNetwork('10.0.0.0/26'):
    print nm.scan('loop_1', '22')
    print nm['loop_1']['tcp'][22]['state']

person George Mastrokostas    schedule 24.12.2014    source источник


Ответы (2)


Если адрес недоступен, вы получите ключевую ошибку от nmap:

import nmap
from netaddr import IPNetwork

nm = nmap.PortScanner()

for loop_1 in IPNetwork('10.0.0.0/26'):
    print(nm.scan(loop_1.format(), '22'))
    try:
       print(nm[loop_1.format()]['tcp'][22]['state'])
    except KeyError as e:
        pass

работает в айпитоне:

In [5]: paste
import nmap
from netaddr import IPNetwork

nm = nmap.PortScanner()

for loop_1 in IPNetwork('192.168.43.65/30'):
    print(loop_1)
    print(nm.scan(loop_1.format(), '22'))
    try:
       print(nm[loop_1.format()]['tcp'][22]['state'])
    except KeyError as e:
        pass

    ## -- End pasted text --
    192.168.43.64
    {'nmap': {'scanstats': {'uphosts': u'0', 'timestr': u'Wed Dec 24 02:41:51 2014', 'downhosts': u'1', 'totalhosts': u'1', 'elapsed': u'3.06'}, 'scaninfo': {u'tcp': {'services': u'22', 'method': u'connect'}}, 'command_line': u'nmap -oX - -p 22 -sV 192.168.43.64'}, 'scan': {}}
    192.168.43.65
    {'nmap': {'scanstats': {'uphosts': u'0', 'timestr': u'Wed Dec 24 02:41:55 2014', 'downhosts': u'1', 'totalhosts': u'1', 'elapsed': u'3.05'}, 'scaninfo': {u'tcp': {'services': u'22', 'method': u'connect'}}, 'command_line': u'nmap -oX - -p 22 -sV 192.168.43.65'}, 'scan': {}}
    192.168.43.66
    {'nmap': {'scanstats': {'uphosts': u'1', 'timestr': u'Wed Dec 24 02:42:01 2014', 'downhosts': u'0', 'totalhosts': u'1', 'elapsed': u'6.14'}, 'scaninfo': {u'tcp': {'services': u'22', 'method': u'connect'}}, 'command_line': u'nmap -oX - -p 22 -sV 192.168.43.66'}, 'scan': {u'192.168.43.66': {'status': {'state': u'up', 'reason': u'syn-ack'}, 'hostname': u'lab', 'vendor': {}, 'addresses': {u'ipv4': u'192.168.43.66'}, u'tcp': {22: {'product': '', 'state': u'open', 'version': '', 'name': u'ssh', 'conf': u'10', 'extrainfo': u'protocol 2.0', 'reason': u'syn-ack', 'cpe': ''}}}}}
    open # only address up so only open or closed received

Если вам нужен список ips и открыт порт или нет, вы можете использовать исключительно nmap:

nm = nmap.PortScanner()

nm.scan(hosts='10.0.0.0/26',ports="22")
results = [[ip, nm[ip]['tcp'][22]['state']] for ip in nm.all_hosts()]

print("ip {}".format(" ".join(*results)))
ip 10.0.0.1 open
....
person Padraic Cunningham    schedule 24.12.2014
comment
Верно. Я могу дойти до этой точки, но это все еще не решает проблему с линейной печатью nm['loop_1']['tcp'][22]['state'] Эта строка, если она не является частью цикла или функции, вывести состояние порта 22. - person George Mastrokostas; 24.12.2014
comment
Я использовал «loop_1», но он просто печатает сканирование ключа. То же самое происходит, если я использую print print(nm[loop_1.format()]['tcp'][22]['state']) - person George Mastrokostas; 24.12.2014
comment
он печатает открыто или закрыто для меня open, не используйте nm['loop_1'], который просто использует строку 'loop_1', вы используете код точно так, как опубликовано? - person Padraic Cunningham; 24.12.2014
comment
Верно. То, что я пытаюсь сделать, чего я не могу сделать в своем исходном коде, - это просто вернуть Open или Close, игнорируя всю другую информацию. Это основная проблема, которая у меня есть. Я не знаю, как это изолировать. Мне просто нужна эта конкретная информация и ничего больше. - person George Mastrokostas; 24.12.2014
comment
Я добавлю код, работающий и работающий на моей машине, он работает именно так, как вы хотите, но вы увидите открытое или закрытое только тогда, когда у вас есть ip, который up акцентирует внимание на up - person Padraic Cunningham; 24.12.2014
comment
чтобы увидеть пример, передайте свой локальный IP-адрес в виде строки, например "192.168.43.65" вместо loop_1.format(), и вы поймете, что я имею в виду. - person Padraic Cunningham; 24.12.2014
comment
Я играю и начинаю понимать, что вы изначально сказали. Мой оригинальный код выходит из строя, когда он не может достичь определенного IP-адреса. Сейчас я пытаюсь изолировать только OPEN. Прямо сейчас это дает мне результаты в формате: Нет "10.0.0.27" Нет "10.0.0.28" Нет открыто Нет "10.0.0.30" Спасибо за вашу помощь. Я пытался в течение нескольких часов понять это :( Я действительно ценю это. - person George Mastrokostas; 24.12.2014
comment
так что первый отпечаток иногда возвращает None? - person Padraic Cunningham; 24.12.2014
comment
Да. Я немного изменил способ вывода формата, выполнив следующие действия: 'code' import nmap from netaddr import IPNetwork nm = nmap.PortScanner() for loop_1 в IPNetwork('10.0.0.1/26'): (nm.scan(loop_1 .format(), '22')).get('state') try: state = (nm[loop_1.format()]['tcp'][22]['state']) if state == open: print loop_1, IS , состояние elif state ==closed: передать кроме KeyError as e: print(e) 'code' Я очень ценю вашу помощь. Я занимаюсь Python второй месяц, и мне нужно многому научиться. - person George Mastrokostas; 24.12.2014

Ваш код цикла не работает:

for loop_1 in IPNetwork('10.0.0.0/26'):
    print nm.scan('loop_1', '22')
    print nm['loop_1']['tcp'][22]['state']

loop_1 вверху — это переменная, которая является адресом для сканирования. Но позже вы используете литеральную строку 'loop_1', которая не является переменной. Вы сказали, что если вы используете loop_1 без кавычек, вы получите сообщение об ошибке, говорящее о том, что вместо IP-адреса требуется строка... поэтому вы должны просто прочитать документацию для класса IP-адреса, чтобы узнать, как преобразовать его в строку (возможно, просто str(loop_1)?) перед тем, как поставить его в скобки.

person John Zwinck    schedule 24.12.2014
comment
Это не проблема - person Padraic Cunningham; 24.12.2014
comment
Я попытался преобразовать в строку, а затем выдает KeyError: 10.0.0.0 - person George Mastrokostas; 24.12.2014
comment
@PadraicCunningham: интересно, как вы говорите, что проблема не в этом, но ваш ответ включает предложенные мной исправления. Я вижу, вы нашли дополнительные вещи, которые нужно исправить, но утверждение, что использование строки там, где предполагалась переменная, не является проблемой, кажется натянутым. - person John Zwinck; 24.12.2014
comment
проблема в том, что namp выдает ошибку ключа для любого IP-адреса, который не возвращает никакого результата, так что это настоящая проблема, OP также уже пробовал str(loop_1), который работает так же, как loop_1.format(). - person Padraic Cunningham; 24.12.2014