I haven't yet seen a good explanation of how DNSSec works outside of the RFC's, so:

How does DNSSec work?

Are there known limitations I should be aware of? Specifically, how to we prevent the case where a MITM hides the "secure" records from being seen on the client, and the client uses insecure DNS? (a variant of this hack)

2 Answers
2

DNSSec is normal DNS, but with signatures. It absolutely prevents DNS Spoofing; that's what it's for, and that's what it does.

Registrars can still theoretically abuse their position because they're responsible for communicating your intentions to the root servers. This includes information about your DNSSec keys. This relationship will never change; if you can't trust your registrar, then get a new registrar.

DNSSec doesn't prevent MITM attacks. It absolutely prevents DNS spoofing. But there are other ways of inserting yourself into a traffic flow than just DNS spoofing.

How it works

In essence, you tell your registrar your signing key's fingerprint by creating a DS record, and that information will be available from your TLD signed by an upstream key which chains in a like manner all the way to a single globally trusted key.

With this set up, your key is now considered to be the trusted authority for your domain, and is allowed to sign your DNS records. So now for each record in your zone, you create a corresponding RRSIG record which contains the associated digital signature.

Now, when someone looks up a domain in your zone, you can send not only the response, you can also send the corresponding RRSIG record as well which shows that the response was signed by you. To verify the signature, the client fetches your DNSKEY record which contains your full public key, and then just follows normal cryptographic signature verification techniques.

Obviously the DNSKEY record also has its own corresponding RRSIG record so that you can verify that it hasn't been tampered with. But more importantly, there is a DS record available from your parent zone (remember, you gave it to your registrar in the first paragraph) which contains enough information about your public key to verify that your DNSKEY record is actually authorized for your zone.

That DS record is, in turn, singed by your parent's DNSKEY, for which there is a corresponding DS record in the root zone. This way, all key signatures can be traced back to a single trusted source.

Problems

The complication comes when you need to tell someone that a record doesn't exist. Obviously that response needs to be signed, but generally the DNS server itself doesn't have access to your signing key and can't sign the response on-the-fly; the signatures are all created "offline" ahead of time. This keeps your key from being exposed if your DNS server gets compromised.

So instead, you alphabetize your subdomains and say "for every name between mail.example.com and pop.example.com, no other subdomains exist" and sign that assertion. Then when someone asks for nachos.example.com you can just give them that response (which has already been signed) and the client knows that because nachos.example.com falls alphabetically between mail.example.com and pop.example.com, then the "this domain doesn't exist" response is considered to be correctly signed and actually came from you.

The place where this becomes problematic is that by having a set of these negative responses which explicitly state that "no responses exist between X and Y, you can easily map out exactly which domains exist for the entire zone. You know that "X" exists, and you know that "Y" exists, and you know there is nothing else between them. Just do a little more poking at random and you'll quickly be able to compile a list of all the records that do exist.

Controversy

There are two camps in the DNS world with respect to whether or not this is a problem. The first group says:
"So what if people know what zones exist; DNS is public information. It was never meant to be a secret anyway."

To which the second group says:
"This is a security risk. If I have a server named accounting.example.com, then someone who intrudes on my network can quickly tell which machine has the juicy information on it and therefore which one to attack."

To which the first group then replies:
"Then don't call it that! If your entire security model is based on the concept of keeping public information secret, then you, sir, are an idiot."

To which the second group replies:
"It's not about keeping secrets, it's about not revealing more information than you have to."

And so on, ad nauseam.

DNS (and DNSSec) was designed largely by folks in the first camp; DNS is public, therefore being able to map out which subdomains exist in a domain isn't a significant security concern. And anyway, you can't really do signed negative responses any other way.

On the other hand, the servers tend to be run by people in the second camp. They're concerned about the safety of their own network, and they don't want to be giving away any more information than necessary, since they know that all information will eventually be used against them.

So you have a protocol is cryptographically sound and perfectly functional, but which real-world admins tend to be hesitant to implement.

We'll all get there eventually, I imagine. After all, DNS spoofing is more of a real-world concern than any dangers raised by mapping out subdomains. But change takes convincing. So here we are... still.

With vanilla DNS one can also easily probe for common hostnames like "accounting". NSEC3 only makes the process somewhat faster.
–
Sandman4Jun 24 '12 at 12:02

1

@tylerl Maybe I'm misunderstanding, but isn't that assuming the attacker is trying to forge a signed record? I'm talking about a downgrade attack, where the MITM just says "Hey client, there is no DNS signature for this record. This record doesn't support DNSSEC. Here's the plain old unsigned DNS record that I modified to say whatever I want." How would the client know that the record was supposed to be signed in the first place?
–
Ajedi32Feb 24 at 14:47

DNSSEC uses 2 keys: a key signing key (KSK), usually a long (2048 bits) key for enhanced security, and a zone signing key (ZSK) that is shorter for better performance. Since the ZSK is shorter it needs to be periodicaly changed, which means resigning your zones.

Some of the older DNSSEC tutorials just tell you to sign your zone and don't tell you that you need to regularly re-sign it, which usually results in your zone having invalid signatures after a week.

Modern authoritative name servers have built in support for generating a new ZSK and resigning zones. But the ones shipping with current distros may not do.

Personally I use ZKT for re-signing my zones, it's fine for small setups.

Authoritative name servers set the AA flag ("Authoritative Answer"), but validating resolvers set the AD flag ("AuthenticateD"), these flags are mutually exclusive. If you have any name servers that run in "hybrid" mode - that is that they do both recursion and serve zones for which they are authoritative then they will have to be split into the two different functions.

Not all registrars support publishing DS records to the root.

This isn't that big a deal since you can use the ISC's DLV service. Beware of EasyDNS, they support signing zones on there own nameservers but don't do anything with the DS records, which makes there DNSSEC support a bit useless.