Force forwarder DNS requests to TCP mode

Solution 1:

First, I would not call that an error, just an informational message.

Second, DNS servers will always answer UDP queries (BIND at least, I cannot find options to disable UDP) and clients will always (?) try to send a UDP query first (for example there are no options in resolv.conf to change that nor in the JVM) - if they fit in a UDP packet (requests usually do)

If you have a specific use case, you can specify to use TCP, e.g. in shell script use 'dig +tcp' or 'host -T' for resolution, and you can use system calls 'sethostent/gethostbyname/endhostent' (see man page) to force TCP in other cases.

If you really want to try and block UDP, the only option I can see is with an iptable rule, but I am not sure that that set up would work. I expect that DNS resolution would simply fail.

Solution 2:

Your BIND server should be using EDNS (see RFC 6891) to allow UDP packets longer than 512 bytes.

options {
    edns-udp-size 4096;
    max-udp-size 4096;
};

This should permit your large NS set to be retrieved over UDP, without requiring the overhead of a TCP connection for other smaller queries.

Note however that these are actually the default values. If EDNS isn't being used, either something is blocking it, or the servers receiving the EDNS options aren't supporting it.

Also, note that host doesn't support EDNS. It's perfectly possible that your forwarder -> server queries are already using EDNS, and you just can't see it when you try with your local client.

Try dig +bufsize=4096 @server hostname A instead of using host.