Does djbdns / tinydns support long TXT records
Does djbdns/tinydns support large TXT
records, for example when serving long DKIM keys?
I'm aware of RFC 4408 section 3.1.3 and RFC 1035 section 3.3.14:
https://www.rfc-editor.org/rfc/rfc4408#section-3.1.3
https://www.rfc-editor.org/rfc/rfc1035#section-3.3.14
Which both suggest that a TXT
record can be split into multiple character strings to permit long (>255 characters) records to be served.
I also bumped into this question during my research:
https://serverfault.com/questions/255580/how-do-i-enter-a-strong-long-dkim-key-into-dns
I've attempted both approaches mentioned in the accepted answer, with and without surrounding parenthesis.
But djbdns refuses to to serve these records correctly. For example, when querying my domainkey record using nslookup
I get:
mail03._domainkey.zygonia.net text =
""v=DKIM1; k=rsa; p=" "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7UNgSlnndT9JY0soSjxLhFFnvAeVN8b6Y3oKctAunNltMjvXfTD37doER8a9xwEOIXkGPgxJ5UPb/KndvHiIo+j8AScoIZCW"
"glFWp4AUoKlQkKP7o7vwFnWypU+DmcJAtyuhZ9X5yzag37cVR"
"YD4icd02yAETLbIpv1mnMUFkTnkdmtSa5gL2cLUueUOValoENwkWTcZR" "+kraTEU/VDPI"
"RgNBu6OJmQdk0sv4qdkwVVvxvquT4C/SimQDoDaQwlFCp2sBryXyaNSRCaAhRxPaKUpKsPmubW0SJF2nQZ3DprJQcaRQLd9Qgxz+V+XaseaXXWPy+6"
"tB6BlPFk5FwIDAQAB""
*** Error: record size incorrect (515 != 419)
*** ns0.example.net can't find mail03._domainkey.zygonia.net: Unspecified error
This is with a DKIM TXT
record that looks like:
"v=DKIM1; k=rsa; p=" "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7UNgSlnndT9JY0soSjxLhFFnvAeVN8b6Y3oKctAunNltMjvXfTD37doER8a9xwEOIXkGPgxJ5UPb/KndvHiIo+j8AScoIZCW1glFWp4AUoKlQkKP7o7vwFnWypU+DmcJAtyuhZ9X5yzag37cVRGYD4icd02yAETLbIpv1mnMUFkTnkdmtSa5gL2cLUueUOValoENwkWTcZR" "+kraTEU/VDPIrRgNBu6OJmQdk0sv4qdkwVVvxvquT4C/SimQDoDaQwlFCp2sBryXyaNSRCaAhRxPaKUpKsPmubW0SJF2nQZ3DprJQcaRQLd9Qgxz+V+XaseaXXWPy+6rtB6BlPFk5FwIDAQAB"
The raw djbdns data record looks like:
:mail03._domainkey.zygonia.net:16:\642"v=DKIM1;\040k=rsa;\040p="\040"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7UNgSlnndT9JY0soSjxLhFFnvAeVN8b6Y3oKctAunNltMjvXfTD37doER8a9xwEOIXkGPgxJ5UPb\057KndvHiIo+j8AScoIZCW1glFWp4AUoKlQkKP7o7vwFnWypU+DmcJAtyuhZ9X5yzag37cVRGYD4icd02yAETLbIpv1mnMUFkTnkdmtSa5gL2cLUueUOValoENwkWTcZR"\040"+kraTEU\057VDPIrRgNBu6OJmQdk0sv4qdkwVVvxvquT4C\057SimQDoDaQwlFCp2sBryXyaNSRCaAhRxPaKUpKsPmubW0SJF2nQZ3DprJQcaRQLd9Qgxz+V+XaseaXXWPy+6rtB6BlPFk5FwIDAQAB":600
Is djbdns a lost cause when it comes to long TXT
records?
Solution 1:
A little bit of background on TXT records and how these are used for DKIM
TXT
records are multi-valued, each value is a string that can be up to 255 bytes.
In your example you started out with a suggested TXT
record specified in the standard master file format that had three values.
There being three values is indicated by the quotation marks, do note that these are not actually part of the record data, they only specify where each value start and end.
Your TXT
value:
"v=DKIM1; k=rsa; p=" "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7UNgSlnndT9JY0soSjxLhFFnvAeVN8b6Y3oKctAunNltMjvXfTD37doER8a9xwEOIXkGPgxJ5UPb/KndvHiIo+j8AScoIZCW1glFWp4AUoKlQkKP7o7vwFnWypU+DmcJAtyuhZ9X5yzag37cVRGYD4icd02yAETLbIpv1mnMUFkTnkdmtSa5gL2cLUueUOValoENwkWTcZR" "+kraTEU/VDPIrRgNBu6OJmQdk0sv4qdkwVVvxvquT4C/SimQDoDaQwlFCp2sBryXyaNSRCaAhRxPaKUpKsPmubW0SJF2nQZ3DprJQcaRQLd9Qgxz+V+XaseaXXWPy+6rtB6BlPFk5FwIDAQAB"
means:
v=DKIM1; k=rsa; p=
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7UNgSlnndT9JY0soSjxLhFFnvAeVN8b6Y3oKctAunNltMjvXfTD37doER8a9xwEOIXkGPgxJ5UPb/KndvHiIo+j8AScoIZCW1glFWp4AUoKlQkKP7o7vwFnWypU+DmcJAtyuhZ9X5yzag37cVRGYD4icd02yAETLbIpv1mnMUFkTnkdmtSa5gL2cLUueUOValoENwkWTcZR
+kraTEU/VDPIrRgNBu6OJmQdk0sv4qdkwVVvxvquT4C/SimQDoDaQwlFCp2sBryXyaNSRCaAhRxPaKUpKsPmubW0SJF2nQZ3DprJQcaRQLd9Qgxz+V+XaseaXXWPy+6rtB6BlPFk5FwIDAQAB
For the purpose of DKIM it's not actually meaningful to have multiple values, but as each value of a TXT
record has limited length and the DKIM spec recognizes this and says that, for the purpose of DKIM, multiple values should simply be concatenated into one long string this allows for long keys.
Ie, a DKIM client will concatenate the above values into the string
v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7UNgSlnndT9JY0soSjxLhFFnvAeVN8b6Y3oKctAunNltMjvXfTD37doER8a9xwEOIXkGPgxJ5UPb/KndvHiIo+j8AScoIZCW1glFWp4AUoKlQkKP7o7vwFnWypU+DmcJAtyuhZ9X5yzag37cVRGYD4icd02yAETLbIpv1mnMUFkTnkdmtSa5gL2cLUueUOValoENwkWTcZR+kraTEU/VDPIrRgNBu6OJmQdk0sv4qdkwVVvxvquT4C/SimQDoDaQwlFCp2sBryXyaNSRCaAhRxPaKUpKsPmubW0SJF2nQZ3DprJQcaRQLd9Qgxz+V+XaseaXXWPy+6rtB6BlPFk5FwIDAQAB
This also means that the above string could have been split at different positions without changing the meaning in DKIM.
Tinydns and TXT
Tinydns has two ways that you could possibly use to represent a TXT
record (from https://cr.yp.to/djbdns/tinydns-data.html):
1)
'fqdn:s:ttl:timestamp:lo
TXT (``text'') record for fqdn. tinydns-data creates a TXT record for fqdn containing the string s. You may use octal \nnn codes to include arbitrary bytes inside s; for example, \072 is a colon.
2)
:fqdn:n:rdata:ttl:timestamp:lo
Generic record for fqdn. tinydns-data creates a record of type n for fqdn showing rdata. n must be an integer between 1 and 65535; it must not be 2 (NS), 5 (CNAME), 6 (SOA), 12 (PTR), 15 (MX), or 252 (AXFR). The proper format of rdata depends on n. You may use octal \nnn codes to include arbitrary bytes inside rdata.
It does not appear that the built in TXT
support (1 above) allows for explicitly specifying multiple values but, while the manual does not state this, I found indications that it will split a long string on its own.
Ie, something like this should work (assuming that the information on automatic splitting is actually correct):
'mail03._domainkey.zygonia.net:v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7UNgSlnndT9JY0soSjxLhFFnvAeVN8b6Y3oKctAunNltMjvXfTD37doER8a9xwEOIXkGPgxJ5UPb/KndvHiIo+j8AScoIZCW1glFWp4AUoKlQkKP7o7vwFnWypU+DmcJAtyuhZ9X5yzag37cVRGYD4icd02yAETLbIpv1mnMUFkTnkdmtSa5gL2cLUueUOValoENwkWTcZR+kraTEU/VDPIrRgNBu6OJmQdk0sv4qdkwVVvxvquT4C/SimQDoDaQwlFCp2sBryXyaNSRCaAhRxPaKUpKsPmubW0SJF2nQZ3DprJQcaRQLd9Qgxz+V+XaseaXXWPy+6rtB6BlPFk5FwIDAQAB:7200
The other option, the generic record support (2 above), will surely work as long as you give it the appropriate rdata.
The thing is, that the rdata referenced there is a very low-level representation, you absolutely cannot just drop some plain text in there and expect it to work.
Ie, if you go down the route of entering generic record data in tinydns you will not really be helped by the master file format representation of records (the friendly plain text record data that you usually work with, such as the record data that was suggested to you) but you would rather have to look up how that data converts into the DNS wire-format (the actual binary format used in the DNS protocol) and write that (escaping problematic bytes as necessary) into the rdata field.
Ie, for a TXT
record you would have the value strings prefixed by their lengths (single byte integer, which would need to be escaped in octal as noted in the documentation).
Is djbdns/tinydns a lost cause?
Afaict not because of its handling of TXT
records specifically.
It is however a piece of software that in its official form has not seen any updates since 2001 (version 1.05).
There are patches and forks that address various shortcomings (the DNS protocol as well as our demands and expectations have continued evolving over those 15 years) but I think it would make more sense to switch to better maintained and up to date DNS server implementation.