Search: Home Bugtraq Vulnerabilities Mailing Lists Jobs Tools Beta Programs
Digg this story   Add to del.icio.us  
A Case Against DNSSEC, Count 2: Too Complicated To Deploy
Thomas Ptacek, Matasano 2007-04-05

1.

Alice wants a.victim.org’s IP. She asks the DNS.

1.png

So, a.victim.org is 1.2.3.4. Simple enough? Let’s add a wrinkle:

2.png

The question, “what is a.victim.org?”, and the answer, “1.2.3.4!”, are records inside of DNS messages. The DNS —- the whole distributed database, that is —- is made up entirely of these records. The records are keyed by name, type, and class, and contain bundles of data.

A subtlety, which we’ll be returning to —- Alice asks for z.victim.org:

3.png

z.victim.org doesn’t exist. Alice doesn’t get a record; she gets an error packet. There’s a difference.

Moving on. Alice didn’t really ask the DNS anything:

71.png

Alice’s stub resolver asks her cache to find out about a.victim.com from the victim.com authority servers. The stub is her Mac’s built-in resolver library, which her browser is linked to. The cache is the nameserver SpeakEasy, her ISP, gave her. The authority is “named”, AKA BIND, running on ns.victim.com.

2.

Enough remedial DNS. Back to DNSSEC. Mallory can spoof responses to Alice’s DNS queries. We want to stop her. We use cryptography:

51.png

Sign the records (RR’s in the jargon) with a signature based on an RSA keypair. Stick the public key in the DNS where Alice’s cache can find it. Her cache gets a public key attached to victim.com and an “a.victim.com is 1.2.3.4” RR signed under that public key.

If you’re with me so far then, with one important exception, you’ve got the “service model” for DNSSEC —- meaning, what DNSSEC is trying to accomplish. Caches can look at records and tell if they’re valid. Mallory can’t forge records without subverting the keys.

How do we manage and protect those keys? Good question. Let’s introduce some notation:

6.png

We can generate and store RSA keypairs. We can fingerprint keys (public keys) by taking a hash or MAC of them, just like SSH and PGP do. And we can use private keys to generate signatures of blobs (or hashes of blobs) of data.

With that in mind:

a2.png

Ok, breathe.

Alice’s cache ships preconfigured to trust a root key, which basically never changes. Exactly the same way Alice’s browser works with SSL to use Verisign’s CA. Again, let’s call that a “trust anchor”; it’s a secure starting point for DNSSEC queries.

A.VICTIM.ORG. is linked from the root, to ORG, to VICTIM.ORG, containing A.VICTIM.ORG. ORG and VICTIM are delegations (because different people run the roots, ORG, and VICTIM).

In DNSSEC, authentication follows delegations. Sometimes. More on that later.

The root vouches for a key in ORG using a fingerprint record (a Delegation Signer, or DS). Root’s voucher for ORG is signed under root’s key, so Mallory can’t change it: Alice knows the root’s key and now ORG’s key.

Repeat until you get the record you want. This is an authentication chain.

3.

And it’s fine, as far as it goes, though you’ve got to remember that it took something like 13 years to get here.

I’m describing RFC4033 DNSSECbis (bis! Still don’t believe me about the invasion of the OSI-snatchers?) from 2006. The original DNSSEC proposals date back to the early 90’s, when government contractor TIS Labs (Marcus Ranum’s old haunt) convinced the DOD to let them try to secure the DNS.

The DNSSEC attempt preceding RFC4033 put signatures in the wrong place, so that if the key for COM ever got compromised, tens of millions of DNS records would have to be replaced.

That proposal lived, as “the DNSSEC standard” until the end of 2001.

You’re right. It’s a cheap shot to attack the standards process itself for being unstable and untenable. Paul Vixie does a much better job:

dnssec is the worst design-by-committee effort i’ve ever seen, both in terms of how late it is, how fuzzy the goals have been, how often the goals have changed, and how complicated and heavy it is now that it is trying to be all-things-to-all-people.

—- Paul Vixie, about 5 months ago.

(I’m not sure if I agree or disagree with Vixie —- allowing for how unqualified I am to make judgements on the IETF —- but I’m pretty sure that the answer of having him and Jim Reid raise $1.6MM to create a members-only “Shadow IETF” that costs $10k to “vote” was a step in the wrong direction).

But whatever. Back to the protocol, as it exists today. I’ve got something cool to show you. Bear with me, this is going to seem redundant.

4.

Insecure DNS. The host “a” exists, and “z” doesn’t:

8.png

Now, secure DNS. The host “a” exists, and “z” doesn’t:

9.png

Uh-oh. DNSSEC protects records. “The” DNS. It doesn’t protect DNS packets. Those are just a means to an end. So without magic, we can’t distinguish between a “real” error and a fake one!

That’s sort of a problem. And I sincerely mean “sort of”.

For one thing, Mallory can deny service to Alice and Bob by forging errors. But so what? In a DNSSEC world, Mallory can deny service to the entire Internet from a small botnet by saturating DNS servers with expensive crypto operations.

On the other hand, being able to forge errors also allows Mallory to change the semantic meaning of some DNS zones. The best example is MX, the mail exchanger record: MX tells Sendmail and Exchange where to send your mail. Without an MX, mail goes to your hostname. So Mallory can send mail to the wrong host.

Reasonable people disagree about whether this is all a real problem, but the “consensus” is that DNSSEC needs to solve it. So we get authenticated denial (or “provable non-existence”, PNE, DNSSEC). Check this out:

42.png

You take all the RR’s in your zone. You sort them —- which requires its own standard because crypto needs canonicalization —- and them link the names of the RR’s together with another kind of record called an NXT —- errr, sorry, NSEC. An NSEC links two DNS names together, basically asserting “no name comes between these two in the sort”.

Now, when you ask for a record that doesn’t exist, the DNS can inform you of that reliably. You get an unexpectedly wrong NSEC record back from the query. It says, “look, your record falls in between two names linked by an NSEC, in a gap where no name can be”. And that record is signed, “proving” the nonexistence of the name.

And that’s fine, because —- oh wait, you in the back there, you have something to say?

Oh. Crap. You’re right. Bad guys can just walk the NSEC chain to list all the names in your zone. Yeah, that’s pretty much exactly the same thing as allowing zone transfers. I know you’ve had zone transfers blocked since 1998 —- yeah? IETF mailing list guy in the front row? With your hand raised? What’s that?

Well, OK, sure, maybe all DNS names should be public. But IETF guy, the names in your zone read like this:

decmultia.greybeard.com
vax-in-my-basement.greybeard.com
sun-ipx.greybeard.com
symbolics.greybeard.com
slackware.greybeard.com
knights-that-say-nee.greybeard.com

And that guy in the back? His names go something like this:

money0.secretcustomer0.bigbank.com
money0.secretcustomer1.bigbank.com
vulnerable.managementsystem.bigbank.com
payrollsystem.bigbank.com
linux-box.boss-not-supposed-to-know-about.bigbank.com

And let’s not even start talking about the guys who run COM. The RR’s in COM right now are just a couple of tiny NS’s. They keep the whole database resident in memory. But DNSSECbis requires them to set up NSEC records for them, too. And sort them. And, by the way, something I haven’t really pointed out yet about DNSSEC RR’s —- know how I’ve been acting like they look like this:

c.png

Well, actually, they look like this:

d.png

RSA signatures are kind of painful that way. The COM guys better find bigger boxes.

The IETF has a solution for this problem, which Ben Laurie helped write. It’s not a “standard” yet, and so not really part of DNSSECbis. But it’s funny, and not hard to explain. It’s called NSEC3.

Here’s the idea: turn the NSEC chain into a Unix password file. Make the names into salted crypt(3)-style hashes. You can prove an NSEC3 record matches what you were looking for or not, but you can’t turn the NSEC chain back into the zone dump. At least not without crack(8).

I have misgivings about this idea. You can scale password files up with compute using adaptive hashing, because people don’t log in to their computers very often —- but people use the DNS all the time, so you can’t make a lookup step take 5 seconds.

Fortunately, there’s another IETF solution to the problem. It’s called “minimum coverage NSEC”, also known as “whitelies”, involves the servers forging NSEC records to trick people trying to dump the zone, seems to require on-demand signing of RR’s (a no-no —- your privkeys are supposed to be in a vault in Tuscon), and nobody is ever going to deploy any of this so let’s move on.

At this point I’m reminded of a classic from the Western canon:

Scientist

Mr. Simpson, we don’t play God here.

Homer

What? You do nothing BUT play God. And I think your Octoparrot would agree.

Octoparrot

Squawk! Polly shouldn’t be!

One more wrinkle. This looks like a total non-starter for the COM guys. So they were demanding an extension, informally known as “opt-in”, which lets them mark whole stretches of the COM RR space as insecure so they don’t have to run their name servers on Beowulf clusters just to let 10 guys mess with DNSSECbis.

But none of these things are in the “standard”. Which is “finished” and we’re supposed to deploy. NSEC? NSEC3? Whitelies? Opt-In? Or can we just do away with authenticated denial altogether and go with “signing only” DNSSECbis?

5.

5.0.

Another issue. DNSSECbis protects RR’s, which are like the nuclei of DNSSEC cells. But the cell walls are still fragile, and other things besides normal DNS rely on them —- for instance, DNS dynamic update, which is its own debacle. Want secure dynamic update? That’s a different standard, either called TSIG (which secures DNS the same way DESLogin secured Telnet), or SIG(0), which uses public keys. These are different standards than DNSSEC.

5.1.

Another issue, which may have been obvious:

b.png

Alice’s stub resolver library is not going to support DNSSECbis any time soon (note to my Apple and Microsoft readers who spend money to audit their OS and runtime code: Alice’s stub resolver library is not going to support DNSSECbis any time soon. Get it?).

So DNSSECbis doesn’t protect the “last mile” between Alice and her ISP. “But that’s OK, that last mile is behind a firewall!”

5.2.

Another issue: nobody knows when or where or how or who or why the roots are going to be signed and who will own the key. Without dignifying this “Homeland Security wants the root signing key” controversey, let’s acknowledge that the dream of a solid authentication chain running from a.victim.com all the way back through COM to the root isn’t happening anytime soon.

That’s OK. The ISC, authors of BIND, have set up a parallel ICANN for DNSSEC, and a protocol extension to match it. If the ICANN/IANA roots won’t secure “a.victim.org”, DLV will secure “a.victim.org.dlv.isc.org” for you. And all you have to do is trust yet another server, this time run by the ISC. And also accept DLV as part of the DNSSECbis standard, which it isn’t, yet.

Having fun yet? Anyone want to lay odds on DNSSECbisbis (or whatever the CCITT folks do after “bis”) happening?

6.

Which, thankfully, brings me to the last part of my argument.

Have you ever set up an SSL certificate?

Have you ever set up a zone with an AXFR secondary in BIND?

These are not two great tastes that go together. But it gets worse. It always does. Because here’s something else that you’ve probably done: you’ve visited a totally legitimate HTTPS website that had an expired or transiently broken SSL cert.

When that happens, you get a click-through warning, which you dutifully ignore. That’s a part of the Internet that the DNSSEC people don’t like. And I feel their pain. But.

When a browser sees an invalid SSL certificate, it has the option of popping up a warning dialog that you can ignore. Now, this is what DNS lookup code looks like in your applications now:

if(!(hp = gethostbyname("a.victim.com")))
    fatality();

And, this is what DNS lookup code looks like in your application after DNSSEC:

if(!(hp = gethostbyname("a.victim.com")))
    fatality();

And, “fatality” is what you get if any piece of this DNSSEC puzzle fails. All the signatures on all those records out there? They expire and need to be renewed. And they have be kept in sync across the whole system. And they have to be configured, by tens of thousands of people of wildly differing skill levels.

That’s because the DNS interfaces on every host on the Internet have no good way of signalling failure. In fact, because DNSSECbis won’t extend down the “last mile”, like I mentioned, the protocol won’t have a good way of signalling failure. Which means that all the transient glitches you get with SSL, which is a vastly simpler and smaller system, are total failures in DNS.

Still a believer? There’s more to come.


Comments


The information, views, and opinions contained on this page are those of the author and do not necessarily reflect the views and opinions of SecurityFocus.






 

Privacy Statement
Copyright 2009, SecurityFocus