I created a very simple script to demonstrate the problem. I have verified that the key works (can use it with nsupdate). I am showing the real key since it's just for testing anyway.
The code:
$ cat dnstest.py
import dns.tsigkeyring
import dns.update
import dns.reversename
import dns.query
import dns.rdatatype
dnsserver = '192.168.40.21'
ipaddress = '192.168.253.55'
keyring = dns.tsigkeyring.from_text({'ddns-test' : 'gwHzfofiiSJeh+cYTl/nUKMi8EzHWmnC+xV0IwG+EKF1LO/BTuZ/byDjscT9hXsxuQjyCpyiWZCYv7PxMI07JQ=='})
update = dns.update.Update('dynamic.domain.com.', keyring=keyring)
update.replace('testname', 300, dns.rdatatype.A, ipaddress)
response = dns.query.udp(update, dnsserver)
print(response)
I cannot use dns.tsigkeyring.from_text as is shown in the Example page. I get the following error:
$ python dnstest.py
Traceback (most recent call last):
File "/home/sstrattn/dnstools/lib/python3.4/base64.py", line 519, in _input_type_check
m = memoryview(s)
TypeError: memoryview: str object does not have the buffer interface
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "dnstest.py", line 9, in <module>
keyring = dns.tsigkeyring.from_text({'ddns-test' : 'gwHzfofiiSJeh+cYTl/nUKMi8EzHWmnC+xV0IwG+EKF1LO/BTuZ/byDjscT9hXsxuQjyCpyiWZCYv7PxMI07JQ=='})
File "/home/sstrattn/dnstools/lib/python3.4/site-packages/dns/tsigkeyring.py", line 31, in from_text
secret = base64.decodestring(textring[keytext])
File "/home/sstrattn/dnstools/lib/python3.4/base64.py", line 561, in decodestring
return decodebytes(s)
File "/home/sstrattn/dnstools/lib/python3.4/base64.py", line 553, in decodebytes
_input_type_check(s)
File "/home/sstrattn/dnstools/lib/python3.4/base64.py", line 522, in _input_type_check
raise TypeError(msg) from err
TypeError: expected bytes-like object, not str
I can get around this error by forcing the key string to be a byte (prepend with 'b'). But then I get an error when trying to do an update.
Change in script:
keyring = dns.tsigkeyring.from_text({'ddns-test' : b'gwHzfofiiSJeh+cYTl/nUKMi8EzHWmnC+xV0IwG+EKF1LO/BTuZ/byDjscT9hXsxuQjyCpyiWZCYv7PxMI07JQ=='})
New error message:
$ python dnstest.py
Traceback (most recent call last):
File "dnstest.py", line 12, in <module>
response = dns.query.udp(update, dnsserver)
File "/home/sstrattn/dnstools/lib/python3.4/site-packages/dns/query.py", line 223, in udp
wire = q.to_wire()
File "/home/sstrattn/dnstools/lib/python3.4/site-packages/dns/update.py", line 249, in to_wire
return super(Update, self).to_wire(origin, max_size)
File "/home/sstrattn/dnstools/lib/python3.4/site-packages/dns/message.py", line 437, in to_wire
self.keyalgorithm)
File "/home/sstrattn/dnstools/lib/python3.4/site-packages/dns/renderer.py", line 292, in add_tsig
algorithm=algorithm)
File "/home/sstrattn/dnstools/lib/python3.4/site-packages/dns/tsig.py", line 121, in sign
post_mac = struct.pack('!HH', error, ol) + other_data
TypeError: can't concat bytes to str
My environment information (using virtualenv):
$ python --version
Python 3.4.3
(dnstools) sstrattn@puppet:~/dnstools$ pip list
dnspython (1.14.0)
pip (8.1.2)
setuptools (21.2.2)
wheel (0.29.0)
A coworker who was also playing with dnspython didn't run into any issues. When I asked him he said he installed dnspython via apt-get, not pip. The version that apt-get has is 1.11.1-1...when I try to install that with pip, I can get 1.11.1 but then I get another error, and I'd rather not get it working on an older version anyway.