RFC 3597 describes mechanism necessary for supporting unknown/new DNS RR types in DNS servers. BIND 9 supports this so we only need to expose this functionality too.
This is a future-proof workaround for cases when someone needs a new type which is not standardized yet or is not supported in installed version of BIND.
Keep in mind that support for new RR types might take a long time to get into conservative distros like CentOS etc. Also, this proposal enables users to mix older and newer versions of BIND in the same LDAP cluster and still use all possible record types.
1 new attribute:
( <OID> NAME 'UnknownRecord' DESC 'unknown DNS record, RFC 3597' EQUALITY
caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
The attribute should be added to existing idnsRecord object class as MAY.
This new attribute will contain data encoded according to RFC 3597 section 5:
The RDATA section of an RR of unknown type is represented as a
sequence of white space separated words as follows:
The special token \# (a backslash immediately followed by a hash
sign), which identifies the RDATA as having the generic encoding
defined herein rather than a traditional type-specific encoding.
An unsigned decimal integer specifying the RDATA length in octets.
Zero or more words of hexadecimal data encoding the actual RDATA
field, each containing an even number of hexadecimal digits.
If the RDATA is of zero length, the text representation contains only
the \# token and the single zero representing the length.
Examples from RFC:
a.example. CLASS32 TYPE731 \# 6 abcd (
ef 01 23 45 )
b.example. HS TYPE62347 \# 0
e.example. IN A \# 4 0A000001
e.example. CLASS1 TYPE1 10.0.0.2
Every DNS RR type has an IANA-assigned number which is used on wire.
RR types which are unknown to the server cannot be named by their mnemonic/type name because server would not be able to do name->number conversion and to generate DNS wire format.
As a result, we have to encode the RR type number somehow. RR type is
represented as LDAP sub-type of UnknownRecord
named using standard
TYPE12345
convention defined in RFC 3597 section
5.
E.g. a record with type 65280
and hex value 0A000001
will be
represented as:
UnknownRecord;TYPE65280: \# 4 0A000001
String stored in attribute value includes whole right-hand side
including \#
and length as decimal number, e.g.
\# 4 0A000001
Usage of LDAP sub-types allows usage of standard LDAP filtering and access control mechanisms on RR type-level.
Unlimited write access to UnknownRecord
attribute allows user to
create arbitrary RR with arbitrary data. It is highly desirable to use
LDAP access controls to allow access only to subset of sub-types and
thus to allow to create only subset of all possible RR types. E.g. it
might be undesirable to allow lower-level users to create TLSA records
for arbitrary hosts etc.
bind-dyndb-ldap converts RR type number to string like AAAA
and
tries to store the data into the <RRType>Record
attribute first. If
this operation fails with LDAP object class violation, then
bind-dyndb-ldap converts the data into generic format and stores them
into UnknownRecord;TYPE12345
attribute.
It is an implementation detail if driver understands the schema or of it is dumb and just tries to write both variants.
Records stored in UnknownRecord
attribute will not be available on
older servers which do not understand this record type.
Generic problem with multiple versions of BIND backed with shared LDAP
database can be mitigated using UnknownRecord
attribute:
Imagine you have a cluster consisting of BIND 9.8 and 9.9 installations running on the same LDAP database.
E.g. BIND 9.8 does not know OPENPGPKEY
record and BIND 9.9 knows it.
Naturally, BIND 9.8 cannot understand the textual representation of
OPENPGPKEY
records so we have to resort to intersection of sets of
record types supported by all BIND versions in the cluster.
If BIND 9.8 receives update request to add OPENPGPKEY
record it
transforms RR type to TYPE61
and uses generic encoding for data
written to LDAP because it is the only format the old BIND understands.
If BIND 9.9 receives update request to add OPENPGPKEY
record it has
two options:
At this point, we need to ensure that BIND 9.9 does the right thing and uses the generic format otherwise the older BIND 9.8 in the same cluster would not understand the data.
This can be done by not adding OPENPGPKEYRecord
attribute to the
schema until all BIND 9.8 servers in the cluster are upgraded to
understand the new record type.
Generally, try to add a new record which is not known to BIND. E.g.
$ nsupdate -g
update add newrec.zone.test. 10 IN TYPE65280 \# 4 0A000001
send
$ dig newrec.zone.test. TYPE65280
dig
command has to display the new record and it has to survive BIND
restart.
TODO Test scenarios that will be transformed to test cases for FreeIPA Continuous Integration during implementation or review phase. This can be also link to source in git with the test, if appropriate.
pspacek@…