157 lines
6.5 KiB
Markdown
157 lines
6.5 KiB
Markdown
|
+++
|
||
|
title = "using unbound and dnsmasq"
|
||
|
date = "2014-12-09T22:13:58+00:00"
|
||
|
author = "Gibheer"
|
||
|
draft = false
|
||
|
+++
|
||
|
|
||
|
After some time of using an [Almond](http://www.securifi.com/almond) as our router
|
||
|
and always having trouble with disconnects, I bought a small [apu1d4](http://www.pcengines.ch/apu1d4.htm),
|
||
|
an AMD low power board, as our new router.
|
||
|
It is now running FreeBSD and is very stable. Not a single connection was
|
||
|
dropped yet.
|
||
|
|
||
|
As we have some services in our network, like a fileserver and a printer, we
|
||
|
always wanted to use names instead of IPs, but not a single router yet could
|
||
|
provide that. So this was the first problem I solved.
|
||
|
|
||
|
FreeBSD comes with unbound preinstalled. Unbound is a caching DNS resolver, which
|
||
|
helps answer DNS queries faster, when they were already queried before. I
|
||
|
wanted to use unbound as the primary source for DNS queries, as the caching
|
||
|
functionality is pretty nice.
|
||
|
Further I wanted an easy DHCP server, which would also function as a DNS server.
|
||
|
For that purpose dnsmasq fits best. There are also ways to use dhcpd, bind and
|
||
|
some glue to get the same result, but I wanted as few services as possible.
|
||
|
|
||
|
So my setup constellation looks like this:
|
||
|
|
||
|
client -> unbound -> dnsmasq
|
||
|
+-----> ISP dns server
|
||
|
|
||
|
For my internal tld, I will use zero. The dns server is called cerberus.zero and
|
||
|
has the IP 192.168.42.2. The network for this setup is 192.168.42.0/24.
|
||
|
|
||
|
## configuring unbound
|
||
|
|
||
|
For this to work, first we configure unbound to make name resolution work at
|
||
|
all. Most files already have pretty good defaults, so we will overwrite these
|
||
|
with a file in `/etc/unbound/conf.d/`, in my case `/etc/unbound/conf.d/zero.conf`.
|
||
|
|
||
|
server:
|
||
|
interface: 127.0.0.1
|
||
|
interface: 192.168.42.2
|
||
|
do-not-query-localhost: no
|
||
|
access-control: 192.168.42.0/24 allow
|
||
|
local-data: "cerberus. 86400 IN A 192.168.42.2"
|
||
|
local-data: "cerberus.zero. 86400 IN A 192.168.42.2"
|
||
|
local-data: "2.42.168.192.in-addr.arpa 86400 IN PTR cerberus.zero."
|
||
|
local-zone: "42.168.192.in-addr.arpa" nodefault
|
||
|
domain-insecure: "zero"
|
||
|
|
||
|
forward-zone:
|
||
|
name: "zero"
|
||
|
forward-addr: 127.0.0.1@5353
|
||
|
|
||
|
forward-zone:
|
||
|
name: "42.168.192.in-addr.arpa."
|
||
|
forward-addr: 127.0.0.1@5353
|
||
|
|
||
|
So what happens here is the following. First we tell unbound, on which addresses
|
||
|
it should listen for incoming queries.
|
||
|
Next we staate, that querying dns servers in localhost is totally okay. This is
|
||
|
needed to later be able to resolve addresses on the local dnsmasq. If your dnsmasq
|
||
|
is running on a different machine, you can leave this out.
|
||
|
With `access-control` we allow the network `192.168.42.0/24` to query the dns
|
||
|
server.
|
||
|
The next three lines tell unbound, that the name cerberus and cerberus.zero are one
|
||
|
and the same machine, the DNS server. Without these two lines unbound would not
|
||
|
resolve the name of the local server, even if its name would be stated in `/etc/hosts`.
|
||
|
With the last line we enable name resolution for the local network.
|
||
|
The key domain-insecure tells unbound, that this domain has no support for DNSSEC.
|
||
|
DNSSEC is enabled by default on unbound.
|
||
|
|
||
|
The two `forward-zone` entries tell unbound, where it should ask for queries regarding
|
||
|
the `zero` tld and the reverse entries of the network. The address in this case points
|
||
|
to the dnsmasq instance. In my case, that is running on localhost and port 5353.
|
||
|
|
||
|
Now we can add unbound to `/etc/rc.conf` and start unbound for the first time
|
||
|
with the following command
|
||
|
|
||
|
$ sysrc local_unbound_enable=YES && service local_unbound start
|
||
|
|
||
|
Now you should be able to resolve the local hostname already
|
||
|
|
||
|
$ host cerberus.zero
|
||
|
cerberus.zero has address 192.168.42.2
|
||
|
|
||
|
## configuring dnsmasq
|
||
|
|
||
|
The next step is to configure dnsmasq, so that it provides DHCP and name resolution
|
||
|
for the network. When adjusting the config, please read the comments for each
|
||
|
option in your config file carefully.
|
||
|
You can find an example config in `/usr/local/etc/dnsmasq.conf.example`. Copy
|
||
|
it to `/usr/local/etc/dnsmasq.conf` and open it in your editor:
|
||
|
|
||
|
port=5353
|
||
|
domain-needed
|
||
|
bogus-priv
|
||
|
no-resolv
|
||
|
no-hosts
|
||
|
local=/zero/
|
||
|
except-interface=re0
|
||
|
bind-interfaces
|
||
|
local-service
|
||
|
expand-hosts
|
||
|
domain=zero
|
||
|
dhcp-range=192.168.42.11,192.168.42.200,255.255.255.0,48h
|
||
|
dhcp-option=option:router,192.168.42.2
|
||
|
dhcp-option=option:dns-server,192.168.42.2
|
||
|
dhcp-host=00:90:f5:f0:fc:13,0c:8b:fd:6b:04:9a,sodium,192.168.42.23,96h
|
||
|
|
||
|
First we set the port to 5353, as defined in the unbound config. On this port
|
||
|
dnsmasq will listen for incoming dns requests.
|
||
|
The next two options are to avoid forwarding dns requests needlessly.
|
||
|
The option `no-resolv` avoids dnsmasq knowning of any other dns server. `no-hosts`
|
||
|
does the same for `/etc/hosts`. Its sole purpose is to provide DNS for the
|
||
|
local domain, so it needn't to know.
|
||
|
|
||
|
The next option tells dnsmasq for which domain it is responsible. It will also
|
||
|
avoid answering requests for any other domain.
|
||
|
|
||
|
`except-interfaces` tells dnsmasq on which interfaces _not_ to listen on. You
|
||
|
should enter here all external interfaces to avoid queries from the wide web
|
||
|
detecting hosts on your internal network.
|
||
|
The option `bind-interfaces` will try to listen only on the interfaces allowed
|
||
|
instead of listening on all interfaces and filtering the traffic. This makes
|
||
|
dnsmasq a bit more secure, as not listening at all is better than listening.
|
||
|
|
||
|
The two options `expand-hosts` and `domain=zero` will expand all dns requests
|
||
|
with the given domain part, if it is missing. This way, it is easier to resolv
|
||
|
hosts in the local domain.
|
||
|
|
||
|
The next three options configure the DHCP part of dnsmasq. First is the range.
|
||
|
In this example, the range starts from `192.168.42.11` and ends in `192.168.42.200`
|
||
|
and all IPs get a 48h lease time.
|
||
|
So if a new hosts enters the network, it will be given an IP from this range.
|
||
|
The next two lines set options sent with the DHCP offer to the client, so it
|
||
|
learns the default route and dns server. As both is running on the same machine
|
||
|
in my case, it points to the same IP.
|
||
|
|
||
|
Now all machines which should have a static name and/or IP can be set through
|
||
|
dhcp-host lines. You have to give the mac address, the name, the IP and the
|
||
|
lease time.
|
||
|
There are many examples in the example dnsmasq config, so the best is to read
|
||
|
these.
|
||
|
|
||
|
When your configuration is done, you can enable the dnsmasq service and start it
|
||
|
|
||
|
$ sysrc dnsmasq_enable=YES && service dnsmasq start
|
||
|
|
||
|
When you get your first IP, do the following request and it should give you
|
||
|
your IP
|
||
|
|
||
|
$ host $(hostname)
|
||
|
sodium.zero has address 192.168.42.23
|
||
|
|
||
|
With this, we have a running DNS server setup with DHCP.
|