1.1.1.1 and wpad.localhost


#1

I switched over to 1.1.1.1 on my PC a week ago. Today while doing website development on my local machine, the hostname for some reason changed from a custom hostname I use which resolves to 127.0.0.1 to www.wpad.localhost which I’ve never seen before.

Running a ping to wpad.localhost resolved to ::1. I then ran nslookup on wpad.localhost and the 1dot1dot1dot1.cloudflare-dns.com server resolved wpad.localhost to ::1 and 127.0.0.1. I switched to 8.8.8.8 and it does not recognize wpad.localhost, nor does mxtoolbox.com.

My questions are… why is 1.1.1.1 resolving wpad.localhost to ::1 and 127.0.0.1 whereas Google 8.8.8.8 does not. And not so much a question, but I’m not sure why I suddenly got switched over from my normal custom hostname to wpad.localhost… is it related to Cloudflare 1.1.1.1 DNS or an unrelated reason. The timing is a little suspicious given that I’ve worked with the custom hostname/website for years without seeing this and it came up a week after switching to 1.1.1.1 DNS.

Thanks,
Ben


#2

It could be that your ISP is interfering. I suggest running a traceroute 1.1.1.1.


#3

Yes I suppose it could be my ISP interfering. traceroute 1.1.1.1 shows it goes through 6 of my ISP’s routers then reaches 1dot1dot1dot1.cloudflare-dns.com. Not sure how to tell if there’s any interference from these results.

Running an nslookup for wpad.localhost via 1.1.1.1 on a different network I RDP’d into, it does not resolve (whereas it does resolve on my machine). Back on my normal network, if I run an nslookup through my ISP’s DNS server, wpad.locahost does not resolve. So so far wpad.localhost is only resolving to ::1 and 127.0.0.1 when using 1.1.1.1 on my normal network.

At this point, I think I’m more concerned / intrigued on how I ended up at www.wpad.localhost in the first place, and whether it’s related to the 1.1.1.1 DNS service. Later I will switch back to 1.1.1.1 for DNS and see if I’m able to reproduce this.


#4

1.1.1.1 really does have A and AAAA records for localhost and *.localhost, apparently.

$ dig @1dot1dot1dot1.cloudflare-dns.com mnordhoff.localhost aaaa

; <<>> DiG 9.10.3-P4-Ubuntu <<>> @1dot1dot1dot1.cloudflare-dns.com mnordhoff.localhost aaaa
; (4 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36946
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1536
;; QUESTION SECTION:
;mnordhoff.localhost.           IN      AAAA

;; ANSWER SECTION:
mnordhoff.localhost.    900     IN      AAAA    ::1

;; Query time: 0 msec
;; SERVER: 2606:4700:4700::1001#53(2606:4700:4700::1001)
;; WHEN: Tue Apr 10 11:45:35 UTC 2018
;; MSG SIZE  rcvd: 76

So the DNS records are real…

But it doesn’t explain why your client made the queries.

Edit: It was probably part of the recursive DNS server software’s default configuration. There’s a draft proposal to change that, but it’s a typical configuration now.


#5

Any correctly designed resolver should return a valid loopback address for requests to localhost:

"When a name resolver receives an address (A or AAAA) query for localhost, it should return the appropriate loopback addresses, and negative responses for any other requested record types. Queries for localhost should not be sent to caching name servers.

To avoid burdening the Domain Name System root servers with traffic, caching name servers should never request name server records for localhost, or forward resolution to authoritative name servers." (from https://en.wikipedia.org/wiki/Localhost)

It is a bit less common to include all subdomains under localhost, but this is nonetheless valid and useful in certain cases.

8.8.8.8 is responding incorrectly as it seems to query the public roots, 4.2.2.2 returns a response for localhost but not subdomains under (which is correct), 9.9.9.9 and 1.1.1.1 include subdomains (which is also correct).

tl;dr: This is correct behaviour, and your client shouldn’t be querying wpad.localhost off your network, you should be using a valid internal domain (or for localhost, the requests should not be sent to an external resolver).


#6

It’s going a bit far to say that 8.8.8.8 is responding incorrectly—the actual RFC 6761 text merely says that it “should” return loopback answers for A/AAAA queries, not that it “must.” I agree that current behavior by 1.1.1.1 is correct—but there are multiple possible correct approaches, including the response given by 8.8.8.8.

One of the problems with returning loopback A/AAAA records is that they cannot be validated with DNSSEC. There is no insecure delegation for localhost (it simply doesn’t exist in the root zone) and the loopback records cannot be signed without the root zone private keys, which are very strictly controlled. This is a concern, but does not mean that providing loopback A/AAAA record answers (as done by many public DNS servers, including those that validate DNSSEC themselves, like 1.1.1.1, 9.9.9.9, and 64.6.64.6) is incorrect—the RFC says that clients “should not send queries for localhost names to their configured caching DNS server(s)”—so if they get an answer that they cannot validate it is arguably their own fault.

However, if we look at the real motivation for these requirements, which is “to avoid unnecessary load on the root name servers and other name servers” an argument can be made that the response by 8.8.8.8 is more effective than many of the others.

It should first of all be noted that both 8.8.8.8 and 1.1.1.1 implement RFC 8198 (Aggressive Use of DNSSEC-Validated Cache) to synthesize negative responses (such as NXDOMAIN) from NSEC records returned in DNSSEC-enabled responses, which significantly reduces the query load on the root name servers for any non-existent name, not merely those that have special consideration in RFC 6761. So although it is true that 8.8.8.8 may sometimes query the root name servers for localhost, it will only do so very rarely, either returning a cached negative response from traditional RFC 2308 negative caching or synthesizing one from the NSEC and SOA records it would have received from the root name servers for queries for any domain (such as elevator.lobby) between LOANS and LOCKER.

It’s instructive to look at a full response from 8.8.8.8 in this case:

$ dig +nocmd +noquestion +dnssec +nocrypto localhost @8.8.8.8
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 29085
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 6, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 512
;; AUTHORITY SECTION:
.			42439	IN	SOA	a.root-servers.net. nstld.verisign-grs.com. 2018041700 1800 900 604800 86400
.			42439	IN	RRSIG	SOA 8 0 86400 20180430050000 20180417040000 39570 . [omitted]
.			42439	IN	NSEC	aaa. NS SOA RRSIG NSEC DNSKEY
.			42439	IN	RRSIG	NSEC 8 0 86400 20180430050000 20180417040000 39570 . [omitted]
loans.			42439	IN	NSEC	locker. NS DS RRSIG NSEC
loans.			42439	IN	RRSIG	NSEC 8 1 86400 20180430050000 20180417040000 39570 . [omitted]

;; Query time: 21 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Wed Apr 18 03:13:39 EDT 2018
;; MSG SIZE  rcvd: 1030

The last NSEC record (with its RRSIG) proves the non-existence of localhost (the previous NSEC proves that there is no root wildcard). The SOA of the negative response—with a TTL of 42349, it is close to the median and smaller than SOA MIN of 86400—shows that it can be cached for a bit more than 11 hours 45 minutes; the answers from root name servers have an original TTL of one day. As a result (barring restarts), the number of queries to all root name servers for all the names between LOANS and LOCKER together will not exceed one per day for each 8.8.8.8 resolver. And the cache lifetime of up to 24 hours for localhost queries applies to clients of 8.8.8.8 regardless of whether DNSSEC is used or not.

By comparison, the positive responses from other resolvers mostly have shorter TTLs:

$ dig +noall +answer +auth +dnssec +crypto localhost @1.1.1.1
localhost.		900	IN	A	127.0.0.1
$ dig +noall +answer +auth +dnssec +crypto localhost @9.9.9.9
localhost.		10800	IN	A	127.0.0.1
$ dig +noall +answer +auth +dnssec +crypto localhost @64.6.64.6
localhost.		10800	IN	A	127.0.0.1
$ dig +noall +answer +auth +dnssec +crypto localhost @4.2.2.2
localhost.		86400	IN	A	127.0.0.1
$ dig +noall +answer +auth +dnssec +crypto localhost @resolver1.opendns.com
localhost.		604800	IN	A	127.0.0.1

It’s probably not an accident that the OpenDNS public resolvers (which handle queries from almost 1% of all DNS clients) return the largest TTL of all. Since the volume of localhost queries received by public resolvers can easily make it into the top-10 TLDs by query volume, trying to get clients to cache the responses for longer can make a non-negligible difference in the total query load (although it seems unlikely many clients will actually cache anything for a whole week).

It also may be, though it’s hard to prove, that the NXDOMAIN responses returned by 8.8.8.8 have some deterrent effect on clients who might otherwise send localhost queries (and get loopback addresses) rather than handle them internally. This is the motivation for the Internet Draft RFC “Let ‘localhost’ be localhost”. Time will tell whether that argument sways the IETF sufficiently to make it an official RFC.


#7

The resolver answers locally for all RFC1918 and RFC6303 and for private zones and special use domain names as in https://www.iana.org/assignments/locally-served-dns-zones and https://www.iana.org/assignments/special-use-domain-names/special-use-domain-names.xhtml