[Freeipa-devel] Generic support for unknown DNS RR types (RFC 3597)

Martin Kosek mkosek at redhat.com
Wed Mar 11 14:45:42 UTC 2015


On 03/11/2015 03:38 PM, Petr Spacek wrote:
> On 11.3.2015 15:28, Martin Kosek wrote:
>> On 03/11/2015 12:43 PM, Petr Spacek wrote:
>>> On 11.3.2015 11:34, Jan Cholasta wrote:
>>>> Dne 11.3.2015 v 11:12 Petr Spacek napsal(a):
>>>>> On 10.3.2015 20:04, Simo Sorce wrote:
>>>>>> On Tue, 2015-03-10 at 19:24 +0100, Petr Spacek wrote:
>>>>>>> On 10.3.2015 18:36, Simo Sorce wrote:
>>>>>>>> On Tue, 2015-03-10 at 18:26 +0100, Petr Spacek wrote:
>>>>>>>>> On 10.3.2015 17:35, Simo Sorce wrote:
>>>>>>>>>> On Tue, 2015-03-10 at 16:19 +0100, Petr Spacek wrote:
>>>>>>>>>>> On 10.3.2015 15:53, Simo Sorce wrote:
>>>>>>>>>>>> On Tue, 2015-03-10 at 15:32 +0100, Petr Spacek wrote:
>>>>>>>>>>>>> Hello,
>>>>>>>>>>>>>
>>>>>>>>>>>>> I would like to discuss Generic support for unknown DNS RR types
>>>>>>>>>>>>> (RFC 3597
>>>>>>>>>>>>> [0]). Here is the proposal:
>>>>>>>>>>>>>
>>>>>>>>>>>>> LDAP schema
>>>>>>>>>>>>> ===========
>>>>>>>>>>>>> - 1 new attribute:
>>>>>>>>>>>>> ( <OID> NAME 'GenericRecord' 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 should contain data encoded according to ​RFC
>>>>>>>>>>>>> 3597 section
>>>>>>>>>>>>> 5 [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
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Open questions about LDAP format
>>>>>>>>>>>>> ================================
>>>>>>>>>>>>> Should we include "\#" constant? We know that the attribute contains
>>>>>>>>>>>>> record in
>>>>>>>>>>>>> RFC 3597 syntax so it is not strictly necessary.
>>>>>>>>>>>>>
>>>>>>>>>>>>> I think it would be better to follow RFC 3597 format. It allows blind
>>>>>>>>>>>>> copy&pasting from other tools, including direct calls to python-dns.
>>>>>>>>>>>>>
>>>>>>>>>>>>> It also eases writing conversion tools between DNS and LDAP format
>>>>>>>>>>>>> because
>>>>>>>>>>>>> they do not need to change record values.
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Another question is if we should explicitly include length of data
>>>>>>>>>>>>> represented
>>>>>>>>>>>>> in hexadecimal notation as a decimal number. I'm very strongly
>>>>>>>>>>>>> inclined to let
>>>>>>>>>>>>> it there because it is very good sanity check and again, it allows
>>>>>>>>>>>>> us to
>>>>>>>>>>>>> re-use existing tools including parsers.
>>>>>>>>>>>>>
>>>>>>>>>>>>> I will ask Uninett.no for standardization after we sort this out
>>>>>>>>>>>>> (they own the
>>>>>>>>>>>>> OID arc we use for DNS records).
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Attribute usage
>>>>>>>>>>>>> ===============
>>>>>>>>>>>>> Every DNS RR type has assigned a number [1] 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. Let's use
>>>>>>>>>>>>> attribute
>>>>>>>>>>>>> sub-types.
>>>>>>>>>>>>>
>>>>>>>>>>>>> E.g. a record with type 65280 and hex value 0A000001 will be
>>>>>>>>>>>>> represented as:
>>>>>>>>>>>>> GenericRecord;TYPE65280: \# 4 0A000001
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> CLI
>>>>>>>>>>>>> ===
>>>>>>>>>>>>> $ ipa dnsrecord-add zone.example owner \
>>>>>>>>>>>>>    --generic-type=65280 --generic-data='\# 4 0A000001'
>>>>>>>>>>>>>
>>>>>>>>>>>>> $ ipa dnsrecord-show zone.example owner
>>>>>>>>>>>>> Record name: owner
>>>>>>>>>>>>> TYPE65280 Record: \# 4 0A000001
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> ACK? :-)
>>>>>>>>>>>>
>>>>>>>>>>>> Almost.
>>>>>>>>>>>> We should refrain from using subtypes when not necessary, and in this
>>>>>>>>>>>> case it is not necessary.
>>>>>>>>>>>>
>>>>>>>>>>>> Use:
>>>>>>>>>>>> GenericRecord: 65280 \# 4 0A000001
>>>>>>>>>>>
>>>>>>>>>>> I was considering that too but I can see two main drawbacks:
>>>>>>>>>>>
>>>>>>>>>>> 1) It does not work very well with DS ACI (targetattrfilter, anyone?).
>>>>>>>>>>> Adding
>>>>>>>>>>> generic write access to GenericRecord == ability to add TLSA records too,
>>>>>>>>>>> which you may not want. IMHO it is perfectly reasonable to limit write
>>>>>>>>>>> access
>>>>>>>>>>> to certain types (e.g. to one from private range).
>>>>>>>>>>>
>>>>>>>>>>> 2) We would need a separate substring index for emulating filters like
>>>>>>>>>>> (type==65280). AFAIK GenericRecord;TYPE65280 should work with presence
>>>>>>>>>>> index
>>>>>>>>>>> which will be handy one day when we decide to handle upgrades like
>>>>>>>>>>> GenericRecord;TYPE256->UriRecord.
>>>>>>>>>>>
>>>>>>>>>>> Another (less important) annoyance is that conversion tools would have to
>>>>>>>>>>> mangle record data instead of just converting attribute name->record
>>>>>>>>>>> type.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> I can be convinced that subtypes are not necessary but I do not see clear
>>>>>>>>>>> advantage of avoiding them. What is the problem with subtypes?
>>>>>>>>>>
>>>>>>>>>> Poor support by most clients, so it is generally discouraged.
>>>>>>>>> Hmm, it does not sound like a thing we should care in this case. DNS
>>>>>>>>> tree is
>>>>>>>>> not meant for direct consumption by LDAP clients (compare with cn=compat).
>>>>>>>>>
>>>>>>>>> IMHO the only two clients we should care are FreeIPA framework and
>>>>>>>>> bind-dyndb-ldap so I do not see this as a problem, really. If someone
>>>>>>>>> wants to
>>>>>>>>> access DNS tree by hand - sure, use a standard compliant client!
>>>>>>>>>
>>>>>>>>> Working ACI and LDAP filters sounds like good price for supporting only
>>>>>>>>> standards compliant clients.
>>>>>>>>>
>>>>>>>>> AFAIK OpenLDAP works well and I suspect that ApacheDS will work too because
>>>>>>>>> Eclipse has nice support for sub-types built-in. If I can draw some
>>>>>>>>> conclusions from that, sub-types are not a thing aliens forgot here when
>>>>>>>>> leaving Earth one million years ago :-)
>>>>>>>>>
>>>>>>>>>> The problem with subtypes and ACIs though is that I think ACIs do not
>>>>>>>>>> care about the subtype unless you explicit mention them.
>>>>>>>>> IMHO that is exactly what I would like to see for GenericRecord. It
>>>>>>>>> allows us
>>>>>>>>> to write ACI which allows admins to add any GenericRecord and at the
>>>>>>>>> same time
>>>>>>>>> allows us to craft ACI which allows access only to
>>>>>>>>> GenericRecord;TYPE65280 for
>>>>>>>>> specific group/user.
>>>>>>>>>
>>>>>>>>>> So perhaps bind_dyndb_ldap should refuse to use a generic type that
>>>>>>>>>> shadows DNSSEC relevant records ?
>>>>>>>>> Sorry, this cannot possibly work because it depends on up-to-date
>>>>>>>>> blacklist.
>>>>>>>>>
>>>>>>>>> How would the plugin released in 2015 know that highly sensitive OPENPGPKEY
>>>>>>>>> type will be standardized in 2016 and assigned number XYZ?
>>>>>>>>
>>>>>>>> Ok, show me an example ACI that works and you get my ack :)
>>>>>>>
>>>>>>> Am I being punished for something? :-)
>>>>>>>
>>>>>>> Anyway, this monstrosity:
>>>>>>>
>>>>>>> (targetattr = "objectclass || txtRecord;test")(target =
>>>>>>> "ldap:///idnsname=*,cn=dns,dc=ipa,dc=example")(version 3.0;acl
>>>>>>> "permission:luser: Read DNS Entries";allow (compare,read,search) userdn =
>>>>>>> "ldap:///uid=luser,cn=users,cn=accounts,dc=ipa,dc=example";)
>>>>>>>
>>>>>>> Gives 'luser' read access only to txtRecord;test and *not* to the whole
>>>>>>> txtRecord in general.
>>>>>>>
>>>>>>> $ kinit luser
>>>>>>> $ ldapsearch -Y GSSAPI -s base -b
>>>>>>> 'idnsname=txt,idnsname=ipa.example.,cn=dns,dc=ipa,dc=example'
>>>>>>> SASL username: luser at IPA.EXAMPLE
>>>>>>>
>>>>>>> # txt, ipa.example., dns, ipa.example
>>>>>>> dn: idnsname=txt,idnsname=ipa.example.,cn=dns,dc=ipa,dc=example
>>>>>>> objectClass: top
>>>>>>> objectClass: idnsrecord
>>>>>>> tXTRecord;test: Guess what is new here!
>>>>>>>
>>>>>>> Filter '(tXTRecord;test=*)' works as expected and returns only objects with
>>>>>>> subtype ;test.
>>>>>>>
>>>>>>> The only weird thing I noticed is that search filter '(tXTRecord=*)' does not
>>>>>>> return the object if you have access only to an subtype with existing value
>>>>>>> but not to the 'vanilla' attribute.
>>>>>>>
>>>>>>> Maybe it is a bug? I will think about it for a while and possibly open a
>>>>>>> ticket. Anyway, this is not something we need for implementation.
>>>>>>>
>>>>>>>
>>>>>>> For completeness:
>>>>>>>
>>>>>>> $ kinit admin
>>>>>>> $ ldapsearch -Y GSSAPI -s base -b
>>>>>>> 'idnsname=txt,idnsname=ipa.example.,cn=dns,dc=ipa,dc=example'
>>>>>>> SASL username: admin at IPA.EXAMPLE
>>>>>>>
>>>>>>> # txt, ipa.example., dns, ipa.example
>>>>>>> dn: idnsname=txt,idnsname=ipa.example.,cn=dns,dc=ipa,dc=example
>>>>>>> objectClass: top
>>>>>>> objectClass: idnsrecord
>>>>>>> tXTRecord: nothing
>>>>>>> tXTRecord: something
>>>>>>> idnsName: txt
>>>>>>> tXTRecord;test: Guess what is new here!
>>>>>>>
>>>>>>>
>>>>>>> And yes, you assume correctly that (targetattr = "txtRecord") gives access to
>>>>>>> whole txtRecord including all its subtypes.
>>>>>>>
>>>>>>> ACK? :-)
>>>>>>>
>>>>>>
>>>>>> ACK.
>>>>>
>>>>> Thank you. Now to the most important and difficult question:
>>>>> Should the attribute name be "GenericRecord" or "UnknownRecord"?
>>>>>
>>>>> I like "GenericRecord" but Honza prefers "UnknownRecord" so we need a third
>>>>> opinion :-)
>>>>
>>>> GenericRecord sounds like something that may be used for any record type,
>>>> known or unknown. I don't think that's what we want. We want users to use it
>>>> only for unknown record types and use appropriate <type>Record attribute for
>>>> known attributes.
>>>>
>>>> The RFC is titled "Handling of *Unknown* DNS Resource Record (RR) Types". The
>>>> word "generic" is used only when referring to encoding of RDATA.
>>>
>>> Okay, be it 'UnknownRecord'.
>>>
>>> Petr^2 Spacek
>>
>> I am just afraid it is quite general name, that may collide with other
>> attribute names. If it would be named "idnsUnknownRecord", it would be more
>> unique. But I assume we cannot add idns prefix for records themselves...
> 
> Good point. What about UnknownDNSRecord?

Maybe. Question is how consistent we want to be with other DNS record names
(arecord, ptrrecord) and how consistent we want to be with Uninett schema
(details in https://fedorahosted.org/bind-dyndb-ldap/wiki/LDAPSchema) and if
this new record would be discussed with them and added to their OID space.

Martin




More information about the Freeipa-devel mailing list