Глядя на ваш код, я вижу некоторые проблемы с DNS, некоторые проблемы Python и некоторые проблемы с DNS python. Давайте посмотрим, не сможем ли мы чему-то научиться вместе.
DNS
Во-первых, параметр вашей функции getNSResults
называется url
. Когда вы отправляете DNS-запросы, вы запрашиваете имя домена . URL - это нечто совершенно другое (например, https://example.com/index.html
). Я бы переименовал url
во что-то вроде domain_name
, domain
или name
. Подробнее о разнице между URL-адресами и именами доменов см. https://www.copahost.com/blog/domain-vs-url/.
Во-вторых, давайте поговорим о том, что вы пытаетесь сделать.
В настоящее время я пытаюсь найти способ проверить, могут ли серверы имен отвечать на пакеты tcp или udp.
Моя идея заключалась в том, чтобы получить все серверы имен с веб-сайта (например, Google .com), сохраните их в списке, а затем попробуйте отправить всем tcp и udp сообщения.
Звучит как отличный подход. Я думаю, вы можете упустить некоторые детали здесь. поэтому позвольте мне объяснить шаги, которые вы можете предпринять, чтобы сделать это:
- Выполните запрос NS для доменного имени. У вас уже есть этот шаг в вашем коде. Что вы на самом деле получите из этого запроса, так это просто другое доменное имя (или несколько доменных имен). Например, если вы запустите
dig +short NS google.com
, вы получите такой вывод:
ns3.google.com.
ns1.google.com.
ns4.google.com.
ns2.google.com.
На этом шаге у нас есть список из одного или нескольких имен авторитетных серверов. Теперь нам нужен IP-адрес для отправки запросов. Поэтому мы сделаем запрос типа A для каждого из имен, которые мы получили на шаге 1. Теперь у нас есть список IP-адресов. Мы можем отправить DNS-запрос по UDP и один по TCP, чтобы убедиться, что они поддерживаются.
Python
По большей части ваш синтаксис Python в порядке , Самым большим красным флажком, который я вижу, является следующий код:
results.update({"nsName" == nameServer,
"receivedUDPPacket" == isNotNone(udpPacket),
"receivedTCPPacket" == isNotNone(tcpPacket)})
Давайте разберем это немного. Во-первых, у вас есть results
, то есть dict
. Тогда у вас есть это:
{"nsName" == nameServer,
"receivedUDPPacket" == isNotNone(udpPacket),
"receivedTCPPacket" == isNotNone(tcpPacket)}
, что составляет set
из bool
с. Я думаю, что вы хотели сделать что-то вроде этого:
results.update({
"nsName": nameServer,
"receivedUDPPacket": true,
"receivedTCPPacket": true
})
Имена функций и переменных в Python обычно пишутся строчными буквами, а слова разделяются подчеркиванием (например, my_variable
, def my_function()
) , Имена классов обычно в верхнем верблюжьем регистре (например, class MyClass
). Ничего из этого не требуется, вы можете называть свой материал по своему усмотрению, множество супер-популярных библиотек и встроенных программ нарушают это соглашение, просто подумав, что я его выброшу, потому что это может быть полезно при чтении Python кода.
днс python
Когда вы не уверены в типах вещей или в каких атрибутах вещей, запомните этих четырех друзей, встроенных в Python: 1. pdb
2. dir
3. type
4. print
pdb
- отладчик Python. Просто import pdb
и поставьте pdb.set_trace()
там, где вы хотите сломаться. Ваш код остановится на этом, и тогда вы сможете проверить значения всех переменных.
dir
вернет атрибуты и методы того, что вы передадите ему. Пример: print(dir(udpPacket))
.
type
вернет тип объекта.
print
, как вы, вероятно, уже знаете, распечатает материал, чтобы вы могли его видеть.
Я собираюсь оставить эту часть для вас, чтобы проверить. Запустите dir()
на всем, если вы не знаете, что это такое. Я также, вероятно, должен упомянуть help()
, который очень полезен для встроенных вещей.
Резюме этого раздела таково, что иногда документации не все, или ее трудно найти, особенно когда вы новый язык / библиотека / что угодно. Таким образом, вы должны разобраться с этим самостоятельно, а это означает, что вы используете все инструменты, которые я только что упомянул, просматривая исходный код и тому подобное.
Резюме
Я надеюсь, что это было полезно. Я знаю, что это много, возможно, это слишком много, но просто наберитесь терпения и знайте, что DNS и Python очень полезны и интересны для изучения.
Я продолжил и написал кое-что, что начать с того, что я думаю, вы надеетесь достичь. Я рекомендую пройти через все это и убедиться, что вы понимаете, что происходит. Если вы чего-то не понимаете, запомните pdb
и dir
(и всегда есть Google, SO, et c).
import dns.resolver
import dns.message
import dns.rdatatype
import json
import sys
def check_tcp_and_udp_support(name):
# this will give me the first default system resolver from /etc/resolv.conf
# (or Windows registry)
where = dns.resolver.Resolver().nameservers[0]
q = dns.message.make_query(name, dns.rdatatype.NS)
ns_response = dns.query.udp(q, where)
ns_names = [t.target.to_text() for ans in ns_response.answer for t in ans]
# this code is the same as the one-liner above
# ns_names = []
# for ans in ns_response.answer:
# for t in ans:
# ns_names.append(t.target.to_text())
results = {}
for ns_name in ns_names:
# do type A lookup for nameserver
q = dns.message.make_query(ns_name, dns.rdatatype.A)
response = dns.query.udp(q, where)
nameserver_ips = [item.address for ans in response.answer for item in ans.items if ans.rdtype == dns.rdatatype.A]
# now send queries to the nameserver IPs
for nameserver_ip in nameserver_ips:
q = dns.message.make_query('example.com.', dns.rdatatype.A)
try:
udp_response = dns.query.udp(q, nameserver_ip)
supports_udp = True
except dns.exception.Timeout:
supports_udp = False
try:
tcp_response = dns.query.tcp(q, nameserver_ip)
supports_tcp = True
except dns.exception.Timeout:
supports_tcp = True
results[nameserver_ip] = {
'supports_udp': supports_udp,
'supports_tcp': supports_tcp
}
return results
def main():
results = check_tcp_and_udp_support('google.com')
# this is just fancy JSON printing
# you could do print(results) instead
json.dump(results, sys.stdout, indent=4)
if __name__ == '__main__':
main()
Опять же, я надеюсь, что это полезно. Тяжело, когда я не знаю точно, что происходит в твоей голове, но это то, что у меня есть для тебя.