Friday, September 16, 2011

Fix linux DNS issues with .local addresses on MS domain

B.L.U.F.:

Microsoft uses .local as the recommended root of internal domains, and serves them via unicast dns. Linux uses .local as the root of multicast dns. If you're stuck on a broken MS network like this, reconfigure your linux multicast DNS to use a different domain like .alocal.

To do this, add a "domain-name=.alocal" line to the "[server]" section of "/etc/avahi/avahi-daemon.conf", then restart avahi-daemon: "sudo service avahi-daemon restart".

#/etc/avahi/avahi-daemon.conf
[server]
domain-name=.alocal

You may need to flush the DNS,mDNS and resolver cache, as well as restart your web browsers to clear their internal cache.

Background.

I was seeing the strangest behavior on my work linux box. I could look up local addresses, but not contact them in my browser. Turns out I could look them up but not ping them, either.
% host foo
foo.corp.local is an alias for bar.corp.local
bar.corp.local has address 10.1.2.3

% host foo.corp.local
foo.corp.local is an alias for bar.corp.local
bar.corp.local has address 10.1.2.3

% ping foo -q -c 1
PING bar.corp.local (10.1.2.3) 56(84) bytes of data.

--- bar.corp.local ping statistics ---
1 packets transmitted, 1 recieved, 0% packet loss, time 0ms

% ping foo.corp.local
unknown host foo.corp.local
I spent a while thinking this was a resolver issue in /etc/resolv.conf, since I knew that was getting modified by the VPN. Everything was fine in the resolver. What I'd forgotten about was /etc/nsswitch.conf! The hosts line in /etc/nsswitch.conf put mdns4_minimal before dns AND set a reply of "NOTFOUND" from mdns to propagate back directly without hitting DNS.
# /etc/nsswitch.conf hosts line:
hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4
We could side-step the problem by removing mdns4_minimal from the hosts search path, but this will lead to potentially long dns timeouts from mistyped .local addresses. (Ok, that's not a very bad side effect, but still let's fix it correctly).

Dig a little deeper into .local and mdns, and you'll find Avahi. Avahi "facilitates service discovery on a local network via the mDNS/DNS-SD protocol suite," what Apple calls Bonjour or Zeroconf. They have a warning page about unicast .local DNS zones that gets to the crux of the problem : linux has mdns (multicast dns) support configured for .local, but Microsoft support suggests using .local with unicast DNS. The two don't get along at all.

mDNS/DNS-SD is inherently incompatible with unicast DNS zones .local. We strongly recommend not to use Avahi or nss-mdns in such a network setup. N.B.: nss-mdns is not typically bundled with Avahi and requires a separate download and install.
-- Avahi and Unicast Dot Local wiki page

Fixes:

  1. move avahi mdns from .local to a different name (e.g. .alocal)
  2. or Remove mdns from /etc/nsswitch.conf or remove mdns module.
For the former, add a domain-name=.alocal line to the [server] section of /etc/avahi/avahi-daemon.conf, then restart avahi-daemon: sudo service avahi-daemon restart.

If that doesn't work (and you restarted your browsers, with their insidious dns cache, right?) you can try removing mdns from the hosts entry in /etc/nsswitch.conf. replace this line:

hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4
with this line:
hosts: files dns
Links: