DNSCurve: Usable security for DNS | ||||||
| ||||||
DNSCurve for DNS software authorsYou're the author of a DNS cache: software to "resolve" DNS names, talking to DNS servers around the Internet. Here's how to add support for DNSCurve to your software, adding link-level public-key protection to DNS packets.When you're about to contact a DNS server, check the DNS server name to see whether it contains a correctly formatted DNSCurve public key. If it does, you can and should encrypt and authenticate the packets that you send to the server. For example, when you're about to contact the DNS server ns1t.nytimes.com for the zone nytimes.com, go ahead and send packets the way you normally do: the name ns1t.nytimes.com does not contain a DNSCurve public key. However, when you're about to contact the DNS server uz5xgm1kx1zj8xsh51zp315k0rw7dcsgyxqh2sl7g8tjg25ltcvhyw.nytimes.com for the zone nytimes.com, encrypt and authenticate your packets; this name does contain a DNSCurve public key. You need your own DNSCurve secret key and a corresponding DNSCurve public key. You can generate these when your program starts and then reuse the keys for talking to any number of servers. You also need, for each outgoing DNSCurve packet, a 96-bit nonce. Nonce means "number used once." Once you have used a particular nonce to encrypt a packet, you must never use the same nonce to encrypt another packet. This requirement is essential for cryptographic security, and lasts as long as you are continuing to use the same secret key. You can, for example, choose the nonce as a simple counter: 1 for the first packet, 2 for the second packet, etc. However, it is better to choose the nonce as a 64-bit counter followed by a 32-bit cryptographically generated random number; then blind attackers will have more trouble consuming your CPU time. It is even better to increase the counter to, e.g., the number of nanoseconds that have passed since the standard C epoch in your local clock, so that the current value of the counter does not leak your traffic rate. Do not decrease the counter if the clock jumps backwards! What you send to the server, instead of the original packet, is an expanded packet containing
What you receive back from the server will also be an expanded packet containing
If the opening fails, the packet is forged; discard the packet and continue waiting for packets from the legitimate server. If the opening succeeds, inside the box you will find the original response packet; handle the packet exactly the same way that you would handle a normal DNS response packet. Software details: Base-32 encodingSometimes DNSCurve communicates byte strings inside DNS query names. A byte string is interpreted as a number in little-endian form. Each 5-bit sequence of this number, from least significant to most significant, is encoded as one of the standard "digits" 0123456789bcdfghjklmnpqrstuvwxyz. A final sequence of fewer than 5 bits is zero-extended before encoding. Decoders must accept BCDFGHJKLMNPQRSTUVWXYZ as synonyms for bcdfghjklmnpqrstuvwxyz.For example, the two-byte string with bytes 0x64,0x88 (i.e., 100,136 decimal) is interpreted as the integer 0x8864 (i.e., 34916). The bits 1000100001100100 of this integer are divided into 5-bit parts 00100, 00011, 00010, 00001, which in turn are encoded as 4, 3, 2, 1. The original string is therefore encoded as the string 4321. Design notes: Base 36 would be slightly more compact than base 32, for example encoding 255 bits as 50 bytes instead of 51 bytes, but this savings is outweighed by the simplicity of base-32 encoding. Decoding of uppercase protects against the possibility of intermediate firewalls changing lowercase to uppercase. RFC 1034 clearly requires case preservation ("When you receive a domain name or label, you should preserve its case. The rationale for this choice is that we may someday need to add full binary domain names for new services") but this requirement was reportedly violated by some of the google.com DNS servers until recently and perhaps is also violated by some firewalls. In theory, DNS can also use non-alphanumeric names, allowing considerably shorter encodings of public keys. However, in practice, non-alphanumeric names would cause trouble with DNS web interfaces, DNS databases, etc., reducing usability. Software details: DNSCurve public keysDNSCurve public keys are 32-byte strings. These strings represent 255-bit numbers in little-endian form; the last byte is always between 0 and 127.When a DNSCurve public key is communicated as part of a DNS server name it is first encoded as a 54-byte alphanumeric string. The first 3 bytes are the magic string uz5. The remaining 51 bytes are the base-32 encoding of the 255-bit public key (i.e., the 52-byte base-32 encoding of the 32-byte public key, with the final 0 removed). To recognize a DNSCurve public key inside a DNS name, check each component of the name (after conversion from uppercase to lowercase) to see whether the component is
Design notes: The name testingalongservernamewithdigits0123456789andlettersyz.ns.dnscurve.org has been successfully registered with a popular .org registrar. Presumably there will be some registrars with length limits causing trouble for some users, but those users can switch to registrars with higher length limits, and in any case it should be easy for registrars (and, if necessary, registries) to raise their limits. Software details: Expanded DNS query formatDNSCurve servers are required to set aside a 4096-byte buffer for receiving a query packet. DNSCurve servers are required to accept two different formats for expanded DNS query packets: the "streamlined" format and the "TXT" format. DNSCurve servers are also required to accept normal DNS queries.An expanded query packet in TXT format is, from the perspective of the original DNS protocol, a DNS TXT query packet. It has the following bytes:
An expanded query packet in streamlined format has the following bytes:
Design notes: In theory, a DNSCurve client is free to send all expanded query packets in streamlined format. The DNSCurve server has announced its capabilities; the DNSCurve client knows that the server can handle more than the original DNS protocol. However, in practice, clients are sometimes run behind firewalls that reject new packet formats addressed to or from port 53. Those clients are forced to use the TXT format instead. In some cases those clients are also forced to choose the "zero or more additional components" as the name of the zone served by this server. These constraints consume extra network traffic while reducing confidentiality, so the streamlined format is preferred, but some administrators will be forced to configure clients to use the TXT format. More complicated query encodings, for example using OPT records, would respect the 255-byte RFC 1035 limit. However, OPT records in query packets are expected to be less likely to pass through firewalls than names exceeding 255 bytes. The "compression" in the standard DNS packet format is better than nothing, from a space perspective, but obviously can be improved; it would be easy to design more compact formats for the same information. DNSCurve could re-encode the original DNS packet in a more compact format before putting the packet into a cryptographic box. However, this re-encoding would force DNSCurve implementations to inspect the original DNS packet rather than simply passing it along as an uninterpreted string. Software details: Expanded DNS response formatWhen a DNSCurve server receives an expanded DNS query packet in streamlined format it is required to use streamlined format for the expanded response packet. When a DNSCurve server receives an expanded DNS query packet in TXT format it is required to use TXT format for the expanded response packet.An expanded response packet in TXT format is, from the perspective of the original DNS protocol, a DNS TXT response packet. It has the following bytes:
An expanded response packet in streamlined format has the following bytes:
Software details: UDP and TCPIf a normal DNS response packet is larger than 512 bytes then the server replaces it by an explicitly truncated packet. The client then tries again through TCP. Servers are not required to support TCP if no responses are above 512 bytes; clients are permitted to try TCP only if the server has explicitly indicated truncation.DNSCurve does not require TCP support from servers that were not already supporting TCP. If the original DNS response packet is at most 512 bytes then the server is permitted to send the expanded response packet as a UDP packet. DNSCurve clients are required to set aside a 4096-byte buffer for receiving a UDP response packet. If the original DNS response packet is above 512 bytes then it is replaced by an explicitly truncated packet and the truncated packet is protected by DNSCurve. In this case the client tries again by TCP, sending its DNSCurve query packet through TCP and receiving the DNSCurve response through TCP. TCP is considerably more expensive for clients and servers than UDP is, and TCP has no protection against denial of service, so server administrators are advised to stay below 512 bytes if possible. DNSCurve adds some denial-of-service protection for UDP but cannot do anything to help TCP. |