Do DNS queries always travel over UDP?

Solution 1:

Normal DNS queries use UDP port 53, but longer queries (> 512 octets) will receive a 'truncated' reply, that results in a TCP 53 conversation to facilitate sending/receiving the entire query. Also, the DNS server binds to port 53, but the query itself originates on a random high-numbered port (49152 or above) sent to port 53. The response will be returned to this same port from port 53.

Network Ports Used by DNS | Microsoft Docs

So, if you're planning on doing some security snooping on DNS queries from your network, you'll need to take the above into account.

As for non-lookup traffic, consider that DNS also uses zone transfers (query type AXFR) to update other DNS servers with new records. A man in the middle attack can begin with such a transfer, DDOS'ing a Primary name server so that it's too busy to respond to a Secondary asking for updated records. The hacker then spoofs that same Primary to feed 'poisoned' records to the Secondary, that redirect popular DNS domains to compromised hosts.

So your security audit should pay close attention to query type AXFR, and your DNS systems should only accept AXFR exchanges from specific IP addresses.

SANS Institute InfoSec Reading Room | sans.org

Solution 2:

This started as a comment to George's answer, but it got long. The larger picture is somewhat complicated, as it requires understanding some history.

  • RFC 1035 originally called for a limit of 512 bytes in order to avoid UDP fragmentation. Fragmented UDP datagrams and TCP were chosen as the options of last resort in order to minimize the overhead of DNS transactions. Zone transfers always use TCP, due to zone transfers taking up >512 bytes by their very nature. (it would be a waste of bandwidth to begin with UDP at all)

  • TCP retry on truncation is widely supported as it has been specified in RFC 1123 since 1989.

  • EDNS(0) is defined by RFC 6891 (2013), and before that existed as a Proposed Standard dating back to 1999. It defines a mechanism where clients and servers can negotiate UDP sizes greater than 512. Due to the newness of EDNS(0), many hardware appliances make assumptions about the structure of DNS packets that cause compliant packets to be discarded. The most frequent reason is an assumption that DNS messages of over 512 bytes are invalid, but this is one among several.

If we break that out into the observed behaviors:

  1. DNS queries usually start as UDP, unless it's known ahead of time that the reply will be too large to begin with. (zone transfers)
  2. The reply may trigger a TCP retry in the client if a truncated reply is seen. This is fairly well supported.
  3. A UDP reply of greater than 512 bytes may be seen if the client used EDNS(0) to advertise a larger payload, and the receiving server supports it. This will only happen if hardware sitting between the two does not interfere and result in a dropped or mangled packet.
  4. The client may elect to retry an EDNS(0) query with a smaller advertised payload if a reply is not seen, but specifics will vary between implementations.
    • It's important to note that the reply which finally makes it through may be too large to fit within the requested size, which results in behavior #2 above. (ye olde TCP retry)
    • The client side may choose to remember the size that finally resulted in a success. This allows it to avoid wasting unnecessary queries probing it out again. To do otherwise would be quite wasteful, particularly if the final result required TCP fallback.

You should also keep in mind that RFC 7766 allows for connection reuse over TCP, and it's possible to encounter query pipelining over TCP in the wild. Some tools do not detect DNS queries beyond the first seen in a TCP session, dnscap being an example of such.


Solution 3:

There is RFC 7766, DNS Transport over TCP - Implementation Requirements.

  1. Introduction

Most DNS [RFC1034] transactions take place over UDP [RFC768]. TCP [RFC793] is always used for full zone transfers (using AXFR) and is often used for messages whose sizes exceed the DNS protocol's original 512-byte limit. The growing deployment of DNS Security (DNSSEC) and IPv6 has increased response sizes and therefore the use of TCP. The need for increased TCP use has also been driven by the protection it provides against address spoofing and therefore exploitation of DNS in reflection/amplification attacks. It is now widely used in Response Rate Limiting [RRL1] [RRL2]. Additionally, recent work on DNS privacy solutions such as [DNS-over-TLS] is another motivation to revisit DNS-over-TCP requirements.

Section 6.1.3.2 of [RFC1123] states:

  DNS resolvers and recursive servers MUST support UDP, and SHOULD
  support TCP, for sending (non-zone-transfer) queries.

However, some implementors have taken the text quoted above to mean that TCP support is an optional feature of the DNS protocol.

The majority of DNS server operators already support TCP, and the default configuration for most software implementations is to support TCP. The primary audience for this document is those implementors whose limited support for TCP restricts interoperability and hinders deployment of new DNS features.

This document therefore updates the core DNS protocol specifications such that support for TCP is henceforth a REQUIRED part of a full DNS protocol implementation.

There are several advantages and disadvantages to the increased use of TCP (see Appendix A) as well as implementation details that need to be considered. This document addresses these issues and presents TCP as a valid transport alternative for DNS. It extends the content of [RFC5966], with additional considerations and lessons learned from research, developments, and implementation of TCP in DNS and in other Internet protocols.

Whilst this document makes no specific requirements for operators of DNS servers to meet, it does offer some suggestions to operators to help ensure that support for TCP on their servers and network is optimal. It should be noted that failure to support TCP (or the blocking of DNS over TCP at the network layer) will probably result in resolution failure and/or application-level timeouts.


Solution 4:

You should not filter TCP/53 in any direction. For example, nsupdate queries may use TCP as soon as the request is too big (which can happen fast). So you should let UDP and TCP for port 53 (in IPv4 & V6 !) flow in all directions.

Also there is more and more work towards DNS over TLS, so TCP will be needed in both directions. See RFC7858.