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

Petr Spacek pspacek at redhat.com
Wed Mar 11 11:43:54 UTC 2015


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

> You even used "*unknown* DNS record, RFC 3597" as description of the attribute
> yourself.
> 
>>
>>> Make sure it is abundantly clear in the docs what is the implication of
>>> giving access to the generic attribute w/o qualifications.
>>
>> Sure.




More information about the Freeipa-devel mailing list