RSS
 

Running a local wildcard DNS server on your mac

12 Jun

Ever since I’am using my macbook pro with XAMPP as my primary development workhorse, i’ve been playing around with the hosts file every single time I started a new project. Until last week, where i suddenly realized that it was a rather stupid practice. After all i’am running a system that comes preinstalled with named. Yeah i know, a bit late… But still, sat down for a few minutes to (re-)read about zone files and how to get an wildcard DNS server up and running.

The goal was to have *.dev.local pointing to 127.0.0.1 so i only needed to add/alter my apache vhosts.conf to fit my project needs.

small hint upfront, # means a single line in your shell followed by a enter, and keep the terminal opened till the end.

Step 1

Open your terminal and use the ‘sudo bash’ command to become the super user, not really needed but I do hate typing sudo before every command. After becoming root, generate a new rndc.key

#su -
#rndc-confgen -a -c /etc/rndc.key

Step 2

Creating the actual zone file for your  .dev.local segment. I’am using textmate as editor on my mac, but you can use any other you like. If your OSX installation is still virgin, substitute mate with nano in the following lines

#mate /var/named/db.dev.local

An empty file should be opened, now drop the zone config in it and save it.

dev.local. 7200    IN       SOA     dev.local. root.dev.local. (
					2008031801 ;    Serial
					15      ; Refresh every 15 minutes
					3600    ; Retry every hour
					3000000 ; Expire after a month+
					86400 ) ; Minimum ttl of 1 day
dev.local. IN      NS      dev.local.
dev.local. IN      MX      10 dev.local.
dev.local. IN      A       127.0.0.1
*.dev.local.	IN      A       127.0.0.1

Please note the trailing dot  after the local! If you want your wildcard DNS to be something else, feel free to substitute it with something else. But keep in mind the trailing dot!

Step 3

Adding the zone to your named config

#mate /etc/named.conf

Locate a section that starts with ‘zone “0.0.127.’ and insert the  pointer to the freshly created zone file in between the 0.0.127 and logging zone.

added "/etc/named.conf"
zone "dev.local" IN {
        type master;
        file "/var/named/db.dev.local";
};
So you end up with a zone file looking a bit like this
zone "." IN {
        type hint;
        file "named.ca";
};

zone "localhost" IN {
        type master;
        file "localhost.zone";
        allow-update { none; };
};

zone "0.0.127.in-addr.arpa" IN {
        type master;
        file "named.local";
        allow-update { none; };
};

zone "dev.local" IN {
        type master;
        file "/var/named/db.dev.local";
};

logging {
        category default {
                _default_log;
        };

        channel _default_log  {
                file "/Library/Logs/named.log";
                severity info;
                print-time yes;
        };
};

Step 4

Firing the whole shabam up :)

Test if the config is right

#named-checkconf /etc/named.conf

If it returns an error, solve it with logic. Most likely a typing error :)

Check if the zone is created correctly

#named-checkzone dev.local /var/named/db.dev.local

that should return something simular to this

/var/named/db.dev.local:7: using RFC1035 TTL semantics
zone dev.local/IN: loaded serial 2008031801
OK

Once again if it fails, fix it using logic. Check for typing errors, first time i forgot one  those dreaded trailing dots

Finally adding it to your mac’s startup list, purely for convenience. If you are a memory freak feel free to start the named server only when needed, but i’am lazy and do not want to be bothered with it every single time i reboot. Which is about 4 times a year ;)

#launchctl load -w /System/Library/LaunchDaemons/org.isc.named.plist

Step 5

The last part, tell your DNS config to use your local DNS before checking the big net for your domain.

Flush your systems DNS cache

#dscacheutil -flushcache

You can safely close the super user shell now, we are done using our superpowers. Keep the shell open, cause the final test is done in a normal user shell.

Open your system preferences,and click network,  then advanced button.
If needed add 127.0.0.1 to your server list with the + on left  and drag it to the top of the list. The other two DNS entries are pointers i created to opendns because my ISP is not that good at running fast responding DNS servers.

OSX DNS config

Do not set the search domain to the same name as your wildcard dns name, or you will end up looking at your local web server for every failed DNS lookup ;)

After pressing the OK button a few times, the final step is testing if it actually works

Final step

Testing if your new zone is dig’able

#dig myzone.dev.local

where  myzone can be anything you want, cause well hey we are running a wildcard DNS here. The response should look a bit like this :

; <<>> DiG 9.6.0-APPLE-P2 <<>> myzone.dev.local

;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53590
;; flags: qraa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1
;; QUESTION SECTION:
;myzone.dev.local.			IN	A
;; ANSWER SECTION:
myzone.dev.local.		7200	IN	A	127.0.0.1
;; AUTHORITY SECTION:
dev.local.		7200	IN	NS	dev.local.
;; ADDITIONAL SECTION:
dev.local.		7200	IN	A	127.0.0.1
;; Query time: 1 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sat Jun 12 08:37:11 2010
;; MSG SIZE  rcvd: 77

Bonus section, enabling the vhost in xampp

I’am assuming you did a basic installation of xampp by dropping the package into the Applications folder like instructed

Using the finder browse to /Applications/XAMPP/etc  and open the file called HTTPD.CONF in your favorite text editor.
Locate the two commented lines for the virtual host, somewhere at the bottom around line number 469
# Virtual hosts
#Include /Applications/XAMPP/etc/extra/httpd-vhosts.conf

And remove the # before the Include and save the file.
Browse one level deeper into the XAMPP folder to /Applications/XAMPP/etc/extra and open the http-vhosts.conf file in the above mentioned favorite text editor and remove all the contents. Replace it with this
NameVirtualHost *:80

<VirtualHost *:80>
    DocumentRoot "/Users/rene/Sites/renebakx.nl"
    ServerName renebakx.dev.local
	<Directory /Users/rene/Sites/renebakx.nl>
	AllowOverride ALL
	</directory>
</VirtualHost>
First part tells apache to listen to port 80, next block defines a virtual host that points to the mac default Sites folder, which i personally find more convenient to use then the docroot in XAMPP, for the renebakx.dev.local site.
Repeat only the <VirtualHost…..></VirtualHost> part for every other wildcard domain you need to setup.
(for more advanced features of the virtualhost directive, consult the apache2 manual.
Restart the apache server using the xampp control application and point your browser to the freshly created site :)

Rik’s bonus part

Like mention below in the comments by Rik, using the vhost_alias module it’s even easierHowever there is a small downside to it. I personally like my development folders named a bit like the site i’am working on. For example the contents of this site is in the “renebakx.nl” folder. vhost_alias uses the dot to calculate offsets in alias names. If you can live with the fact that your subdomain can not contain a dot, or you don’t mind replacing a dot with a dash. Feel free to swap the above mentioned vhost directives with something like this.

Boy was I wrong :) You can use multiple VirtualDocumentRoot rules. I ended up with a vhost configuration like this

<VirtualHost *:80>
	ServerName dev.local
	ServerAlias *.dev.local
	ServerAdmin webmaster@localhost
	VirtualDocumentRoot "/Users/rene/Sites/%1"
	VirtualDocumentRoot "/Users/rene/Sites/%-3+/"
	<Directory /Users/rene/Sites/>
		Options Indexes FollowSymLinks
		AllowOverride All
		Order allow,deny
		Allow from all
	</Directory>
</Virtualhost>

As you can see, this point whatever.dev.local to ‘/Users/rene/Sites/whatever’ and somesite.nl.dev.local points to ‘/Users/rene/Sites/somesite.nl’

Now how awesome is that? :D

 
6 Comments

Posted in OSX

 

Tags: , , ,

Leave a Reply

 
 
  1. rik

    12/06/2010 at 22:47

    Nice thanks!

    To make life even simpler enable vhost_alias so you do not have to add the virtual host sections anymore.

    - Make sure vhost_alias_module is loaded in apache (In MAMP it’s already loaded)

    Now in httpd.conf or where ever add something similar to this:

    ServerAdmin webmaster@localhost
    VirtualDocumentRoot “/Users/rikvanderkemp/Sites/%1/public_html”
    ServerName subdomains.dev.local
    ServerAlias *.dev.local

    Options Indexes FollowSymLinks
    AllowOverride All
    Order allow,deny
    Allow from all

    Of course substituting what applies to you :-)

    Now you will not have to do any maintenance whatsoever. The server will just look for the appropriate folder.

    So e.g. mysite.dev.local will look for /Users/rikvanderkemp/Sites/mysite/public_html

    (Note, the folder public_html is of course optional)

    greets,
    Rik

     
  2. rik

    12/06/2010 at 22:48

    Oh nice I see the VirtualHost *:80 and Directory “/Users/bla” things were filtered out in the comment.

     
  3. Rik

    13/06/2010 at 10:40

    Cool to see my comment in the article.

    As for the ‘renebakx.nl.dev.local’ issue:

    Just replace the VirtualDocumentRoot with something like this:

    VirtualDocumentRoot “/Users/rikvanderkemp/Sites/%-3+/public_html”

     
  4. Rene

    13/06/2010 at 12:34

    The syntax of the vhost alias module really bugs me, it so not logic to me. But i just found out that you can use multiple rules! So i added your part to the part i already had. Presto, very flexible folder structure. Sweet!

     
  5. drm

    13/06/2010 at 13:26

    I have tried VirtualDocumentRoot some time ago, but one big downside is that the DOCUMENT_ROOT environment variable isn’t virtual, which might get you in trouble with resolving rewritten paths to local files. So be aware that this will get you in trouble when relying on DOCUMENT_ROOT.

    I’m not sure this is still the case though, but it might be worth checking.

     
  6. Fixing the documentroot with vhost_alias « Rene Bakx

    15/07/2010 at 11:09

    [...] small solution in follow up of the document root issue drm brought up in a previous post. Setting the correct $_SERVER["document_root"] value for your vhost_alias [...]