Use the .dev TLD locally the easy way

You know, there are times where developing on your local box is much nicer than on a remote box. Sure, OS X has this nice ~/Sites/ directory. We could just create a sub folder for each project and we are almost ready to go. Start up apache/nginx/whateverwwwserver and we are ready to go.

But to be honest, I like to have a domain for each project and don't have to fiddle with subdirectory settings in various locations and submodules.

I think .dev is really nice for this purpose. At the moment (winter of 2015) we could improvise a quick hack. Add 127.0.53.53 to your lo0/lo device, let your web server listen to it and everthing.dev myblog.dev and really.everything.dev would load correspondent local virtual host.

Why this works? Google fetched .dev and until it has total control over the gTLD ICANN answers all request to *.devwith 127.0.53.53 .

Okay now for a serious solution..
First I hope you have already installed homebrew. If not head over to brew.sh and install it, I will wait here until you are finished.

We will use unbound DNS server for this experiment. As a nice side effect you can use it to run your own local fast and uncensored DNS server.

So finally let's get going..

brew install unbound

sudo mkdir /etc/resolver
sudo echo "nameserver 127.0.0.1" > /etc/resolver/dev

cd `brew --prefix`
vim etc/unbound/unbound.conf

The fist line should be self explaining.. In lines 2 and 3 we create the /etc/resolver directory and create a file for the .dev tld. If you are unsure consult the resolver(5) manpage.

OS X now asks our local name server for every request to a .dev domain. But right know it will just ask an authoritative name server for the record instead of answering it itself. That's why the last line directs you into vim, please choose your own loved editor for this.

Add the following to lines:

local-zone: "dev." redirect                                                   
local-data: "dev. 600 IN A 127.0.0.1"

This will finally redirect all request to *.dev to 127.0.0.1.

To finish we have to start unbound and while we are on it we set it up as a launch daemon that will be started at boot time.

sudo cp -fv /usr/local/opt/unbound/*.plist /Library/LaunchDaemons
sudo chown root /Library/LaunchDaemons/homebrew.mxcl.unbound.plist
sudo launchctl load /Library/LaunchDaemons/homebrew.mxcl.unbound.plist

If you execute scutil --dns you should see something like this:

..
resolver #11
  domain   : dev
  nameserver[0] : 127.0.0.1
  flags    : Request A records, Request AAAA records
Reachable, Local Address, Directly Reachable Address
..

Or just dig a random .dev domain.

$dig neverletyoudown.dev

; <<>> DiG 9.8.3-P1 <<>> neverletyoudown.dev
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 13796
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;neverletyoudown.dev.           IN      A

;; ANSWER SECTION:
neverletyoudown.dev.    600     IN      A       127.0.0.1

;; Query time: 376 msec
;; SERVER: 149.154.159.12#53(149.154.159.12)
;; WHEN: Sat Dec 12 15:35:58 2015
;; MSG SIZE  rcvd: 53

If it doesn't work look at first if the process is running.

$ ps aux | grep unbound
nobody          41264   0.0  0.0  2471776   2320   ??  Ss    2:54PM   0:00.06 /usr/local/opt/unbound/sbin/unbound -d -c /usr/local/etc/unbound/unbound.conf

If it isn't running check the Console.app for error messages from unbound.

If it is running ask the name server directly to resolve a domain.

$ dig neverletyoudown.dev @127.0.0.1
...
;; QUESTION SECTION:
;neverletyoudown.dev.           IN      A

;; ANSWER SECTION:
neverletyoudown.dev.    600     IN      A       127.0.0.1
...

If this isn't working then OS X was a little bit lazy while recognizing the configuration change. You can wait, reboot or just try to disable/enable your network interface.

When it works you basically are not required to touch the configuration ever again. Every .dev domain is redirected to 127.0.0.1. Or at least until Google uses the gTLD for something useful and we all have to make up a new tld..