libunbound python DNSSEC example - first character in TXT records

nusenu nusenu-lists at riseup.net
Mon Nov 8 22:31:10 UTC 2021


Hi,

I'd like to use the python unbound module to
- resolve TXT records
- inspect the strings in the TXT record
- check if the record validates correctly (DNSSEC).


I took the DNSSEC example from the documentation [1] and stored the DS record
for the root zone in the keys file.

I made some minor changes to the example from the documentation
(make it work with python3, RR_TYPE_A -> RR_TYPE_TXT, ...)
the result is bellow [2].

The ub_data class has explicit support for PTR, A, MX but I didn't see anything
related to TXT records so I used as_raw_data() to look at the strings in TXT records
but then I noticed that the first character is always random and not actually what is in the TXT
record when compared with 'host -t txt ...'

here a few examples:

python3 dnssec.py debian.org
Result is secure
response contains 1 TXT records
Result: [b'Dgoogle-site-verification=loe-ysjvPgopd0fB1ptQlg6Fy0OppGRCHTAKLZ8BdF4']
Result (raw): 44 67 6F 6F 67 6C 65 2D 73 69 74 65 2D 76 65 72 69 66 69 63 61 74 69 6F 6E 3D 6C 6F 65 2D 79 73 6A 76 50 67 6F 70 64 30 66 42 31 70 74 51 6C 67 36 46 79 30 4F 70 70 47 52 43 48 54 41 4B 4C 5A 38 42 64 46 34

python3 dnssec.py nic.cz
Result is secure
response contains 2 TXT records
Result: [b'+MS=92011E91562E6FD18FF9C5FA1F053F90DD5B1892', b'\x83v=spf1 ip4:217.31.192.0/20 ip4:185.43.135.0/24 ip4:81.91.84.116 ip6:2001:1568:b::145 ip6:2001:1568:b:145::1 ip6:2001:1488::/29 ~all']
Result (raw): 2B 4D 53 3D 39 32 30 31 31 45 39 31 35 36 32 45 36 46 44 31 38 46 46 39 43 35 46 41 31 46 30 35 33 46 39 30 44 44 35 42 31 38 39 32;83 76 3D 73 70 66 31 20 69 70 34 3A 32 31 37 2E 33 31 2E 31 39 32 2E 30 2F 32 30 20 69 70 34 3A 31 38 35 2E 34 33 2E 31 33 35 2E 30 2F 32 34 20 69 70 34 3A 38 31 2E 39 31 2E 38 34 2E 31 31 36 20 69 70 36 3A 32 30 30 31 3A 31 35 36 38 3A 62 3A 3A 31 34 35 20 69 70 36 3A 32 30 30 31 3A 31 35 36 38 3A 62 3A 31 34 35 3A 3A 31 20 69 70 36 3A 32 30 30 31 3A 31 34 38 38 3A 3A 2F 32 39 20 7E 61 6C 6C


Is there something special about the first character of a TXT record
that one needs to consider when using as_raw_data() or is this a bug?
I didn't see anything obvious in the RFC:
https://datatracker.ietf.org/doc/html/rfc1035#section-3.3.14

and a second question:
Is there any way I can tell the unbound module to use TCP for queries and use a SOCKS proxy?
similar to this:
https://stackoverflow.com/questions/5148589/python-urllib-over-tor

I'm using python3-unbound from the debian stable package (1.13.1).

kind regards,
nusenu



[1] unbound-1.13.2/doc/html/pyunbound/examples/example1b.html
created via sphinx-build

[2]
import os
import sys
from unbound import ub_ctx,RR_TYPE_TXT,RR_CLASS_IN

domain = sys.argv[1]

ctx = ub_ctx()
ctx.resolvconf("resolv.conf")
if (os.path.isfile("keys")):
     ctx.add_ta_file("keys") #read public keys for DNSSEC verification

status, result = ctx.resolve(domain, RR_TYPE_TXT, RR_CLASS_IN)
if status == 0 and result.havedata:
     if result.secure:
         print("Result is secure")
     elif result.bogus:
         print("Result is bogus")
     else:
         print("Result is insecure")
     print("response contains %s TXT records" % len(result.rawdata))
     print("Result: %s" % str(result.data.as_raw_data()))
     print("Result (raw): %s" % str(result.data))





More information about the Unbound-users mailing list