Solved FreeBSD 10 BIND host lookup error

I encountered an odd problem, that has to do with performing a simple hostname lookup on the server itself. The server will not lookup hostnames, that does not have a zone on the server. However, it does ping (and lookup) the same address. What is wrong? How is this even possible? The following example is the FreeBSD 10 in question.

Code:
# host google.dk
Host google.dk not found: 3(NXDOMAIN)
# ping google.dk
PING google.dk (216.58.209.227): 56 data bytes
64 bytes from 216.58.209.227: icmp_seq=0 ttl=53 time=108.368 ms
64 bytes from 216.58.209.227: icmp_seq=1 ttl=53 time=109.097 ms
64 bytes from 216.58.209.227: icmp_seq=2 ttl=53 time=108.031 ms
The following example is FreeBSD 9. This just works.

Code:
$ host google.dk
google.dk has address 216.58.209.227
google.dk has IPv6 address 2a00:1450:4009:80b::2003
google.dk mail is handled by 50 alt4.aspmx.l.google.com.
google.dk mail is handled by 30 alt2.aspmx.l.google.com.
google.dk mail is handled by 10 aspmx.l.google.com.
google.dk mail is handled by 40 alt3.aspmx.l.google.com.
google.dk mail is handled by 20 alt1.aspmx.l.google.com.

The two servers uses the same configuration of BIND and is hosted in the same data center.
 
I can add, that, if the FreeBSD 10 server is queried from a remote host, the response is correct.
 
I know, that it is a very common question; However, what does NXDOMAIN mean here? I read it as non-existant domain, which makes no sense here. Also, the manual for host does not mention this error - nor the possible reasons behind this error code.
 
NXDOMAIN is a connectivity issue.

1. Is forwarders set?
2. Is setting forwarders (like 8.8.8.8) fixes the issue?
3. Is named listening and allowed to receive inbound udp and tcp on 53 port?
4. Is named allowed to make outgoing connections to udp and tcp 53 port?
5. Is named listening interface you accessing locally?
6. Logs are your friends
Code:
logging {
channel default_file {
file "/var/log/named/default.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel general_file {
file "/var/log/named/general.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel database_file {
file "/var/log/named/database.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel security_file {
file "/var/log/named/security.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel config_file {
file "/var/log/named/config.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel resolver_file {
file "/var/log/named/resolver.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel xfer-in_file {
file "/var/log/named/xfer-in.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel xfer-out_file {
file "/var/log/named/xfer-out.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel notify_file {
file "/var/log/named/notify.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel client_file {
file "/var/log/named/client.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel unmatched_file {
file "/var/log/named/unmatched.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel queries_file {
file "/var/log/named/queries.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel network_file {
file "/var/log/named/network.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel update_file {
file "/var/log/named/update.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel dispatch_file {
file "/var/log/named/dispatch.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel dnssec_file {
file "/var/log/named/dnssec.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};
channel lame-servers_file {
file "/var/log/named/lame-servers.log" versions 3 size 5m;
severity dynamic;
print-time yes;
};

category default { default_file; };
category general { general_file; };
category database { database_file; };
category security { security_file; };
category config { config_file; };
category resolver { resolver_file; };
category xfer-in { xfer-in_file; };
category xfer-out { xfer-out_file; };
category notify { notify_file; };
category client { client_file; };
category unmatched { unmatched_file; };
category queries { queries_file; };
category network { network_file; };
category update { update_file; };
category dispatch { dispatch_file; };
category dnssec { dnssec_file; };
category lame-servers { lame-servers_file; };
};
 
Forwarders is set. It makes no difference, whether I use forwarders or root servers.

I tested 8.8.8.8 on top of the list. It makes no difference.

BIND should be listening and allowed to receive queries. This part also works; Hence, remote hosts can query - and do get a response.

BIND should be allowed to make outgoing queries. I use PF. I also tested the "pass all" rule. It makes no difference.

It makes no difference, if I manually configure BIND to listen to 127.0.0.1 and its local IP addresses.

I added your complete logging section and restarted BIND. After that, I re-tested my command, which still gives the NXDOMAIN error. There were no logging of this error in any of the logs. There were only logging of other unrelated queries.
 
None of the logs contains traces of my test - nor error.
Code:
# ls -la
total 90
drwxrwxrwx  2 root  wheel    512 30 dec 22:30 .
drwxr-xr-x  4 root  wheel   1536 30 dec 22:30 ..
-rw-r--r--  1 bind  wheel      0 30 dec 22:30 client.log
-rw-r--r--  1 bind  wheel      0 30 dec 22:30 config.log
-rw-r--r--  1 bind  wheel      0 30 dec 22:30 database.log
-rw-r--r--  1 bind  wheel      0 30 dec 22:30 default.log
-rw-r--r--  1 bind  wheel      0 30 dec 22:30 dispatch.log
-rw-r--r--  1 bind  wheel      0 30 dec 22:30 dnssec.log
-rw-r--r--  1 bind  wheel   7237 30 dec 22:30 general.log
-rw-r--r--  1 bind  wheel      0 30 dec 22:30 lame-servers.log
-rw-r--r--  1 bind  wheel      0 30 dec 22:30 network.log
-rw-r--r--  1 bind  wheel    839 30 dec 22:30 notify.log
-rw-r--r--  1 bind  wheel  40568 30 dec 22:37 queries.log
-rw-r--r--  1 bind  wheel      0 30 dec 22:30 resolver.log
-rw-r--r--  1 bind  wheel  36154 30 dec 22:37 security.log
-rw-r--r--  1 bind  wheel      0 30 dec 22:30 unmatched.log
-rw-r--r--  1 bind  wheel      0 30 dec 22:30 update.log
-rw-r--r--  1 bind  wheel      0 30 dec 22:30 xfer-in.log
-rw-r--r--  1 bind  wheel      0 30 dec 22:30 xfer-out.log
 
If I use dig, I see a warning about recursion. Could this give us a hint?
Code:
# dig @localhost google.dk

; <<>> DiG 9.9.6-P1 <<>> @localhost google.dk
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 20420
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;google.dk.            IN    A

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Tue Dec 30 22:47:36 CET 2014
;; MSG SIZE  rcvd: 38
 
Could it be a general problem with FreeBSD 10 and BIND?

I just ran the same test on another FreeBSD 10 server, that was just recently upgraded from version 9; It has the same error; It can not resolve host names locally. It can resolve for remote clients.

The reason, that I continued to use BIND is, that I could not get the new default Unbound to work for authorative domain name service. I also read, that Unbound had problems, when used for that. I believe, it was related to transfer queries.
 
I don't think it's a problem with FreeBSD 10 and BIND in general, because mine seems to work. But a difference between 9 and 10 that affects BIND, maybe. It might be worth comparing the stock named.conf from FreeBSD 9 with the one from 10 to see what changed. Is it the same version of BIND on both FreeBSD 9 and 10? Both installed from the port? Both running outside a chroot()?
 
I compared the two configurations.
The old server (9) is running BIND 9.8.1-P1. The new server (10) is running BIND 9.9.6-P1 (Extended Support Version). I believe, that BIND was installed per default on the old 9. However, I have updated it since default install. BIND on the new 10 has been installed from the new packaging system pkg.
There is no difference in the named.conf configuration - except of certain IP addresses. I use the default paths; 9 uses /etc/namedb and 10 uses the new /usr/local/etc/namedb. I am not using any jail nor chroot'ing.
 
BIND was in base on FreeBSD 9, and if you installed the port it had an option to overwrite base, or use those paths, and that would run in a chroot because the base one did. That might not be the problem, I'm just trying to think of differences.
 
Thanks. Do you think, that a PF misconfiguration could give that exact NXDOMAIN error message?
 
Bogus request have to be logged if you applied my logging suggestions. If it is not logged I assume the matter is a connectivity issue. Can you test host with the third parameter - your external IP and 8.8.8.8 ?
 
It has to be a mysterious connect issue. There is no trace in the logs. What is left to investigate, if PF can not cause NXDOMAIN?

Snip from the configuration.

Code:
forward only;

forwarders
{
  # Test
  8.8.8.8;

Searching the logs.

Code:
$ grep 8.8.8.8 /var/log/named/*
$
 
Are you using an "allow-query" query directive? If so is 127.0.0.1 part of what is allowed? That can absolutely cause queries to work on your LAN but not work when you query on localhost.

Additionally, the "REFUSED" and "NXDOMAIN" tell you that you are getting a response back. You shouldn't need to worry about a firewall at this point because you got an answer.

The reason, that I continued to use BIND is, that I could not get the new default Unbound to work for authorative domain name service. I also read, that Unbound had problems, when used for that. I believe, it was related to transfer queries.
Regarding this, take a look at upstream's site below and you'll see that "Unbound is a validating recursive caching resolver" and "NSD is an authoritative only, high performance, simple and open source name server". Unbound is simply not designed for authoritative duties and should be paired with NSD to handle authoritative duties.

http://www.nlnetlabs.nl/projects/unbound/
http://www.nlnetlabs.nl/projects/nsd/
 
I am using the allow-query directive.

Code:
allow-query
{
  any;
};

I can see, that you are right about the response. I was just in doubt, whether the NXDOMAIN came from the host command itself - or the name server. I actually contacted the writer of the manual for host and sent him this thread. I am not sure, if he will bother with this though.
 
I still wonder, why the ping command works, when the host command does not. Does this mean, that the ping command, and other programs, can resolve - but host can not? Could this give us a hint as to the cause of the problem?
 
I ran the dig command again - and noticed, that status is listed as refused.

Code:
# dig @localhost google.dk
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 53402
 
I think I found the solution to this issue.

I disabled the use for forwarding - and downloaded the list of root servers named.root instead.

Then, I added localhost to a list of whitelisted networks, that is allowed to do recursion.

I also added control for cache queries.

The response then changed status from NXDOMAIN to NOERROR - and gave correct answer. It does not seem to have affected the authoritive DNS (as retested with the external test tool MX Toolbox).

If I remove the localhost from the whitelist, then NXDOMAIN is back, which could confirm, that localhost has to be allowed recursion for the host command to function.

Code:
acl "whitelist"
{
  ...
  127.0.0.1;
  ...
};

...

allow-query { any; };
allow-recursion { whitelist; };
allow-query-cache { whitelist; };
allow-transfer { whitelist; };
 
The allow-recursion directive is what allows "recursive" queries to be served, without that permission BIND will only serve the domains it is authoritative for. This is independent of the forwarding setting, you can have a forwarding resolver as long as you allow the recursive queries for your clients.
 
Back
Top