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

Martin Kosek mkosek at redhat.com
Wed Mar 11 14:28:31 UTC 2015


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...

Martin




More information about the Freeipa-devel mailing list