rthalley / dnspython Goto Github PK
View Code? Open in Web Editor NEWa powerful DNS toolkit for python
Home Page: http://www.dnspython.org
License: Other
a powerful DNS toolkit for python
Home Page: http://www.dnspython.org
License: Other
I was looking for a python DNS library that handled CERT records. Although this is defined as dns.rdtypes.ANY.CERT, it the following code does not work:
import dns.resolve
for rdata in dns.resolver.query('alan.direct.transparenthealth.org', 'CERT')
print rdata.target
I get:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/dist-packages/dns/resolver.py", line 770, in query
raise_on_no_answer)
File "/usr/lib/python2.7/dist-packages/dns/resolver.py", line 709, in query
raise_on_no_answer)
File "/usr/lib/python2.7/dist-packages/dns/resolver.py", line 129, in __init__
raise NoAnswer
dns.resolver.NoAnswer
If I do it using the command line utility, I do indeed get the certificate back.
>dig alan.direct.transparenthealth.org CERT
dig alan.direct.transparenthealth.org CERT +noall +answer
;; Truncated, retrying in TCP mode.
; <<>> DiG 9.8.1-P1 <<>> alan.direct.transparenthealth.org CERT +noall +answer
;; global options: +cmd
alan.direct.transparenthealth.org. 83828 IN CERT PKIX 38725 RSASHA1
MIIDtzCCAyCgAwIBAgIIexSV8b464C8wDQYJKoZIhvcNAQEFBQAwgaEx
MDAuBgkqhkiG9w0BCQEWIXJvb3RAZGlyZWN0LnRyYW5zcGFyZW50aGVh
.
.
.
Is this functionality possible with this library? Am I doing it wrong? I couldn’t find any examples of doing this in Python
Some tests from dnssec.py fail with Python 3. All tests from other files pass with Python 3.
$ cd tests
$ PYTHONPATH=".." python3.2 dnssec.py
..EE...EE
======================================================================
ERROR: testAbsoluteRSABad (__main__.DNSSECValidatorTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "dnssec.py", line 102, in testAbsoluteRSABad
self.assertRaises(dns.dnssec.ValidationFailure, bad)
File "/usr/lib64/python3.2/unittest/case.py", line 557, in assertRaises
callableObj(*args, **kwargs)
File "dnssec.py", line 101, in bad
when)
File "/tmp/dnspython3-1.10.0/dns/dnssec.py", line 356, in _validate
_validate_rrsig(rrset, rrsig, keys, origin, now)
File "/tmp/dnspython3-1.10.0/dns/dnssec.py", line 303, in _validate_rrsig
digest = bytes(0) + bytes(1) + bytes(0xFF) * padlen + bytes(0) + \
TypeError: 'int' object is not callable
======================================================================
ERROR: testAbsoluteRSAGood (__main__.DNSSECValidatorTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "dnssec.py", line 96, in testAbsoluteRSAGood
dns.dnssec.validate(abs_soa, abs_soa_rrsig, abs_keys, None, when)
File "/tmp/dnspython3-1.10.0/dns/dnssec.py", line 356, in _validate
_validate_rrsig(rrset, rrsig, keys, origin, now)
File "/tmp/dnspython3-1.10.0/dns/dnssec.py", line 303, in _validate_rrsig
digest = bytes(0) + bytes(1) + bytes(0xFF) * padlen + bytes(0) + \
TypeError: 'int' object is not callable
======================================================================
ERROR: testRelativeRSABad (__main__.DNSSECValidatorTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "dnssec.py", line 112, in testRelativeRSABad
self.assertRaises(dns.dnssec.ValidationFailure, bad)
File "/usr/lib64/python3.2/unittest/case.py", line 557, in assertRaises
callableObj(*args, **kwargs)
File "dnssec.py", line 111, in bad
abs_dnspython_org, when)
File "/tmp/dnspython3-1.10.0/dns/dnssec.py", line 356, in _validate
_validate_rrsig(rrset, rrsig, keys, origin, now)
File "/tmp/dnspython3-1.10.0/dns/dnssec.py", line 303, in _validate_rrsig
digest = bytes(0) + bytes(1) + bytes(0xFF) * padlen + bytes(0) + \
TypeError: 'int' object is not callable
======================================================================
ERROR: testRelativeRSAGood (__main__.DNSSECValidatorTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "dnssec.py", line 106, in testRelativeRSAGood
abs_dnspython_org, when)
File "/tmp/dnspython3-1.10.0/dns/dnssec.py", line 356, in _validate
_validate_rrsig(rrset, rrsig, keys, origin, now)
File "/tmp/dnspython3-1.10.0/dns/dnssec.py", line 303, in _validate_rrsig
digest = bytes(0) + bytes(1) + bytes(0xFF) * padlen + bytes(0) + \
TypeError: 'int' object is not callable
----------------------------------------------------------------------
Ran 9 tests in 0.014s
FAILED (errors=4)
Tests are currently run via a Makefile
. Each test file is executed separately, which makes the test summary line a bit useless.
Also, it's not easily runnable via nose
or sniffer
.
I have created a fork and will move the tests over to dns/tests
and rename them so nose
will discover them automatically. This should also make it runnable via sniffer
.
At the same time, I am considering skipping tests which are not runnable due to missing pycrypto
for example. This will report an "S" in the status instead of raising an exception. If pycrypto
is available they will be run as expected.
q = dns.query.udp(msg, server, timeout=2)
help( q )
i think i can not found anything about query time?
Hello!
I wonder if you are open to accepting patches which would add human-readable messages to DNSException messsages.
The motivation is that currently dnspython users have to implement own logic which catches exceptions e.g. from resolver.query and translates them to meanigful messages for users. I had to do that myself several time.
I propose to add generic but explanatory text messages like 'YXDOMAIN from 192.0.2.1 when querying for x.y.z.example.' to DNSExceptions so dnspython users could simply do str(e) and be done with it.
Are you okay with the idea?
Hello,
I have trouble with decoding punycoded IDN domain back to Unicode, here is example (python 2.7):
>>> n = dns.name.from_unicode(u'ee tč')
>>> n.to_text()
'xn--ee\\032t-jua.'
>>> print n.to_text()
xn--ee\032t-jua.
>>> n.to_unicode()
---------------------------------------------------------------------------
UnicodeError Traceback (most recent call last)
<ipython-input-66-38cdd9f34ab1> in <module>()
----> 1 n.to_unicode()
/usr/lib/python2.7/site-packages/dns/name.pyc in to_unicode(self, omit_final_dot)
346 else:
347 l = self.labels
--> 348 s = u'.'.join([encodings.idna.ToUnicode(_escapify(x)) for x in l])
349 return s
350
/usr/lib64/python2.7/encodings/idna.pyc in ToUnicode(label)
137 # label2 will already be in lower case.
138 if label.lower() != label2:
--> 139 raise UnicodeError("IDNA does not round-trip", label, label2)
140
141 # Step 8: return the result of step 5
UnicodeError: ('IDNA does not round-trip', 'xn--ee\\032t-jua', 'xn--ee\\032t-u1a')
But when I use standard library, it works:
>>> a = encodings.idna.ToASCII(u'ee tč')
>>> a
'xn--ee t-jua.'
>>> u = encodings.idna.ToUnicode(a)
>>> u
>>> u'ee t\u010d'
>>> print u
ee tč
When I substitute space with \032, it works with encoding module, but it is giving me different punycoded value:
>>> a = encodings.idna.ToASCII(u'ee\\032tč')
>>> a
'xn--ee\\032t-p6a'
>>> u = encodings.idna.ToUnicode(a)
>>> u
u'ee\\032t\u010d'
>>> print u
ee\032tč
Hi,
I'd like to be able to export the results of a Message to JSON format, for integration with other tools, such as client-side Ajax requests for DNS lookups, etc.
I wrote some code that does this, but I think a native solution as part of the framework would be ideal, by adding to_json() methods in rdata types, etc. Has anyone considered working on this?
In Python 2.7 dns.rrset.from_text does not allow a Unicode string as rdata:
In [13]: dns.rrset.from_text("test.com", 123,
dns.rdataclass.IN, dns.rdatatype.PTR,
u"fóó.bar").to_text()
[...]
AttributeError: 'unicode' object has no attribute 'get'
while it does accept an IDNA encoded string:
In [12]: dns.rrset.from_text("test.com", 123,
dns.rdataclass.IN, dns.rdatatype.PTR,
u"fóó.bar".encode("idna")).to_text()
Out[12]: 'test.com 123 IN PTR xn--f-vgaa.bar'
In the Python3 version this behaviour is exactly reversed: An Unicode string is accepted, while a pre-IDNA'd string is not, making it difficult to support both Py2 and 3 in client code.
In [20]: dns.rrset.from_text("test.com", 123,
....: dns.rdataclass.IN, dns.rdatatype.PTR,
....: u"fóó.bar").to_text()
Out[20]: 'test.com 123 IN PTR xn--f-vgaa.bar'
In [21]: dns.rrset.from_text("test.com", 123,
....: dns.rdataclass.IN, dns.rdatatype.PTR,
....: u"fóó.bar".encode("idna")).to_text()
[...]
AttributeError: 'bytes' object has no attribute 'get'
I suspect this is not intended behaviour...
Python 3.2
File "/lib/python3.2/site-packages/dns/name.py", line 171
h = 0L
^
SyntaxError: invalid syntax
should be h = 0
accordingly to http://legacy.python.org/dev/peps/pep-0237/ Transition paragraph C
Hello!
I have found that LOC records have incorrect default values for size, horizontal and vertical precision. Also the explicit value for vertical precision is not parsed correctly if there is no 'm' (unit) at the end of input.
I have patches for both problems so I will create pull request. The third patch adds unit tests for LOC records so you can try it yourself that it really doesn't work with current master :-)
Have a nice day!
Hi,
When I try to import from text a DNS entry with an empty name, it raise the following AttributeError:
File "/usr/lib/python2.7/dist-packages/dns/zone.py", line 924, in from_text
reader.read()
File "/usr/lib/python2.7/dist-packages/dns/zone.py", line 873, in read
self._rr_line()
File "/usr/lib/python2.7/dist-packages/dns/zone.py", line 589, in _rr_line
if not name.is_subdomain(self.zone.origin):
AttributeError: 'NoneType' object has no attribute 'is_subdomain'
You could reproduce it with:
import dns.zone
dns.zone.from_text(' IN NS foo.bar.oni.', origin='foo.bar.oni.', check_origin=False)
self.last_name isn't updated in _MasterReader._rr_line() if token is a whitespace and keep None as value.
I'm not sure if this is really a syntax error, but if this is the case, add
if name is None:
raise dns.exception.SyntaxError
before https://github.com/rthalley/dnspython/blob/master/dns/zone.py#L589 should be enough.
import dns.query, dns.zone
ThisXFERedZone = dns.zone.from_xfr(dns.query.xfr("192.228.79.201", "."))
ThisPrintableZone = ThisXFERedZone.to_text()
yields:
Traceback (most recent call last):
File "./FindRootserverAddresses.py", line 4, in
ThisPrintableZone = ThisXFERedZone.to_text()
File "/usr/local/lib/python3.4/site-packages/dns/zone.py", line 511, in to_text
self.to_file(temp_buffer, sorted, relativize, nl)
File "/usr/local/lib/python3.4/site-packages/dns/zone.py", line 487, in to_file
print(l, file=f)
TypeError: 'str' does not support the buffer interface
Here's a DNS hijacking exploit with dnspython.
The host name of this host is "sitetruth.com", running CentOS 6, 64 bit, Python 2.7 and dnspython 1.9.4.
Here, we look up "noexample.com", which is a nonexistent domain.
>>> import dns
>>> resolv = dns.resolver.Resolver()
>>> resolv.domain
<DNS name com.>
>>> resolv.query("noexample.com")
<dns.resolver.Answer object at 0x2984b90>
>>> result = resolv.query("noexample.com")
>>> result
<dns.resolver.Answer object at 0x2984e10>
>>> result[0]
<DNS IN A rdata: 64.30.224.112>
64.30.224.112 is "search.com", an ad-heavy search site. We've had a DNS hijacking.
Compare what the Linux "host" command returns:
> host noexample.com
Host noexample.com not found: 3(NXDOMAIN)
So "host" gets it right, and dnspython gets hijacked. So this isn't a problem out in DNS; it's local. Really. This is not a problem with a bad DNS server. It's a client side problem.
Here's what's going on. Notice "resolv.domain" above, with a value "com". The host name is "sitetruth.com", so the "domain" of the host is "com". If the initial lookup fails, the "domain" is appended to the query and the query is retried. So the second lookup is "noexample.com.com", and the query has thus been hijacked to "com.com".
The proprietors of "com.com" have their DNS server set up to accept all queries for any unknown subdomain under "com.com" and divert it to the IP address of "search.com", a fake search engine which returns mostly ads.
The bug is that there should never be a second search with the "domain" appended when "domain" is a top-level domain. If "domain" doesn't have at least 2 components, it should not be used.
Most hosts have longer primary names such as "gator123.hostgator.com"; web sites they host are aliased. They don't hit this problem. But hosts where the host name is a primary domain name in ".com" are vulnerable.
It's possible to work around this bug by assigning
resolv2.domain = dns.name.from_text("")
This prevents such hijacking.
The same bug exists in glibc's "getaddrinfo". See that report for more detail, and how this interacts with the relevant RFC.
Ref: "http://sourceware.org/bugzilla/show_bug.cgi?id=13935"
Multimessage AXFR via dns.query.xfr using TSIG with algorithm DIFFERENT from hmac-md5 always gives BadSignature.
dnspython3-1.11.0:
File "/usr/local/lib/python3.3/dist-packages/dns/query.py", line 438, in xfr
one_rr_per_rrset=(rdtype==dns.rdatatype.IXFR))
File "/usr/local/lib/python3.3/dist-packages/dns/message.py", line 787, in from_wire
reader.read()
File "/usr/local/lib/python3.3/dist-packages/dns/message.py", line 728, in read
self._get_section(self.message.additional, adcount)
File "/usr/local/lib/python3.3/dist-packages/dns/message.py", line 680, in _get_section
self.message.first)
File "/usr/local/lib/python3.3/dist-packages/dns/tsig.py", line 178, in validate
raise BadSignature
Steps to reproduce:
This works fine if I run it directly on my laptop (running Ubuntu 13.04). It fails (raises dns.resolver.NoAnswer) if I run it inside a VirtualBox VM (running Ubuntu 12.04).
I've captured network traffic when dns.resolver is doing its job, and I see this in Wireshark:
14 2.416588 10.0.2.15 10.0.2.3 DNS 66 Standard query 0x33bb MX pov.lt
15 2.419498 10.0.2.3 10.0.2.15 DNS 82 Standard query response 0x33bb A 213.133.64.220
I'm not a networking expert, but it seems to me there was an answer, and the correct one in fact (213.133.64.220 is the primary MX for pov.lt).
If I change the query type to 'A' instead of 'MX', DNS resolution succeeds.
I am not sure whether it is a bug in dnspython or just some other strange issue, but maybe you could comment on it either here or there:
nsupdate-info/nsupdate.info#138
and btw: thanks a lot for dnspython, we find it really useful for our https://nsupdate.info/ software/service.
it raises here:
dns/resolver.py in query
#
# We got a response, but we're not happy with the
# rcode in it. Remove the server from the mix if
# the rcode isn't SERVFAIL.
#
if rcode != dns.rcode.SERVFAIL or not retry_servfail:
I'm using Django, Celery, Eventlet and dnspython to asynchronous parse about 500 rss feeds.
Using dnspython causes 'lookup timed out' error when I try to parse more than 20 feeds at the same time. When I uninstall dnspython all works great, but I lose some time because dns lookups are blocking celery pool. Do you have any ideas how can it be fixed?
this is my celery task code:
import eventlet
feedparser = eventlet.import_patched('feedparser')
from celery import group
@task(ignore_result=True)
def update_feeds():
group(update_feed.s(feed) for feed in Feed.objects.filter(active=True)).apply_async()
@task(ignore_result=True)
def update_feed(feed):
parsed_feed = feedparser.parse(feed.feed_url, etag=feed.etag, modified=feed.modified)
# It fails when I have dnspython installed returning <urlopen error (-3, 'Lookup timed out')> error
I'm using Ubuntu 12.04 LTS
python-dns 1.11.1
Hit this once but not always reproducible. Unfortunately don't have data what domain was actually queried.
Exception in thread Thread-5:
Traceback (most recent call last):
File "/usr/share/python3.3/threading.py", line 901, in _bootstrap_inner
self.run()
File "/usr/share/python3.3/threading.py", line 858, in run
self._target(_self._args, *_self._kwargs)
File "report_unused_domains.py", line 241, in _tFilterByDns
new_domain_list, not_used_domain_list, nxdomains, nonameservers, noanswer = self.filterByDns([domain_data])
File "report_unused_domains.py", line 342, in filterByDns
resolver_answer = dns.resolver.query(domain_data['domain_name'], 'NS')
File "/usr/share/python3.3/site-packages/dns/resolver.py", line 972, in query
raise_on_no_answer, source_port)
File "/usr/share/python3.3/site-packages/dns/resolver.py", line 827, in query
source_port=source_port)
File "/usr/share/python3.3/site-packages/dns/query.py", line 230, in udp
one_rr_per_rrset=one_rr_per_rrset)
File "/usr/share/python3.3/site-packages/dns/message.py", line 787, in from_wire
reader.read()
File "/usr/share/python3.3/site-packages/dns/message.py", line 726, in read
self._get_section(self.message.answer, ancount)
File "/usr/share/python3.3/site-packages/dns/message.py", line 708, in _get_section
rrset.add(rd, ttl)
File "/usr/share/python3.3/site-packages/dns/rdataset.py", line 124, in add
super(Rdataset, self).add(rd)
File "/usr/share/python3.3/site-packages/dns/set.py", line 46, in add
if not item in self.items:
File "/usr/share/python3.3/site-packages/dns/rdata.py", line 218, in eq
return self._cmp(other) == 0
File "/usr/share/python3.3/site-packages/dns/rdtypes/nsbase.py", line 68, in _cmp
return dns.util.cmp(self.target, other.target)
AttributeError: 'GenericRdata' object has no attribute 'target'
BIND9 test suite contains a script for generating zone files. Zones from this script are valid (BIND is able to load and serve them correctly), but zone parser in python-dns blows up on some zones.
Steps to Reproduce:
$ genzone.sh 2 3 4 > master2.db
import dns.zone
dns.zone.from_file('master2.db', origin='master2.')
Actual results:
Traceback (most recent call last):
File "test.py", line 2, in <module>
dns.zone.from_file('master2.db', origin='master2.')
File "/usr/lib/python2.7/site-packages/dns/zone.py", line 814, in from_file
filename, allow_include, check_origin)
File "/usr/lib/python2.7/site-packages/dns/zone.py", line 761, in from_text
reader.read()
File "/usr/lib/python2.7/site-packages/dns/zone.py", line 715, in read
raise dns.exception.SyntaxError("%s:%d: %s" % (filename, line_number, detail))
dns.exception.SyntaxError: master2.db:41: generic rdata does not start with \#
Additional info:
line 41 from generated zone:
mb02 MG .
Also, I hit exactly same problem with KEY records. Attached zone was generated by BIND scripts in bind-9.9.2-P1/bin/tests/system/tsiggss/ns1.
Hi,
it seems that dnspython can't process an empty APL record. Although this isn't a big problem, in fact, this case is useful for testing because APL is the only record I know which allows empty rdata (RFC 3123 sec. 5: "The data consists of zero or more strings...").
dnspython3-1.11.1
I have next request identical to dig @8.8.8.8 -t ANY google.com
:
import dns.flags
import dns.name
import dns.message
import dns.rdatatype
import dns.query
TIMEOUT = 2
ADDITIONAL_RDCLASS = 4096
domain = 'google.com.'
name_server = '8.8.8.8'
record_type = dns.rdatatype.ANY
request = dns.message.make_query(domain, record_type)
request.flags |= dns.flags.AD
request.find_rrset(request.additional, dns.name.root, ADDITIONAL_RDCLASS,
dns.rdatatype.OPT, create=True, force_unique=True)
response = dns.query.udp(request, name_server, timeout=TIMEOUT)
For me this request return malformed packet and throw socket.error
:
File "/home/tbicr/Projects/cspw-ui.env/local/lib/python2.7/site-packages/dns/query.py", line 218, in udp
(wire, from_address) = s.recvfrom(65535)
None: [Errno 11] Resource temporarily unavailable
Dig handle this behaviour and send packet again, that take about 5 seconds, but take result with two requests:
first request:
0000 c8 be 19 aa 83 58 50 46 5d a5 70 99 08 00 45 00 .....XPF ].p...E.
0010 00 43 ff 18 00 00 40 11 a9 fc c0 a8 00 dd 08 08 .C....@. ........
0020 08 08 a8 4b 00 35 00 2f eb c8 5b c9 01 20 00 01 ...K.5./ ..[.. ..
0030 00 00 00 00 00 01 06 67 6f 6f 67 6c 65 03 63 6f .......g oogle.co
0040 6d 00 00 ff 00 01 00 00 29 10 00 00 00 00 00 00 m....... ).......
0050 00 .
first response:
0000 50 46 5d a5 70 99 c8 be 19 aa 83 58 08 00 45 00 PF].p... ...X..E.
0010 02 8b d1 d8 00 00 30 11 e4 f4 08 08 08 08 c0 a8 ......0. ........
0020 00 dd 00 35 a8 4b 02 77 9d 64 5b c9 81 80 00 01 ...5.K.w .d[.....
0030 00 19 00 00 00 01 06 67 6f 6f 67 6c 65 03 63 6f .......g oogle.co
0040 6d 00 00 ff 00 01 c0 0c 00 01 00 01 00 00 00 83 m....... ........
0050 00 04 ad c2 70 41 c0 0c 00 01 00 01 00 00 00 83 ....pA.. ........
0060 00 04 ad c2 70 44 c0 0c 00 01 00 01 00 00 00 83 ....pD.. ........
0070 00 04 ad c2 70 4e c0 0c 00 01 00 01 00 00 00 83 ....pN.. ........
0080 00 04 ad c2 70 48 c0 0c 00 01 00 01 00 00 00 83 ....pH.. ........
0090 00 04 ad c2 70 43 c0 0c 00 01 00 01 00 00 00 83 ....pC.. ........
00a0 00 04 ad c2 70 40 c0 0c 00 01 00 01 00 00 00 83 ....p@.. ........
00b0 00 04 ad c2 70 46 c0 0c 00 01 00 01 00 00 00 83 ....pF.. ........
00c0 00 c0 a8 00 01 47 c0 0c 00 01 00 01 00 00 00 83 .....G.. ........
00d0 00 04 ad c2 70 45 c0 0c 00 01 00 01 00 00 00 83 ....pE.. ........
00e0 00 04 ad c2 70 49 c0 0c 00 01 00 01 00 00 00 83 ....pI.. ........
00f0 00 04 ad c2 70 42 c0 0c 00 1c 00 01 00 00 00 83 ....pB.. ........
0100 00 10 2a 00 14 50 40 01 08 02 00 00 00 00 00 00 ..*..P@. ........
0110 10 08 c0 0c 00 0f 00 01 00 00 01 af 00 11 00 1e ........ ........
0120 04 61 6c 74 32 05 61 73 70 6d 78 01 6c c0 0c c0 .alt2.as pmx.l...
0130 0c 00 0f 00 01 00 00 01 af 00 04 00 0a c0 fb c0 ........ ........
0140 0c 01 01 00 01 00 00 53 b7 00 13 00 05 69 73 73 .......S .....iss
0150 75 65 73 79 6d 61 6e 74 65 63 2e 63 6f 6d c0 0c uesymant ec.com..
0160 00 0f 00 01 00 00 01 af 00 09 00 14 04 61 6c 74 ........ .....alt
0170 31 c0 fb c0 0c 00 06 00 01 00 00 53 b7 00 26 03 1....... ...S..&.
0180 6e 73 31 c0 0c 09 64 6e 73 2d 61 64 6d 69 6e c0 ns1...dn s-admin.
0190 0c 77 fd 35 14 00 00 1c 20 00 00 07 08 00 12 75 .w.5.... ......u
01a0 00 00 00 01 2c c0 0c 00 02 00 01 00 00 53 b7 00 ....,... .....S..
01b0 06 03 6e 73 32 c0 0c c0 0c 00 0f 00 01 00 00 01 ..ns2... ........
01c0 af 00 09 00 32 04 61 6c 74 34 c0 fb c0 0c 00 10 ....2.al t4......
01d0 00 01 00 00 0d 67 00 4c 4b 76 3d 73 70 66 31 20 .....g.L Kv=spf1
01e0 69 6e 63 6c 75 64 65 3a 5f 73 70 66 2e 67 6f 6f include: _spf.goo
01f0 67 6c 65 2e 63 6f 6d 20 69 70 34 3a 32 31 36 2e gle.com ip4:216.
0200 37 33 2e 39 33 2e 37 30 2f 33 31 20 69 70 34 3a 73.93.70 /31 ip4:
0210 32 31 36 2e 37 33 2e 39 33 2e 37 32 2f 33 31 20 216.73.9 3.72/31
0220 7e 61 6c 6c c0 0c 00 02 00 01 00 00 53 b7 00 06 ~all.... ....S...
0230 03 6e 73 33 c0 0c c0 0c 00 0f 00 01 00 00 01 af .ns3.... ........
0240 00 09 00 28 04 61 6c 74 33 c0 fb c0 0c 00 02 00 ...(.alt 3.......
0250 01 00 00 53 b7 00 02 c1 55 c0 0c 01 01 00 01 00 ...S.... U.......
0260 00 53 b7 00 17 00 09 69 73 73 75 65 77 69 6c 64 .S.....i ssuewild
0270 73 79 6d 61 6e 74 65 63 2e 63 6f 6d c0 0c 00 02 symantec .com....
0280 00 01 00 00 53 b7 00 06 03 6e 73 34 c0 0c 00 00 ....S... .ns4....
0290 29 02 00 00 00 00 00 00 00 )....... .
second request:
0000 c8 be 19 aa 83 58 50 46 5d a5 70 99 08 00 45 00 .....XPF ].p...E.
0010 00 43 ff 19 00 00 40 11 a9 fb c0 a8 00 dd 08 08 .C....@. ........
0020 08 08 a8 4b 00 35 00 2f eb c8 5b c9 01 20 00 01 ...K.5./ ..[.. ..
0030 00 00 00 00 00 01 06 67 6f 6f 67 6c 65 03 63 6f .......g oogle.co
0040 6d 00 00 ff 00 01 00 00 29 10 00 00 00 00 00 00 m....... ).......
0050 00 .
second response:
0000 50 46 5d a5 70 99 c8 be 19 aa 83 58 08 00 45 00 PF].p... ...X..E.
0010 02 8b e7 39 00 00 31 11 ce 93 08 08 08 08 c0 a8 ...9..1. ........
0020 00 dd 00 35 a8 4b 02 77 c0 be 5b c9 81 80 00 01 ...5.K.w ..[.....
0030 00 19 00 00 00 01 06 67 6f 6f 67 6c 65 03 63 6f .......g oogle.co
0040 6d 00 00 ff 00 01 c0 0c 00 01 00 01 00 00 00 7e m....... .......~
0050 00 04 ad c2 70 41 c0 0c 00 01 00 01 00 00 00 7e ....pA.. .......~
0060 00 04 ad c2 70 44 c0 0c 00 01 00 01 00 00 00 7e ....pD.. .......~
0070 00 04 ad c2 70 4e c0 0c 00 01 00 01 00 00 00 7e ....pN.. .......~
0080 00 04 ad c2 70 48 c0 0c 00 01 00 01 00 00 00 7e ....pH.. .......~
0090 00 04 ad c2 70 43 c0 0c 00 01 00 01 00 00 00 7e ....pC.. .......~
00a0 00 04 ad c2 70 40 c0 0c 00 01 00 01 00 00 00 7e ....p@.. .......~
00b0 00 04 ad c2 70 46 c0 0c 00 01 00 01 00 00 00 7e ....pF.. .......~
00c0 00 04 ad c2 70 47 c0 0c 00 01 00 01 00 00 00 7e ....pG.. .......~
00d0 00 04 ad c2 70 45 c0 0c 00 01 00 01 00 00 00 7e ....pE.. .......~
00e0 00 04 ad c2 70 49 c0 0c 00 01 00 01 00 00 00 7e ....pI.. .......~
00f0 00 04 ad c2 70 42 c0 0c 00 1c 00 01 00 00 00 7e ....pB.. .......~
0100 00 10 2a 00 14 50 40 01 08 02 00 00 00 00 00 00 ..*..P@. ........
0110 10 08 c0 0c 00 0f 00 01 00 00 01 aa 00 11 00 1e ........ ........
0120 04 61 6c 74 32 05 61 73 70 6d 78 01 6c c0 0c c0 .alt2.as pmx.l...
0130 0c 00 0f 00 01 00 00 01 aa 00 04 00 0a c0 fb c0 ........ ........
0140 0c 01 01 00 01 00 00 53 b2 00 13 00 05 69 73 73 .......S .....iss
0150 75 65 73 79 6d 61 6e 74 65 63 2e 63 6f 6d c0 0c uesymant ec.com..
0160 00 0f 00 01 00 00 01 aa 00 09 00 14 04 61 6c 74 ........ .....alt
0170 31 c0 fb c0 0c 00 06 00 01 00 00 53 b2 00 26 03 1....... ...S..&.
0180 6e 73 31 c0 0c 09 64 6e 73 2d 61 64 6d 69 6e c0 ns1...dn s-admin.
0190 0c 77 fd 35 14 00 00 1c 20 00 00 07 08 00 12 75 .w.5.... ......u
01a0 00 00 00 01 2c c0 0c 00 02 00 01 00 00 53 b2 00 ....,... .....S..
01b0 06 03 6e 73 32 c0 0c c0 0c 00 0f 00 01 00 00 01 ..ns2... ........
01c0 aa 00 09 00 32 04 61 6c 74 34 c0 fb c0 0c 00 10 ....2.al t4......
01d0 00 01 00 00 0d 62 00 4c 4b 76 3d 73 70 66 31 20 .....b.L Kv=spf1
01e0 69 6e 63 6c 75 64 65 3a 5f 73 70 66 2e 67 6f 6f include: _spf.goo
01f0 67 6c 65 2e 63 6f 6d 20 69 70 34 3a 32 31 36 2e gle.com ip4:216.
0200 37 33 2e 39 33 2e 37 30 2f 33 31 20 69 70 34 3a 73.93.70 /31 ip4:
0210 32 31 36 2e 37 33 2e 39 33 2e 37 32 2f 33 31 20 216.73.9 3.72/31
0220 7e 61 6c 6c c0 0c 00 02 00 01 00 00 53 b2 00 06 ~all.... ....S...
0230 03 6e 73 33 c0 0c c0 0c 00 0f 00 01 00 00 01 aa .ns3.... ........
0240 00 09 00 28 04 61 6c 74 33 c0 fb c0 0c 00 02 00 ...(.alt 3.......
0250 01 00 00 53 b2 00 02 c1 55 c0 0c 01 01 00 01 00 ...S.... U.......
0260 00 53 b2 00 17 00 09 69 73 73 75 65 77 69 6c 64 .S.....i ssuewild
0270 73 79 6d 61 6e 74 65 63 2e 63 6f 6d c0 0c 00 02 symantec .com....
0280 00 01 00 00 53 b2 00 06 03 6e 73 34 c0 0c 00 00 ....S... .ns4....
0290 29 02 00 00 00 00 00 00 00 )....... .
So is dnspython support malformed packet processing like dig?
In dns/edns.py, EDNS is often written ENDS.
Patch in https://gist.github.com/2758613 (cannot attach patch in the bug tracker)
On windows the 'string` attribute does not exists.
I created a workaround for that:
for txt in dns.resolver.query(domain, 'TXT'):
if hasattr(txt, 'strings'):
strings = txt.strings
else:
strings = [txt.data[1:]]
It looks like it's impossible to install dnspython 1.10.0 from PyPI, probably since 1.11.0 went out:
$ pip install dnspython==1.10.0
Downloading/unpacking dnspython==1.10.0
Could not find a version that satisfies the requirement dnspython==1.10.0 (from versions: 1.11.0)
Cleaning up...
No distributions matching the version for dnspython==1.10.0
The index page doesn't list older versions, although the release page for 1.10.0 is visible on PyPI.
Is there an option or something that was unchecked?
python -c 'import dns.resolver; dns.resolver.query("_domainkey.collabfinder.com", "TXT")'
This hangs because nameservers aren't removed from the list for SERVFAIL: https://github.com/rthalley/dnspython/blob/master/dns/resolver.py#L839
The comment is not very helpful in explaining why.
I've just tested the Python3 branch, which seems to be working. Is it ready to be merged into master for the next release ? OpenStack could really use a Python3 compatible version of dnspython :)
In version 1.11.1
a\.10.10.in-addr.arpa. 28800 IN CNAME ca\.
is no longer imported from master file by zone.from_file (this record is skipped)
In version 1.7.1 all works fine
See the bottom of the stack trace below. This happens under load, when multiple threads are invoking query()
return dns_resolver.query(hostname, record_type)
File "build/bdist.linux-x86_64/egg/dns/resolver.py", line 591, in query
answer = self.cache.get((qname, rdtype, rdclass))
File "build/bdist.linux-x86_64/egg/dns/resolver.py", line 208, in get
self.maybe_clean()
File "build/bdist.linux-x86_64/egg/dns/resolver.py", line 195, in maybe_clean
del self.data[k]
KeyError: (, 15, 1)
Hi,
If I try to list multi-message IXFR response (dns.query.xfr output), I always get timeout exception no matter which dns server I query. One message responses are processed without problems.
for msg in response:
File "/usr/local/lib/python3.3/dist-packages/dns/query.py", line 432, in xfr
ldata = _net_read(s, 2, mexpiration)
File "/usr/local/lib/python3.3/dist-packages/dns/query.py", line 243, in _net_read
_wait_for_readable(sock, expiration)
File "/usr/local/lib/python3.3/dist-packages/dns/query.py", line 140, in _wait_for_readable
_wait_for(s, True, False, True, expiration)
File "/usr/local/lib/python3.3/dist-packages/dns/query.py", line 117, in _wait_for
raise dns.exception.Timeout
dnspython3 (1.11.1)
Dan
If one uses python 2.7 and gives a unicode ipaddr to these methods, they crash.
It is because of some wrong isinstance(x, str) [not: isinstance(x, (str, unicode))] that just checks for str.
Maybe you want to check these isinstance(str) in general, that bug might be at multiple places.
Even though it is marketed as such, it is not working properly on Python 3. I get:
AttributeError: 'dict' object has no attribute 'iteritems'
I will address Python 2/3 compatibility in my fork. I will aim for Python 2.7 an Python 3.3.
See this gist for reproducing the problem: https://gist.github.com/hkraal/345e488f6b555efcb4bb
Perhaps I'm doing something very stupidly wrong here but I don't see it. The fact that an answer is being returned (seen with tcpdump) but an Timeout occurs makes be believe I'm hitting a bug of some sort?
IP addresses with leading zeros are not accepted in /etc/resolv.conf.
Content of /etc/resolv.conf:
nameserver 127.0.0.01
This doesn't work with python-dns from master branch (commit 0b2b985):
>>> import dns.resolver
>>> dns.resolver.query('test.')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "dns/resolver.py", line 974, in query
raise_on_no_answer, source_port)
File "dns/resolver.py", line 830, in query
source_port=source_port)
File "dns/query.py", line 219, in udp
if _addresses_equal(af, from_address, destination) or \
File "dns/query.py", line 150, in _addresses_equal
n2 = dns.inet.inet_pton(af, a2[0])
File "dns/inet.py", line 50, in inet_pton
return dns.ipv4.inet_aton(text)
File "dns/ipv4.py", line 43, in inet_aton
raise dns.exception.SyntaxError
dns.exception.SyntaxError
I think that we could use standard inet_aton and inet_ntoa methods from Python for this. I will send a pull request.
File "/lib/python3.2/site-packages/dns/zone.py", line 874
except dns.exception.SyntaxError, detail:
^
SyntaxError: invalid syntax
shouldn't be?
except dns.exception.SyntaxError as detail:
Currently dnspython is hosted off of PyPi, this presents security and performance challenges. If you could upload the releases to PyPi and then follow the instructions at pypi-externals.caremad.io/help/what/ it'd be great!
I discovered that a SyntaxError
exception is being raised when asking a authoritative nameserver for an A record when there is only an CNAME record available for this very subdomain.
Working example:
See dig ghs.google.com SOA @ns1.google.com
for simple copy'n'paste verification
import dns.resolver
query = dns.message.make_query("ghs.google.com", dns.rdatatype.A)
answers = dns.query.udp(query,"ns1.google.com", timeout=2).answer
I guess a meaningful dnspython exception would be more fitting. Maybe the resulting CNAME information could be included within the exception as well, so programmers wouldn't need to perform two new lookups again to get the CNAME record of the subdomain again. A proper workflow could be like this:
try:
query = dns.message.make_query("ghs.google.com", dns.rdatatype.A)
answers = dns.query.udp(query,"ns1.google.com", timeout=2).answer
except SomeCnameException as e: # we already received the CNAME data, right?
query = dns.message.make_query(e.returned_rdatatype.cname_value, dns.rdatatype.A)
answers = dns.query.udp(query,"ns1.google.com", timeout=2).answer
Hmm, maybe catch this exception and raise something more meaningful?
Traceback (most recent call last):
[...]
update_ns(fqdn, 'A', '0.0.0.0', action='add')
File "/srv/nsupdate.info/repo/nsupdate/main/dnstools.py", line 304, in update_ns
response = dns.query.tcp(upd, nameserver, timeout=UPDATE_TIMEOUT)
File "/srv/nsupdate.info/env/local/lib/python2.7/site-packages/dns/query.py", line 317, in tcp
ldata = _net_read(s, 2, expiration)
File "/srv/nsupdate.info/env/local/lib/python2.7/site-packages/dns/query.py", line 246, in _net_read
raise EOFError
EOFError
There are missing methods copy and deepcopy in Name class, python is unable to create copy without them in this case.
When querying the TXT record of a domain that has no the following exception occours:
Traceback (most recent call last):
File ".\client\patch.py", line 838, in _update
File ".\lib.bin\dns\resolver.py", line 974, in query
File ".\lib.bin\dns\resolver.py", line 905, in query
File ".\lib.bin\dns\resolver.py", line 137, in __init__
AttributeError: 'GenericRdata' object has no attribute 'target'
On Linux (Ubuntu) I don't see such an error, I don't know if it exists on Mac but it defInitely exists on Windows. Testet with the current stable and master.
Imagine DNS zone with following record:
toolong.example.com. 324 IN DNAME xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
Following Python snippet throws NoNameservers exception. I would expect something like YXDOMAIN exception or something similar.
import dns.resolver
resolver = dns.resolver.Resolver(configure=False)
resolver.nameservers = ["127.0.0.1"]
resolver.edns = 0
resolver.payload = 4096
resolver.query('hell.toolong.example.com','txt')
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python2.7/site-packages/dns/resolver.py", line 772, in query
raise NoNameservers
Relevant output from dig:
; <<>> DiG 9.9.2-P1-RedHat-9.9.2-3.P1.fc17 <<>> @127.0.0.1 -t TXT hell.toolong.example.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: YXDOMAIN, id: 43662
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;hell.toolong.example.com. IN TXT
;; ANSWER SECTION:
toolong.example.com. 324 IN DNAME xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Thu Feb 21 14:14:12 2013
;; MSG SIZE rcvd: 316
This may be incorrect to begin with, but it's in our zone files and bind appears to handle it.
When you enter a TXT record with as content a b c
, bind will return it to the end client as "a b c"
while dnspython returns it as `"a" "b" "c"``. Or in code:
zone_content = '''$ORIGIN example.com.
@ IN SOA ns.example.com. username.example.com. ( 2007120710 1d 2h 4w 1h )
@ NS ns1.example.com.
@ TXT b c d'''
zone = dns.zone.from_text(zone_content)
zone.get_rdataset('@', 'TXT').to_text()
Returns a string `0 IN TXT "b" "c" "d"``.
This is with dnspython 1.11.1.
Could someone push the tags into the guthub repository as well?
It makes it easier to see which patches are post 1.11.1 release.
Thanks!
ttl is the _MasterReader 's attribute.
but how can I get it.
dns.resolver
in dnspython3 tries to import _winreg
under Windows, but it has been renamed to winreg
in Python 3.
zone.example file:
@ IN SOA dns.example.com. admin.example.com. (
2010042671 ; serial
3600 ; refresh
1200 ; retry
86400 ; expire
360 ; minimum
)
@ NS dns
test A 127.0.0.1
test.py
#!/usr/bin/python
import dns.zone, dns.name, dns.rdtypes
z = dns.zone.from_file('zone.example','example.com')
name = dns.name.from_text('test.example.com')
a = dns.rdtypes.IN.A.A(dns.rdataclass.IN, dns.rdatatype.A, '127.0.0.2')
z.replace_rdataset(name, a)
z.to_file('zone.output')
output:
Traceback (most recent call last):
File "./test.py", line 9, in
z.to_file('zone.output')
File "/usr/lib64/python2.7/site-packages/dns/zone.py", line 496, in to_file
relativize=relativize)
File "/usr/lib64/python2.7/site-packages/dns/node.py", line 52, in to_text
print >> s, rds.to_text(name, **kw)
TypeError: to_text() got multiple values for keyword argument 'origin'
Hi,
I have discovered that some special APL records (having prefix with trailing zeroes) are in a bad wireformat. RFC 3123 says: "sender MUST NOT include trailing zero octets in the AFDPART regardless of the value of PREFIX".
dnspython3-1.11.0
cls = dns.rdataclass.IN
tpe = dns.rdatatype.from_text("APL")
in4 = "!1:127.0.0.0/1"
rd4 = dns.rdata.from_text(cls, tpe, in4)
out4 = rd4.to_digestable(dns.name.from_text("test"))
print(binascii.hexlify(out4).decode('ascii'))
in6 = "!2:::1000/1"
rd6 = dns.rdata.from_text(cls, tpe, in6)
out6 = rd6.to_digestable(dns.name.from_text("test"))
print(binascii.hexlify(out6).decode('ascii'))
000101847f000000
should be:
000101817f
0002019000000000000000000000000000001000
should be:
0002018f000000000000000000000000000010
Regards,
Dan
Let's try this in python3
>>> import dns
>>> import dns.name
>>> parent = 'afnic.fr'
>>> child = 'www.afnic.fr'
>>> p = dns.name.from_text(parent)
>>> c = dns.name.from_text(child)
>>> c.is_subdomain(p)
True
>>> c.relativize(p)
<DNS name www>
>>> answers = dns.resolver.query(parent, 'NS')
(-- no problem here --)
>>> answers = dns.resolver.query(child, 'NS')
Traceback (most recent call last):
File "dns/resolver.py", line 126, in __init__
rdclass, rdtype)
File "dns/message.py", line 340, in find_rrset
raise KeyError
KeyError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "dns/resolver.py", line 136, in __init__
dns.rdatatype.CNAME)
File "dns/message.py", line 340, in find_rrset
raise KeyError
KeyError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "dns/resolver.py", line 979, in query
raise_on_no_answer, source_port)
File "dns/resolver.py", line 910, in query
raise_on_no_answer)
File "dns/resolver.py", line 145, in __init__
raise NoAnswer
SPF records can be defined either in txt or spf record type.
But dnspython only tries to get a spf type, but it didnt read spf records from txt type.
For example i want to get spf record.
resolver.query('mailroute.net', 'SPF')
and i get no answer because at this domain spf are stored in txt:
http://mxtoolbox.com/SuperTool.aspx?action=spf%3amailroute.net&run=toolpage
And i was expected to get spf record with this query..
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.