in Developer Experience

DNS for your Vagrant needs: with Landrush, libvirt and dnsmasq

Have you ever needed a DNS server that would be visible both on your host and your Vagrant guests? Landrush is one of those things that can pretty much save you. Unfortunately it was designed around VirtualBox and Mac OS, so it does not work on Linux out-of-the-box. And it does not work with libvirt provider at all. Until of course recently since I added the support there. Here is how to make all that work together on Fedora.

First things first — my libvirt patch is not yet merged, so you will have to build Landrush yourself. Check out my fork of Landrush and build the plugin with rake build, than you can install it with vagrant plugin install command:

$ bundle
$ bundle exec rake build
$ vagrant plugin install ./pkg/landrush-0.18.0.gem

This expects you to have Bundler and Vagrant installed. If you don’t, check Fedora Developer Portal and learn how to do it.

Now you should be able to run Landrush and it should work just fine for your guests. To confirm that Landrush is running run vagrant landrush status. Let’s make it work on Linux host too! On Mac OS Landrush adds entries in /etc/resolver, unfortunately that won’t work on Linux. That’s why I put dnsmasq in the title of this post.

We can tell dnsmasq to listen on 127.0.0.1 (localhost) and make an entry to redirect requested domain names (such as all ending with .dev or .local for example) to our Landrush DNS server (which runs on localhost too, but on port 10053 instead of standard 53). Let’s do it:

Add the following to /etc/dnsmasq.conf:

listen-address=127.0.0.1

And create a following file to redirect our .local domains traffic to Landrush:

$ cat /etc/dnsmasq.d/vagrant-landrush 
server=/.local/127.0.0.1#10053

Now let’s try to start dnsmasq service:

$ sudo systemctl start dnsmasq.service 
$ sudo systemctl status dnsmasq.service 
‚óŹ dnsmasq.service - DNS caching server.
   Loaded: loaded (/usr/lib/systemd/system/dnsmasq.service; disabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since Sun 2015-11-29 10:13:17 CET; 4s ago
  Process: 26654 ExecStart=/usr/sbin/dnsmasq -k (code=exited, status=2)
 Main PID: 26654 (code=exited, status=2)

Nov 29 10:13:17 strzibny-x1 systemd[1]: Started DNS caching server..
Nov 29 10:13:17 strzibny-x1 systemd[1]: Starting DNS caching server....
Nov 29 10:13:17 strzibny-x1 dnsmasq[26654]: dnsmasq: failed to create listening socket for port 53: Address already in use
Nov 29 10:13:17 strzibny-x1 systemd[1]: dnsmasq.service: main process exited, code=exited, status=2/INVALIDARGUMENT
Nov 29 10:13:17 strzibny-x1 systemd[1]: Unit dnsmasq.service entered failed state.
Nov 29 10:13:17 strzibny-x1 systemd[1]: dnsmasq.service failed.

Oh no. It seems that we have a conflict here. This is because libvirt actually starts dnsmasq for your domains as well automatically.

We can fix it by telling the system version of dnsmasq to bind to specific interfaces. Open the /etc/dnsmasq.conf again and list only the interfaces you need (and don’t conflict):

listen-address=127.0.0.1
...
# on my system
interface=wlp4s0
bind-interfaces

The service should start just fine afterwards. Let’s see if we can resolve our host:

$ host site.local
Host site.local not found: 3(NXDOMAIN)

We have dnsmasq set up, but it’s not used. For that we need to edit /etc/resolv.conf and add our new name server:

nameserver 127.0.0.1
...

Is this working?

$ host site.local
site.local has address X.X.X.X

Great! Can we ping it yet? Yes and no. If you went with .dev domain name, you are fine, but if you went with my changes and setup .local instead, ping won’t see your new settings. This is because of Avahi.

To change the domain for Avahi from .local, edit the avahi-daemon.conf configuration file and restart avahi-daemon:

$ cat /etc/avahi/avahi-daemon.conf
[server]
domain-name=.something_else_than_local
...

$ sudo systemctl restart avahi-daemon

If you don’t really need Avahi, you can also change the following in nsswitch.conf:

$ cat /etc/nsswitch.conf
...
#hosts:          files mdns4_minimal [NOTFOUND=return] dns
hosts:          files dns

Now you can ping your development hostnames and they should be redirected to your VM by dnsmasq and Landrush.

Afterwards you can open your browser or use curl:

$ curl http://site.local
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Directory listing for /</title>
</head>
<body>
<h1>Directory listing for /</h1>
<hr>
<ul>
<li><a href=".bash_history">.bash_history</a></li>
<li><a href=".bash_logout">.bash_logout</a></li>
<li><a href=".bash_profile">.bash_profile</a></li>
<li><a href=".bashrc">.bashrc</a></li>
<li><a href=".ssh/">.ssh/</a></li>
</ul>
<hr>
</body>
</html>

Write a Comment

Comment