Как получить IP-адрес с помощью nslookup и python в Windows

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

Одно такое изменение произошло, когда я использовал nslookup и python для поиска ip addresses в Windows, поскольку в основном у меня нет Mac или Linux.

Как мы можем получить только IP-адрес «URL верхнего уровня» (tld) с помощью python и nslookup по состоянию на 2019 год?


person SowingFiber    schedule 02.10.2019    source источник
comment
Вы имеете в виду, как разрешить имя хоста? Сами TLD не имеют IP-адресов. Можете ли вы привести примеры входных данных и ожидаемых результатов?   -  person Ulrich Eckhardt    schedule 02.10.2019
comment
Не выполняйте внешнюю команду, если в вашем языке программирования есть все библиотеки, необходимые для выполнения той же операции. См. библиотеку dnspython. Вот почему в отношении того, как некоторые функции и команды обеспечивают вывод, произошли некоторые изменения. вам следует перестать пытаться анализировать внешние команды, которые никогда не ожидаются, и использовать соответствующие функции для получения нужного вам результата.   -  person Patrick Mevzek    schedule 03.10.2019


Ответы (3)


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

In [2]: import dns

In [3]: import dns.resolver

In [5]: import dns.rdataclass

In [7]: import dns.rdatatype

In [9]: ans = dns.resolver.query('www.example.com', rdtype=dns.rdatatype.A, rdclass=dns.rdataclass.IN)

In [10]: print ans.rrset
www.example.com. 43193 IN A 93.184.216.34

In [12]: print ans.rrset[0]
93.184.216.34

Прочтите полную документацию по адресу http://www.dnspython.org/docs/1.16.0/ для более подробной информации, особенно входных и выходных параметров.

Два важных момента:

  • не думайте, что query всегда будет успешным; обязательно обработайте его ошибки
  • не думайте, что query обязательно вернет вам записи того типа, который вы ожидали, вы можете получить что-то совершенно другое, поэтому вам нужно проверить, а не делать слепые предположения.
person Patrick Mevzek    schedule 03.10.2019

Я посмотрел на SO и нашел этот ответ

Предоставленное решение является хорошей отправной точкой. На основании вышеуказанных требований решение может быть изменено в соответствии с описанным выше вариантом использования.

Если вы используете nslookup google.com в своей консоли в Windows, вы найдете аналогичный вывод:

Non-authoritative answer:

Server:  UnKnown
Address:  192.168.0.1

Name:    facebook.com
Addresses:  2a03:2880:f12f:183:face:b00c:0:25de
      31.13.79.35

Следуя ссылочному решению, эти две строки являются сердцевиной нашего решения:

process = subprocess.Popen(["nslookup", url], stdout=subprocess.PIPE)
output = str(process.communicate()[0]).split('\\r\\n')

Если вы напечатаете вывод в консоли, вы получите результат, аналогичный этому:

["b'Server:  UnKnown", 'Address:  192.168.0.1', '', 'Name:    facebook.com', 'Addresses:  2a03:2880:f12f:183:face:b00c:0:25de', '\\t  31.13.79.35', '', "'"]

Этого списка достаточно для описанного выше варианта использования. Следующее, что нужно сделать, это найти надежный способ всегда получать 6th element, который равен "\\t 31.13.79.35".

Чтобы упростить задачу, я использовал нарезку индекса, чтобы получить 6th element с помощью output[5].

Я тестировал этот код около 10-15 раз, используя разные URL-адреса, и получил аналогичные результаты. Лучшим способом было бы каким-то образом определить адрес, перебирая элементы списка в выводе.

Опять же, для приведенного выше варианта использования использование output[5] работает достаточно хорошо. Если кто-то может предложить более надежный способ определения IP-адреса в списке, сделайте это.

get_ip_address.py

import subprocess


def get_ip_address(url):
    process = subprocess.Popen(
        ["nslookup", url], stdout=subprocess.PIPE)
    output = str(process.communicate()[0]).split('\\r\\n')
    address = output[5].replace('\\t ', '')
    return address


print(get_ip_address('google.com'))

person SowingFiber    schedule 02.10.2019
comment
Не выполняйте внешнюю команду, если в вашем языке программирования есть все библиотеки, необходимые для выполнения той же операции. См. библиотеку dnspython. Анализ текстового результата команды, никогда не предназначенной для анализа, является хрупким. - person Patrick Mevzek; 03.10.2019

Возможно, вы сэкономите время, используя nmap

pip install python-nmap

Тогда ваш скрипт Python просто:

import nmap

scan = nmap.Portscanner()

scan.scan('127.0.0.1', '21-443') # Returns scan on ports from 21-433 

Если вы сканируете что-то, с чем хотите быть осторожным, рассмотрите возможность использования proxychains, который представляет собой службу на основе tor с использованием SOCKS5. Вы можете использовать такие варианты, как -O -I, чтобы идентифицировать операционные системы, которые использует IP-адрес, и некоторую информацию о том, какие сокеты открыты или закрыты.

Есть много полезных методов, таких как:

>>> scan.scaninfo()
{'tcp': {'services': '22-443', 'method': 'connect'}}

>>> scan.all_hosts()
['127.0.0.1']

>>> scan['127.0.0.1'].hostname()
'localhost'

>>> scan['127.0.0.1'].state()
'up'

>>> scan['127.0.0.1'].all_protocols()
['tcp']

>>> scan['127.0.0.1']['tcp'].keys()
[80, 25, 443, 22, 111]

>>> scan['127.0.0.1'].has_tcp(22)
True

>>> scan['127.0.0.1'].has_tcp(23)
False

>>> scan['127.0.0.1']['tcp'][22]
{'state': 'open', 'reason': 'syn-ack', 'name': 'ssh'}

>>> scan['127.0.0.1'].tcp(22)
{'state': 'open', 'reason': 'syn-ack', 'name': 'ssh'}
person Barb    schedule 02.10.2019
comment
Использование nmap и преобразование имени в IP-адрес — две совершенно не связанные между собой вещи. - person Patrick Mevzek; 03.10.2019
comment
nmap -sn возвращает все имена хостов и IP-адреса в более новой версии. Я думаю, что OP пытается получить имена хостов, потому что у TLD нет IP-адреса. - person Barb; 03.10.2019
comment
nmap — это инструмент для подключения к хостам и определения открытых портов (среди прочего). nslookup — это инструмент, который выполняет DNS-запросы, обычно сопоставляя имя с IP-адресом. Это концептуально совершенно разные вещи. - person Patrick Mevzek; 03.10.2019
comment
Nmap имеет параллельный механизм обратного разрешения DNS, который обычно используется как часть сканирования nmap, но также может использоваться независимо от функции сканирования для перечисления DNS. - person Barb; 03.10.2019
comment
Тот факт, что вы игнорируете тот факт, что TLD не имеет IP-адреса, говорит больше, чем попытка опровергнуть более простой метод решения вопроса о том, что OP имеет в виду - person Barb; 03.10.2019
comment
Ваше решение немного вводит в заблуждение. Дело в винде, пока не установишь nmap и не добавишь в путь, команда nmap.PortScanner() не работает. - person Hikki; 03.10.2019
comment
TLD не имеет IP-адреса, что неверно. .DK имеет IP-адрес. И это не единственный. - person Patrick Mevzek; 05.10.2019