[Freeipa-devel] DNSSEC key metadata handling

Petr Spacek pspacek at redhat.com
Wed Jun 18 17:19:17 UTC 2014


On 13.6.2014 18:43, Petr Spacek wrote:
> On 12.6.2014 17:49, Petr Spacek wrote:
>> On 12.6.2014 17:19, Simo Sorce wrote:
>>> On Thu, 2014-06-12 at 17:08 +0200, Petr Spacek wrote:
>>>> Hello list,
>>>>
>>>> I have realized that we need to store certain DNSSEC metadata for every
>>>> (zone,key,replica) triplet. It is necessary to handle splits in replication
>>>> topology.
>>>>
>>>> DNSSEC key can be in one of following states:
>>>> - key created
>>>> - published but not used for signing
>>>> - published and used for signing
>>>> - published and not used for signing but old signatures exist
>>>> - unpublished
>>>>
>>>> Every state transition has to be postponed until relevant TTL expires, and of
>>>> course, we need to consider TTL on all replicas.
>>>>
>>>>
>>>> Example of a problem
>>>> ====================
>>>> DNS TTL=10 units
>>>> Key life time=100 units
>>>>
>>>> Replica=1 Key=1 Time=0   Published
>>>> Replica=2 Key=1 Time=0   Published
>>>> Replica=1 Key=1 Time=10  Published, signing
>>>> Replica=2 Key=1 Time=10  Published, signing
>>>> Replica=1 Key=2 Time=90  Generated, published, not signing yet
>>>> Replica=2 Key=2 Time=90  <replication is broken: key=2 is not on replica=2>
>>>> Replica=1 Key=1 Time=100
>>>> ^^^ From time=100, all new signatures should be created with key=2 but that
>>>> can break DNSSEC validation because key=2 is not available on replica=2.
>>>
>>> Can you explain how this break validation ?
>>> Aren't signatures regenerated on each replica ?
>> They are.
>>
>>> And so isn't each replica self-consistent ?
>> Ah, sorry, I didn't mention one important detail. Keys published in the zone
>> 'example.com.' have to match keys published in parent zone. There has to be a
>> mechanism for synchronizing this.
>>
>> Validation will break if (keys published by parent) are not subset of (keys on
>> replicas).
>>
>> Next logical step in the example above is to remove key1 from replica 1 so you
>> will end replica1 having key2 and replica2 having only key1.
>>
>> How can we guarantee that synchronization mechanism will not wipe key1 from
>> parent? Or the other way around? How can we guarantee that key2 was uploaded?
>>
>> Also, things will break is number of keys in parent exceeds reasonable number
>> (because DNS replies will be to big etc.).
>>
>>>> Proposal 1
>>>> ==========
>>>> - Store state and timestamps for (zone,key,replica) triplet
>>>> - Do state transition only if all triplets (zone,key,?) indicate that all
>>>> replicas reached desired state so the transition is safe.
>>>> - This implicitly means that no transition will happen if one or more
>>>> replicas
>>>> is down. This is necessary otherwise DNSSEC validation can break mysteriously
>>>> when keys got out of sync.
>>>>
>>>> dn: cn=<some-replica-id>,ipk11Label=zone1_keyid123_private, cn=keys, cn=sec,
>>>> cn=dns, dc=example
>>>> idnssecKeyCreated: <timestamp>
>>>> idnssecKeyPublished: <timestamp>
>>>> idnssecKeyActivated: <timestamp>
>>>> idnssecKeyInactivated: <timestamp>
>>>> idnssecKeyDeleted: <timestamp>
>>>
>>> Why do you care for all 5 states ?
>> In short, to follow RFC 6781 and all it's requirements.
>
> Simo and I have discussed this off-line. The final decision is to rely on
> replication. The assumption is that if replication is broken, everything will
> break soon anyway, so the original proposal is overkill.
>
> We have to store one set of timestamps somewhere to be able to follow RFC
> 6781, so we decided to store it in the key-metadata object.
>
> I added other attributes to object class definition so it contains all
> necessary metadata. The new object class idnsSecKey is now complete.
>
> Please note that DN in the previous example was incorrect. It is necessary to
> store the metadata separately for pairs (zone, key) to cover the case where
> key is shared between zones. This also nicely splits metadata from actual key
> material.
>
> All attributes are single-valued.
> MUST attributes are:
>   idnsSecKeyRef
>   idnsSecKeyCreated
>   idnsSecAlgorithm
>
> dn: cn=<z/ksk+keytag>, cn=keys, idnsname=example.com, cn=dns, dc=example
> objectClass: idnsSecKey
> idnsSecKeyRef: <DN of the PKCS#11 key object under cn=keys, cn=sec, dn=dns>
> idnsSecKeyCreated: <timestamp>
> idnsSecKeyPublish: <timestamp>
> idnsSecKeyActivate: <timestamp>
> idnsSecKeyInactive: <timestamp>
> idnsSecKeyDelete: <timestamp>
> idnsSecKeyZone: <boolean> equivalent to bit 7 (ZONE) in [1]
> idnsSecKeyRevoke: <boolean> equivalent to bit 8 (REVOKE) in [1]
> idnsSecKeySep: <boolean> equivalent to bit 15 (SEP) in [1]
> idnsSecAlgorithm: <string> used as mnemonic in [2]

I haven't heard any complains so I allocated OIDs and I'm going to implement it.

Petr^2 Spacek

> [1]
> http://www.iana.org/assignments/dnskey-flags/dnskey-flags.xhtml#dnskey-flags-1
> [2]
> http://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml#dns-sec-alg-numbers-1
>
>
>>> It looks to me the only relevant states are Activated and (perhaps)
>>> Deactivated.
>>>
>>> But then again if replication is broken *many* other things are, so
>>> should we *really* care to handle broken replication by adding all this
>>> information ?
>> We need to keep track of timestamps anyway (to follow RFC 6781) so we need
>> some other way how to *make sure* that timestamps never go backwards, even if
>> replication was broken and later restarted.
>>
>> What do you propose?
>>
>>>> Effectively, state machine will be controlled by max(attribute) over all
>>>> replicas (for given key).
>>>>
>>>> Replication traffic estimation
>>>> ------------------------------
>>>> Number of writes to LDAP = (State transitions per key) * (Keys per zone) *
>>>> (Number of zones) * (Number of replicas)
>>>>
>>>> The obvious problem is that amount of traffic grows linearly with all
>>>> variables.
>>>>
>>>> State transitions per key: 5
>>>> Keys per zone: 10
>>>> Zones: 100
>>>> Replicas: 30
>>>> Key life time: 1 month
>>>>
>>>> 5*10*100*30 / 1 month
>>>> i.e.
>>>> 150 000 writes / 1 month
>>>> i.e.
>>>> ~ 1 write / 17 seconds
>>>>
>>>> It seems like that this generates a lot of replication traffic. (Please note
>>>> that number of replicas/zones/keys per zone is also quite high but it will be
>>>> hard to improve scalability later if we decide to use LDAP in this way.)
>>>
>>> Right, and for an edge case that is already a broken state. I would
>>> rather spend time on a monitoring process that warns the amdin
>>> replication is broken rather than adding all this unnecessary traffic.
>>>
>>>> And ... our favorite question :-)
>>>> What should I use for cn=<some-replica-id> ? I would propose use either FQDN
>>>> of replica or value returned by LDAP whoami.
>>>
>>> Add to this dealing with dead/removed replicas ? I question the sanity
>>> of this approach :)
>>>
>>>> Proposal 2
>>>> ==========
>>>> Another possibility is to make timestamp attributes non-replicated and
>>>> (somehow) use DNS queries to determine if the desired key is available on all
>>>> other replicas before any state transition is allowed.
>>>>
>>>> That would require:
>>>> - Full-mesh replica-to-replica connectivity
>>>> - Similar amount of DNS query/response round trips (multiply <small int>)
>>>> - Security is questionable: (Maybe, I'm not sure!) Attacker could spoof DNS
>>>> answers and break key rotation mechanism during bootstrap (when no keys are
>>>> available) and maybe even later.
>>>>
>>>> It is easy to detect that key is:
>>>> - published
>>>> - unpublished
>>>> - used for signing
>>>>
>>>> The problem is that there is no reliable way to detect that is a key was
>>>> created/is available on replica but is not published yet and similarly that
>>>> the key is published but not used for signing anymore (it would require to
>>>> check all names published in the zone).
>>>>
>>>> I will think about it a bit more but I would like to know if full-mesh
>>>> replica-to-replica connectivity is acceptable requirement or not.
>>>
>>> Not really, and again I question the need to do this.
>
> We will do some limited set DNS queries to do sanity checking, mainly when new
> KSK is to-be published. In that case we need to wait until parent zone picks
> it up.




More information about the Freeipa-devel mailing list