Re: [Freeipa-devel] DNSSEC support design considerations

2013-05-21 Thread Simo Sorce
On Tue, 2013-05-21 at 18:32 +0200, Petr Spacek wrote:
> Hello,
> 
> I found that we (probably) misunderstood each other. The sky-high level 
> overview of the proposal follow:
> 
> NO CHANGE:
> 1) LDAP stores all *unsigned* data.
> 
> 2)
> NO CHANGE:
> a) bind-dyndb-ldap *on each server* fetches all unsigned data from LDAP and 
> store them in *in memory* database (we do it now)
> 
> THE DIFFERENCE:
> b) All data will be stored in BIND's native RBT-database (RBTDB) instead of 
> our own in-memory database.
> 
> NEW PIECES:
> 3)
> Mechanisms implemented in BIND's RBTDB will do DNSSEC signing etc. for us. 
> The 
> BIND's feature is called 'in-line signing' and it can do all key/signature 
> maintenance for us, including periodical zone re-signing etc.
> 
> 
> The whole point of this proposal is about code-reusage. I'm trying to avoid 
> re-inventing of the wheel.
> 
> Note that DNSSEC implementation in BIND has ~ 150 kiB of C code, stand-alone 
> signing utilities add another ~ 200 kiB of code (~ 7000 lines) . I really 
> don't want to re-write it again when it's not reasonable.
> 
> Further comments are in-line.

Ok putting some numbers on this topic really helps, thanks!

More inline.

[..]

> > I haven't seen any reasoning from you why letting Bind do this work is
> > a better idea.
> Simply said - because all the code is already in BIND (the feature is called 
> 'in-line signing', as I mentioned above).
> 
> > I actually see some security reasons why putting this into a DS plugin
> > can have quite some advantages instead. Have you considered doing this
> It could improve the security a bit, I agree. But I don't think that it is so 
> big advantage. BIND already has all the facilities for key material handling, 
> so the only thing we have to solve is how to distribute keys from LDAP to 
> running BIND.

Well it would mean sticking the key in ldap and letting Bind pull them
from there based on ACIs ...
The main issue would be changes in keys, but with the persistent search
I guess that's also not a huge deal.

> > work in a DS plugin at all ? If you haven and have discarded the idea,
> > can you say why ?
> 1) It would require pulling ~ 200 kiB (~ 7000 lines) of DNSSEC signing code 
> into 389.
> 
> 2) It would require pulling 'text->DNS wire format' parser into 389 (because 
> our LDAP stores plain text data but the signing process works with DNS wire 
> format).
> 
> 3) It simplifies bind-dyndb-ldap, but we still need to re-implement DNS 
> search 
> algorithm which takes DNSSEC oddities into account. (Note that the DNS search 
> algorithm is part of the database implementation. Bugs/limitations in our 
> implementation are the reason why wildard records are not supported...)
> 
> 4) I'm not sure how it will work with replication. How to ensure that new 
> record will not appear in the zone until the associated RRset is (re)computed 
> by DS? (BIND has transaction mechanism built-in to the internal RBTDB.)

389ds has internal transactions, which is why I was thinking to do the
signatures on any change coming into LDAP (direct or via replication,
within the transaction.

> >> The point is that you *can* do changes run-time, but you need to know about
> >> the changes as soon as possible because each change requires significant
> >> amount of work (and magic/mana :-).
> >>
> >> It opens a lot of opportunities for race condition problems.
> >
> > Yes, I am really concerned about the race conditions of course, however
> > I really wonder whether doing signing in bind is really a good idea.
> > We need to synchronize these signatures to all masters right ?
> No, because signatures are computed and stored only in memory - and forgotten 
> after BIND shutdown. Yes, it requires re-computing on each load, this is 
> definitely disadvantage.

Ok I definitely need numbers here.
Can you do a test with a normal, text based, Bind zone with 10k entries
and see how much time it takes to re-sign everything ?

I suspect that will be way too much, so we will have the added problem
of having to maintain a local cache in order to be able to restart Bind
and have it actually server results in a reasonable time w/o killing the
machine completely.

> > Doesn't that mean we need to store this data back in LDAP ?
> No, only 'normal' DNS updates containing unsigned data will be written back 
> to 
> LDAP. RRSIG and NSEC records will never reach LDAP.
> 
> > That means more round-trips before the data ends up being usable, and we
> > do not have transactions in LDAP, so I am worried that doing the signing
> > in Bind may not be the best way to go.
> I'm proposing to re-use BIND's transaction mechanism built in internal 
> database implementation.
> 
>  => It should be possible to save old database to disk (during BIND 
>  shutdown
>  or
>  periodically) and re-use this old database during server startup. I.e. 
>  server
>  will start replying immediately from 'old' database and then the server 
>  wil

Re: [Freeipa-devel] DNSSEC support design considerations

2013-05-21 Thread Petr Spacek

Hello,

I found that we (probably) misunderstood each other. The sky-high level 
overview of the proposal follow:


NO CHANGE:
1) LDAP stores all *unsigned* data.

2)
NO CHANGE:
a) bind-dyndb-ldap *on each server* fetches all unsigned data from LDAP and 
store them in *in memory* database (we do it now)


THE DIFFERENCE:
b) All data will be stored in BIND's native RBT-database (RBTDB) instead of 
our own in-memory database.


NEW PIECES:
3)
Mechanisms implemented in BIND's RBTDB will do DNSSEC signing etc. for us. The 
BIND's feature is called 'in-line signing' and it can do all key/signature 
maintenance for us, including periodical zone re-signing etc.



The whole point of this proposal is about code-reusage. I'm trying to avoid 
re-inventing of the wheel.


Note that DNSSEC implementation in BIND has ~ 150 kiB of C code, stand-alone 
signing utilities add another ~ 200 kiB of code (~ 7000 lines) . I really 
don't want to re-write it again when it's not reasonable.


Further comments are in-line.


On 20.5.2013 14:07, Simo Sorce wrote:

On Wed, 2013-05-15 at 17:11 +0200, Petr Spacek wrote:

On 15.5.2013 10:29, Simo Sorce wrote:

I investigated various scenarios for DNSSEC integration and I would like to
hear your opinions about proposed approach and it's effects.


The most important finding is that bind-dyndb-ldap can't support DNSSEC
without rewrite of the 'in-memory database' component.


Can you elaborate why a rewrite would be needed ? What constraint we do not 
meet ?


We have three main problems - partially with data structures and mostly with
the way how we work with the 'internal database':

1) DNSSEC requires strict record ordering, i.e. each record in database has to
have predecessor and successor (ordering by name and then by record data).
This can be done relatively simply, but it requires a full dump of the database.

2) On-line record signing requires a lot of data stored
per-record+per-signature. This would require bigger effort than point 1),
because many data structures and respective APIs and locking protocols have to
be re-designed.

3) Our current 'internal database' acts as a 'cache', i.e. records can appear
and disappear dynamically and the 'cache' is not considered as authoritative
source of data: LDAP search is conducted each time when some data are not
found etc. The result is that the same data can disappear and then appear
again in the cache etc.

Typical update scenario, with persistent search enabled:
a) DNS UPDATE from client is received by BIND
b) New data are written to LDAP
c) DN of modified object is received via persistent search
d) All RRs under the *updated name* are discarded from the cache
<-- now the cache is not consistent with data in LDAP
e) Object from LDAP is fetched by plugin
<-- a query for the updated name will enforce instant cache refresh, because
we know that the cache is not authoritative
f) All RRs in the object are updated (in cache)

The problem is that the cache in intermediate states (between <-- marks) can't
be used as authoritative source and will produce incorrect signatures. The
text below contains more details.

Database's in BIND has concept of 'versions' ('transactions') which our
internal cache do not implement ... It could be solved by proper locking, of
course, but it will not be a piece of cake. We need to take care of many
parallel updates, parallel queries and parallel re-signing at the same time.

I don't say that it is impossible to implement our own backend with same
properties as BIND's database, but I don't see the value (and I can see a lot
of bugs :-).


Well, we do not necessarily need all the same properties of bind's
database, only those that allow us to properly handle DNSSEC, so let's
try to uncover what those constrains are first, so I can understand why
you propose this solution as better than something else.


Fortunately, it seems
that we can drop our own implementation of the internal DNS database
(ldap_driver.c and cache.c) and re-use the database from BIND (so called
RBTDB).

I'm trying to reach Adam Tkac with the question "Why we decided to implement
it again rather than re-use BIND's code?".


Re-usage of BIND's implementation will have following properties:


== Advantages ==
- Big part of DNSSEC implementation from BIND9 can be reused.
- Overall plugin implementation will be simpler - we can drop many lines of
our code and bugs.
- Run-time performance could be much much better.

- We will get implementation for these tickets "for free":
-- #95  wildcard CNAME does NOT work
-- #64  IXFR support (IMHO this is important!)
-- #6   Cache non-existing records

And partially:
-- #7   Allow limiting of the cache


Sounds very interesting.



== Disadvantages ==
- Support for configurations without persistent search will complicate things
a lot.
-- Proposal => Make persistent search obligatory. OpenLDAP supports LDAP
SyncRepl, so it should be possible to make plugin compatible with 389 and
OpenLDAP at the same time. I