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

Jan Cholasta jcholast at redhat.com
Wed Mar 11 10:34:49 UTC 2015


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.

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


-- 
Jan Cholasta




More information about the Freeipa-devel mailing list