dnspythonzal mijn DNS-lookups heel goed doen, maar het negeert volledig de inhoud van /etc/hosts
.
Is er een python-bibliotheekoproep die het juiste doet? dwz controleer eerst in etc/hosts
, en val anders alleen terug op DNS-lookups?
Antwoord 1, autoriteit 100%
Ik weet niet zeker of je zelfDNS-lookups wilt doen of dat je alleen het IP-adres van een host wilt. Als je het laatste wilt,
/!\ socket.gethostbyname is verouderd, geef de voorkeur aan socket.getaddrinfo
van man gethostbyname
:
De functies gethostbyname*(), gethostbyaddr*(), […] zijn verouderd. Toepassingen moeten getaddrinfo(3), getnameinfo(3),
. gebruiken
import socket
print(socket.gethostbyname('localhost')) # result from hosts file
print(socket.gethostbyname('google.com')) # your os sends out a dns query
Antwoord 2, autoriteit 77%
De normale naamresolutie in Python werkt prima. Waarom heb je daar DNSpython voor nodig. Gebruik gewoon socket‘s getaddrinfo
die de geconfigureerde regels volgt voor uw besturingssysteem (op Debian volgt dit /etc/nsswitch.conf
:
>>> print(socket.getaddrinfo('google.com', 80))
[(10, 1, 6, '', ('2a00:1450:8006::63', 80, 0, 0)), (10, 2, 17, '', ('2a00:1450:8006::63', 80, 0, 0)), (10, 3, 0, '', ('2a00:1450:8006::63', 80, 0, 0)), (10, 1, 6, '', ('2a00:1450:8006::68', 80, 0, 0)), (10, 2, 17, '', ('2a00:1450:8006::68', 80, 0, 0)), (10, 3, 0, '', ('2a00:1450:8006::68', 80, 0, 0)), (10, 1, 6, '', ('2a00:1450:8006::93', 80, 0, 0)), (10, 2, 17, '', ('2a00:1450:8006::93', 80, 0, 0)), (10, 3, 0, '', ('2a00:1450:8006::93', 80, 0, 0)), (2, 1, 6, '', ('209.85.229.104', 80)), (2, 2, 17, '', ('209.85.229.104', 80)), (2, 3, 0, '', ('209.85.229.104', 80)), (2, 1, 6, '', ('209.85.229.99', 80)), (2, 2, 17, '', ('209.85.229.99', 80)), (2, 3, 0, '', ('209.85.229.99', 80)), (2, 1, 6, '', ('209.85.229.147', 80)), (2, 2, 17, '', ('209.85.229.147', 80)), (2, 3, 0, '', ('209.85.229.147', 80))]
Antwoord 3, autoriteit 3%
Het klinkt alsof je dns niet zelf wilt oplossen (dit kan de verkeerde nomenclatuur zijn) dnspython lijkt een zelfstandige dns-client te zijn die begrijpelijkerwijs je besturingssysteem negeert omdat het de hulpprogramma’s van het besturingssysteem omzeilt.
We kunnen kijken naar een shell-hulpprogramma met de naam getent
om te begrijpen hoe het (debian 11 gelijkaardige) besturingssysteem dns voor programma’s oplost, dit is waarschijnlijk de standaard voor alle *nix-achtige systemen die een socket gebruiken implementatie.
zie de sectie “hosts” van man getent
, waarin het gebruik van getaddrinfo
wordt genoemd, wat we kunnen zien als man getaddrinfo
en om het in python te gebruiken, moeten we wat informatie uit de datastructuren halen
.
import socket
def get_ipv4_by_hostname(hostname):
# see `man getent` `/ hosts `
# see `man getaddrinfo`
return list(
i # raw socket structure
[4] # internet protocol info
[0] # address
for i in
socket.getaddrinfo(
hostname,
0 # port, required
)
if i[0] is socket.AddressFamily.AF_INET # ipv4
# ignore duplicate addresses with other socket types
and i[1] is socket.SocketKind.SOCK_RAW
)
print(get_ipv4_by_hostname('localhost'))
print(get_ipv4_by_hostname('google.com'))
Antwoord 4, autoriteit 2%
list( map( lambda x: x[4][0], socket.getaddrinfo( \
'www.example.com.',22,type=socket.SOCK_STREAM)))
geeft u een lijst van de adressen voor www.example.com. (ipv4 en ipv6)
Antwoord 5
Deze code werkt goed voor het retourneren van alle IP-adressen die mogelijk tot een bepaalde URI behoren. Aangezien veel systemen zich nu in een gehoste omgeving bevinden (AWS/Akamai/etc.), kunnen systemen meerdere IP-adressen retourneren. De lambda is “geleend” van @Peter Silva.
def get_ips_by_dns_lookup(target, port=None):
'''
this function takes the passed target and optional port and does a dns
lookup. it returns the ips that it finds to the caller.
:param target: the URI that you'd like to get the ip address(es) for
:type target: string
:param port: which port do you want to do the lookup against?
:type port: integer
:returns ips: all of the discovered ips for the target
:rtype ips: list of strings
'''
import socket
if not port:
port = 443
return list(map(lambda x: x[4][0], socket.getaddrinfo('{}.'.format(target),port,type=socket.SOCK_STREAM)))
ips = get_ips_by_dns_lookup(target='google.com')
Antwoord 6
Ik heb deze manier gevonden om een DNS RR-hostnaam uit te breiden die uitbreidt naar een lijst met IP’s, naar de lijst met hostnamen van leden:
#!/usr/bin/python
def expand_dnsname(dnsname):
from socket import getaddrinfo
from dns import reversename, resolver
namelist = [ ]
# expand hostname into dict of ip addresses
iplist = dict()
for answer in getaddrinfo(dnsname, 80):
ipa = str(answer[4][0])
iplist[ipa] = 0
# run through the list of IP addresses to get hostnames
for ipaddr in sorted(iplist):
rev_name = reversename.from_address(ipaddr)
# run through all the hostnames returned, ignoring the dnsname
for answer in resolver.query(rev_name, "PTR"):
name = str(answer)
if name != dnsname:
# add it to the list of answers
namelist.append(name)
break
# if no other choice, return the dnsname
if len(namelist) == 0:
namelist.append(dnsname)
# return the sorted namelist
namelist = sorted(namelist)
return namelist
namelist = expand_dnsname('google.com.')
for name in namelist:
print name
Wat, als ik het run, een paar 1e100.net-hostnamen opsomt: