Looking up a name in the DNS system involves a set of questions and answers. One computer sends a question to a second, and the second replies with an answer. The first computer then acts on the information received. But can it trust the answer? Has a third-party (an “attacker”) tampered with the data? These are the concerns that DNSSEC addresses.
The problem arises in the way that DNS messages are exchanged. DNS uses UDP (“User Datagram Protocol”), which means that each DNS query and each DNS response is encapsulated in a single Internet packet. When a message is received, the only clue as to who sent the message is the IP address of the sender in the message itself. (The IP address is the “Internet Protocol Address” – essentially a number that uniquely identifies a computer on the Internet.) As there is no way to check that the information is authentic, it is possible for the IP address to be forged.
Forging a DNS response is not straightforward though, as DNS does have some in-built security. When an answer is received from a nameserver, the answer is only accepted by the questioner if:
Despite all the checking it is still possible for an attacker to forge an answer.
If the attacker has some way of knowing what query is being made and when it is sent, they can try flooding the questioner with responses. Since the question is known, the nameserver to which it is sent can be guessed (the identities of the nameservers are not secret). Until recently (see below), the port number was static, so the only truly uncertain component was the ID. So the attack sequence is (1) The attacker tricks the victim into sending out a known query (e.g. it may send an email with a fake “From:” address; the recipient’s spam filter will make a DNS query as it verifies the address). (2) The authoritative server replies but at the same time (3) the attacker sends a flood of fake responses, each with a different ID. If the attacker is lucky and successfully guesses the ID, and if it is able to get the forged response to the questioner before the authentic one, the questioner will believe the answer sent by the attacker.
Although it is possible to get an individual computer to believe an incorrect response, it is easier to trick a resolver: typically a client is behind a firewall and is inaccessible, whereas the resolver listens to responses from the Internet. It is also more profitable: if the attacker manages to get a resolver to believe the forged answer, the answer will be cached and the resolver will hand out the wrong information to all systems asking it the same question (this is known as “cache poisoning”).
Such control can be powerful and the potential for misuse is great. An obvious use of this is phishing: for example, directing traffic for an Internet banking portal to a system of the attackers choosing. Another is mail interception; if an attacker were to be able to cause a resolver to pick up the wrong address for a mail server, they could cause email sent to that server to be sent to them. (If they then subsequently delivered it to the intended destination, no-one would be any the wiser but the attacker could read and potentially alter confidential correspondence.)
These problems have been known about for some time, and it was to answer them that DNSSEC was designed. Even so, it was thought that the problem was small and the chance of spoofing remote. If nothing else, caching worked to reduce the window of opportunity: an attacker has only a small chance to get in a forged answer and, if they fail, the correct answer will be cached, typically for a period of a couple of days. The attacker must wait for the information to expire from the cache before trying again. Under these circumstances, an attack will take an infeasibly long time to succeed.
This belief was shattered in 2008 by Dan Kaminsky, an American security researcher. He discovered an attack that got round the limitations on the attempt rate set by caching. In laboratory conditions, it was possible to poison a cache in a few seconds! Dan Kaminsky responsibly alerted the authors of nameserver software and the software was updated to combat the bug by randomising the port used in the query. Effectively this means that each DNS query now has a number between zero and four billion associated with it. The change has made it much harder to spoof domain names, but not impossible. As computers become faster and information channels are able to carry data at a higher rate, attackers’ chances will improve. Fortunately DNSSEC is able to counter the new threat.
DNSSEC is a way of proving that the information received in response from a DNS query came from the nameserver authorised to return it, and was not modified in transit. It is based on public-key cryptography and digital signatures, so before we go any further, these technologies should be explained.
The classic picture of a secret message is one where both the sender and the recipient use a code book. Since the message is both encrypted and decrypted with the same key, the method is referred to as symmetric cryptography (also known as secret-key cryptography). The problem with this process is that it requires that the sender and recipient have been able to agree on a common key in some secure way before secret messages are exchanged. This is difficult if the parties have not met before, but not impossible.
Further problems come when an encrypted message has to be distributed to more than one person. If a separate key is used for each recipient, there is the overhead of key exchange (which can be insurmountable if the number of the recipients is in the millions). If the same key is used for each recipient, there are the problems of message security and authenticity. Since many people know the key, if one them intercepts a message sent to someone else, they could read it. They could also send a message pretending that it is from someone else; the mere fact that a received message is encrypted with a particular key no longer proves who sent it. (And these issues are quite apart from the difficulty that the more people that know the key, the less secure it is.)
Using public key cryptography overcomes these problems. In this scheme, two keys are used: a message encrypted with one can be decrypted with the other, and vice-versa. One key is known as the public key and is widely distributed; the other is the private key and is kept as secret as possible. The use of the system is illustrated by the example of Alice wanting to send a private message to Bob. To do this, she looks up Bob’s public key (on his web site perhaps) and encrypts the message with it. When Bob receives it, he decrypts it with his private key. No-one other than Bob – even those with a copy of his public key – can decrypt the message.
Note that Bob cannot confirm that the message came from Alice – it could have come from anyone who has a copy of his public key. But he does know that it has not been seen or altered in transit from the sender. In other words, the message is secret but not necessarily authentic. Conversely, if Alice had a pair of keys and sent Bob a message encrypted with her private key, then the fact that he can decrypt it with her public key proves it came from her. But in this case, anyone with her public key can also decrypt it, so the message is authentic but not necessarily secret. Sending a message that is both secret and can be authenticated requires use of both Alice’s and Bob’s keys.
Quite often though, a message is not secret but proof of authenticity is desired. For example, if I look up the address of the Nominet web site, the answer is not particularly sensitive, but I would like some assurance that the information has not been tampered with. From the preceding description, public key cryptography suggests itself – if the information I want were to be encrypted with a private key by the sender, I could decrypt it with a public key, so proving its authenticity.
Unfortunately, even with the fast computers of today, there is still significant overhead in encrypting data using public key cryptography (it is more compute-intensive that encryption using a symmetric key). But if I am not concerned about the security of the message, there is a faster solution using something known as the message digest.
The message digest is a number that is characteristic of the message, calculated according to a particular algorithm. Given a particular message I can calculate the digest, although the reverse is not true – given the digest I cannot recreate the message: the algorithms used give a number that is so large that (a) the chance of finding another message that will give the same digest is minuscule and (b) the chance that a message with the same digest will be anything other than a random string of bytes is even smaller. To all intents and purposes then, the digest is a unique fingerprint of the message.
The digest of a message can be calculated quite rapidly. As it is smaller than the message (for example, the SHA1 algorithm produces a digest that is 40 hexadecimal digits long, regardless of the size of the message), it is faster to encrypt. An encrypted digest is known as a digital signature and can be used in message authentication.
I create the digital signature of the message by calculating the digest and encrypting that with my private key, then send both the message and the signature to the recipient. The recipient calculates the digest of the message, and compares the answer with the number they obtain by decrypting the digital signature with my public key. If the figures match then: (a) the fact that they can successfully decrypt the signature with my public key proves it came from me and (b) the fact that the digests match prove that the message has not been altered in transit.
DNSSEC addresses the problem of proving that a DNS response is not forged. It does this by including in the response both the answer to the DNS query and the digital signature of that answer. As the digital signature of the answer is encrypted using the private key of the zone that supplied the answer, the fact that the digital signature matches the answer proves that the answer is authentic.
There still remains the question of distributing the public key of the zone. As it is not practical to require every system making DNS queries to be pre-configured with the keys of all possible zones, a simpler solution has been adopted: the public key is read from the zone itself via a DNS query.
Of course, if that were all there was to it, there would still be a gaping hole in security – if it were possible to forge a DNS response, it would be possible to forge the DNS response containing the public key. Should an attacker be able to get a system to believe that a key they controlled was the key of the zone, they could sign forged DNS responses with the private part of that key and get the victim to accept them as genuine.
To overcome this, DNSSEC validates the key by checking its message digest against the value held in the parent zone.
Supposing we look up the domain name www.nominet.org.uk:
In essence, there is a chain of trust: to trust www.nominet.org.uk, you need to trust nominet.org.uk. To trust that domain, you need to trust org.uk, and so on up to the root. If you trust the root (and if all zones are signed), you should be able to look up a domain name securely.