NOERROR response for not exist domain breaks nslookup

Related to Why does Cloudflare's name servers return NOERROR rather than NXDOMAIN?

Cloudflare return NOERROR instead of NXDOMAIN for invalid domain. This breaks nslookup if you have ‘search’ set in the /etc/resolv.conf and the search domain is managed by Cloudflare. It’s easy to demonstrate in both debian:10.4 and alpine:3.11.6(with bind-tools installed) docker images.

# cat /etc/resolv.conf
nameserver 1.1.1.1
search cloudflare.com
options ndots:5

# nslookup google.com
Server:		1.1.1.1
Address:	1.1.1.1#53

Non-authoritative answer:
*** Can't find google.com.cloudflare.com: No answer

If the search domain is not managed by Cloudflare, for example google.com, nslookup can get the IP correctly.

# cat /etc/resolv.conf
nameserver 1.1.1.1
search google.com
options ndots:5

# nslookup google.com
Server:		1.1.1.1
Address:	1.1.1.1#53

Non-authoritative answer:
Name:	google.com
Address: 74.125.200.138
Name:	google.com
Address: 74.125.200.100
Name:	google.com
Address: 74.125.200.101
Name:	google.com
Address: 74.125.200.102
Name:	google.com
Address: 74.125.200.139
Name:	google.com
Address: 74.125.200.113
Name:	google.com
Address: 2404:6800:4003:c02::71

It also breaks some language runtime like node:14-alpine.

/ # cat /etc/resolv.conf 
nameserver 1.1.1.1
search cloudflare.com
options ndots:5
/ # node
Welcome to Node.js v14.2.0.
Type ".help" for more information.
> dns.lookup('google.com', {}, (err, addresses) => console.log('addresses: %j', addresses));
GetAddrInfoReqWrap {
  callback: [Function (anonymous)],
  family: 0,
  hostname: 'google.com',
  oncomplete: [Function: onlookup]
}
> addresses: undefined

The ndots:5 option is the default settings in Kubernetes cluster. So why Cloudflare return NOERROR instead of NXDOMAIN?

2 Likes

If you have ever enabled DNSSEC of your domain, Cloudflare will use a “Black Lies” strategy to return a NOERROR response instead of NXDOMAIN for non-existent domain. They have a blog to describe this strategy: Economical With The Truth: Making DNSSEC Answers Cheap .

Unfortunately this NOERROR response breaks the resolve function of several language runtimes in Alpine distribution. I’ve test it in node:14-alpine and python:3.7-alpine:

# cat /etc/resolv.conf
nameserver 1.1.1.1
search cloudflare.com
options ndots:5

/ # node
Welcome to Node.js v14.2.0.
Type ".help" for more information.
> dns.lookup('google.com', {}, (err, addr) => console.log('addresses: %j', addr));
GetAddrInfoReqWrap {
  callback: [Function (anonymous)],
  family: 0,
  hostname: 'google.com',
  oncomplete: [Function: onlookup]
}
> addresses: undefined

/ # python
Python 3.7.7 (default, Apr 24 2020, 22:09:29) 
[GCC 9.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket
>>> socket.gethostbyname('google.com')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
socket.gaierror: [Errno -2] Name does not resolve

Even if you disable DNSSEC in Cloudflare’s DNS app. The DNSKEY record is not deleted(dig DNSKEY youdomain.com @1.1.1.1). And you still get the NOERROR response.

Cloudflare has released a new API to delete the DNSSEC record manually: Cloudflare API v4 Documentation

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.