<!-- 
.. title: Configuring dnsmasq in a BSD Jail on FreeNAS 11
.. slug: dnsmasq-FreeNAS
.. date: 2017-12-05
.. tags: network,server,dns,dhcp
.. category: admin
.. link: 
.. description: 
.. type: text
-->

These are notes on how I setup dnsmasq to act as a DNS and DHCP server running
in a BSD Jail on FreeNAS 11. 

<!-- TEASER_END -->

These notes are largely based on [this writeup](
http://www.wordpress.lonbil.co.uk/2013/08/installing-dnsmasq-on-freenas-9-1/
) and [this one too](
https://www.linux.com/learn/dnsmasq-easy-lan-name-services
).

# Update /etc/resolv.conf on FreeNAS

Add the entry:

    nameserver 192.168.88.24

# Create a BSD Jail

In the FreeNAS UI, create a jail, ensure that VIMAGE is checked so that the entire
network is accessible outside the jail.  I assigned the jail an IP of
``192.168.88.24``.

Once created, the jail should be running.  Confirm this via ``jls``.

	root@files:~ # jls
	   JID  IP Address      Hostname                      Path
		 2                  dnsmasq                       /mnt/tank2/jails/dnsmasq
	root@files:~ # 


# Install dnsmasq

Enter the jail you just created.  In my case, it was shown as jail ``2`` in
the output of ``jls``.  To enter it:  ``jexec 2 /bin/csh``.

Ensure the package is available by running ``pkg search dnsmasq``.  Then
install it via ``pkg install dnsmasq``.  You should see the following output:

	*** To enable dnsmasq, edit /usr/local/etc/dnsmasq.conf and
	*** set dnsmasq_enable="YES" in /etc/rc.conf[.local]
	***
	*** Further options and actions are documented inside
	*** /usr/local/etc/rc.d/dnsmasq

# Create a Directory to Contain Leases

	[root@dnsmasq /]# mkdir -p /var/db/dnsmasq

# Configure dnsmasq

Create a ``dnsmasq.conf`` file in ``/usr/local/etc``:

	[root@dnsmasq /]# cat  /usr/local/etc/dnsmasq.conf
	######################################################################
	#
	# dnsmasq Settings
	#

	# Never forward simple hostnames (names that do not contain a dot).
	domain-needed

	# Prevent non-routable private IP addresses from being forwarded.
	bogus-priv

	# Our domain.  Allows lookups using either simple hostnames or
	# FQHNs.  For example, either 'laptop' or 'laptop.east.fm'.
	domain=east.fm

	# Append the above domain to to simple hostnames (i.e., hostnames
	# without a period), thereby creating FQDNs.
	expand-hosts

	# Queries for my domain answered only by dnsmasq, /etc/hosts, or DHCP.
	# I don't want this, as it precludes the use of east.fm for hosts
	# not on this local net (e.g., my web and email servers).
	# local=/east.fm/

	# Only listen on listen-address.
	# As configured below, only listen on the local network.
	listen-address=127.0.0.1
	listen-address=192.168.88.24   # IP of what Dnsmasq is running on/in
	bind-interfaces

	######################################################################
	#
	# DHCP Settings
	#

	# IP range to give out
	dhcp-range=set:lan,192.168.88.100,192.168.88.199,12h

	# Store leases here
	dhcp-leasefile=/var/db/dnsmasq/dnsmasq.leases

	# Default gateway
	dhcp-option=tag:lan,option:router,192.168.88.1   # MikroTik router

	# Specify DNS server for DHCP clients.
	# IP of FreeNAS BSD jail dnsmasq runs in.
	dhcp-option=tag:lan,option:dns-server,192.168.88.24

	# Use DNS servers in order shown
	strict-order

	# Upstream DNS servers
	server=8.8.8.8         # Google
	server=208.67.220.220  # OpenDNS
	server=8.8.4.4         # Google

	# Location of our hosts file
	addn-hosts=/usr/local/etc/hosts

	# Ensure these devices always get same IP
	dhcp-host=B0:A7:37:EB:E6:29,192.168.88.90    # Roku

# Create a local ``hosts`` file

Create a local hosts file for all of my systems with static IP addresses:

	[root@dnsmasq /]# cat  /usr/local/etc/hosts
	127.0.0.1      localhost

	# Network Equipment
	192.168.5.1    modem         # LTE modem
	192.168.88.1   aprouter      # MikroTik AP/router
	192.168.88.9   switch        # MikroTik router for servers
	192.168.88.5   bridge        # MikroTik 5GHz bridge

	# Dell R510 Server (FreeNAS)
	192.168.88.20  drac510       # iDRAC 6
	192.168.88.21  files         # FreeNAS 11
	192.168.88.22  filessmb      # SMB shares
	192.168.88.23  filesafp      # AFP shares
	192.168.88.24  dnsmasq       # dnsmasq in BSD jail

	# Dell R610 Server (Proxmox VE)
	192.168.88.30  drac610       # iDRAC 6
	192.168.88.31  apps          # Proxmox via port 8006
	192.168.88.32  ubuntu plex   # Ubuntu server, Plex via port 32400

	# Other devices
	192.168.88.90  roku          # Roku box.  IP assigned via dnsmasq.conf

# Starting dnsmasq at Boot

In the jail, add the following to ``/etc/rc.conf``:

	dnsmasq_enable="YES"
	dnsmasq_conf="/usr/local/etc/dnsmasq.conf"

In FreeNAS, access the Advanced settings for the jail and check 'autostart'.

# Start dnsmmasq manually

Start it manually via: ``service dnsmasq restart``.

Test the config files:  ``dnsmasq --test``.

# Update /etc/resolv.conf

This is not strictly necessary, but if you wish to use dnsmasq for domain
resolution *within* the BSD jail, then ``/etc/resolv.conf`` should contain:

    search local
	nameserver 192.168.88.24
	
If you don't do this and run commands such as ``drill aprouter`` at the
command line from within the jail, dnsmasq will not be used for the lookup and
the results may fool one into think dnsmasq isn't working correctly.

# Testing dnsmasq

To test DNS:

```bash
# From another host
$ dig drac610 @192.168.88.24

# From the jail
$ drill aprouter @localhost

# If you updated resolv.conf, this should work in the jail
$ drill aprouter
```

How to see if DHCP is working properly?  One method is to use
an ``nmap`` script.  This script can be a little misleading, in that it only
returns the first answer that it gets from a DHCP server.  If there are
multiple DHCP servers, you'll never know about it.

```bash

$ sudo nmap --script broadcast-dhcp-discover -e eth0
```
Another option is ``dhcpdump``.  I prefer this one as it runs on top of
``tcpdump`` and will dump DHCP responses as long as it runs.  It's the best
way to see if there is more than one DHCP server active.

```bash
$ sudo dhcpdump -i eth0
```
	
MacPorts does not contain ``dhcpdump``, but the source is [here](
http://www.mavetju.org/unix/general.php).  It is trivial to build.
The same page also has source for ``dhcping``.


# Updating the Hosts File

To update the hosts file:

* Enter the dnsmasq jail.
* Update /usr/local/etc/hosts and save it.
* ``$ service dnsmasq restart``

# MacOS Reminders

In working through all this, at times, I'd make changes and be confused when
the results that I saw on my laptop didn't match the change I thought I made.
I'd eventually remember that MacOS is caching query results.  To clear the
cache on 10.13:

```bash
$ sudo killall -HUP mDNSResponder
$ sudo killall mDNSResponderHelper
$ sudo dscacheutil -flushcache
```

To see *all* DNS servers MacOS is using, including scoped queries (taken from
[here](https://superuser.com/questions/1177175)):
```bash
# To see all DNS servers MacOS is using
$ scutil --dns

# To query DNS the way that MacOS does
$ dns-sd -G v4v6 example.com
```

DNS tools such as ``nslookup``, ``dig``, and ``host`` each contain their own
unique DNS resolver code, so their answers may or may not match those used by
MacOS itself.

To see which DHCP server your address came from and which
DNS server your DHCP server told MacOS to use, look at the
the output from:

```bash
$ ipconfig getpacket en0
```
