Set DNS server on OS X even when without internet connection

domain-name-systemmac-osxresolv.conf

I have installed, configured DNS server(local instance of Dnsmasq) which resolves to localhost as I want, all OK.

When I go offline, it stops working, because OS X empty content of resolv.conf and ignore attempt to reflect changes in this file.

Any idea, how to configure DNS even when offline?

Similar issue(unresolved): http://blog.steamshift.com/geek/leopard-lookupd-and-local-web-development-sites

Main motivation is ease development of RoR application which uses subdomains as account keys. And you can not use 127.0.0.1 *.yourapp.local in /etc/hosts. Some guy registered domain smackaho.st and srt DNS for it like .smackaho.st at 127.0.0.1 but still, you can not use it when you are working offline.

EDIT: tried scutil command, but it seems you can change DNS if offline

NOTE: when you have all interfaces down, you cannot set DNS servers in Pref. panel.

Best Answer

SEE UPDATE BELOW!

I also enjoy using Dnsmasq on my local machine, and I had this problem too. Here is the solution:

From man 5 resolver:

The configuration for a particular client may be read from a file
having the format described in this man page. These are at present
located by the system in the /etc/resolv.conf file and in the files
found in the /etc/resolver directory.

/etc/resolver/ is not present by default; you must create it yourself.

Also from the man page:

domain
  Domain name associated with this resolver configuration. This
  option is normally not required by the Mac OS X DNS search system
  when the resolver configuration is read from a file in the
  /etc/resolver directory. In that case the file name is used as the
  domain name.

So if you wanted all dns queries for the top level domain of dev to be routed to the local nameserver, you would:

# mkdir /etc/resolver
# echo 'nameserver 127.0.0.1' > /etc/resolver/dev

configd does not alter files in /etc/resolver/, so this setting will persist through network changes and reboots.

UPDATE 17 July 2012

Unfortunately, as of OS X Lion, the top resolver (as shown by scutil --dns) disappears when no interfaces are active:

# scutil --dns # Online
DNS configuration

resolver #1
  nameserver[0] : 127.0.0.1

...

resolver #8
  domain   : dev
  nameserver[0] : 127.0.0.1

# scutil --dns # Offline
DNS configuration

resolver #1

...

resolver #8
  domain   : dev
  nameserver[0] : 127.0.0.1

Notice that resolver #1 is empty, but that the /etc/resolver derived nameserver entry remains.

It turns out that since you can specify the resolver domain directly in the /etc/resolver/ file, specifying the special Internet root domain . causes the creation of a global resolver entry that looks like:

resolver #8
  nameserver[0] : 127.0.0.1

Now all DNS queries are routed to localhost, even when offline.

Of course, you will still have to resolve your chosen domains as 127.0.0.1 using something like dnsmasq's --address option:

# dnsmasq --address=/dev/127.0.0.1

In summary:

  • Set all your network interface dns servers to 127.0.0.1:
    networksetup -setdnsservers Ethernet 127.0.0.1
    networksetup -setdnsservers Wi-Fi 127.0.0.1
    ...
  • Create a file /etc/resolver/whatever:
    nameserver 127.0.0.1
    domain .
  • Set up a local DNS server and be happy.

cf. http://opensource.apple.com/source/configd/configd-395.11/dnsinfo/dnsinfo_flatfile.c