FOSS, linux, networking, nextcloudpi

dnsmasq as DNS cache server for NextCloudPi and Raspbian

Alright, so you already have your own NextCloudPi server ( or any other similar service ) at home. You also registered for Dynamic DNS with and set it up using the installer from last post.

Now you might or might not have another extra problem.

You can configure your Android or laptop sync client for NextCloud with your flashy new dynamic DNS domain, so you can access to your private cloud at home from outside, but depending on the modem-router provided by your ISP, you will find that you might not be able to access through URL from inside your house.

In this situation you

  • Can access from the street typing something like
  • You can only access from inside your house using your local IP. Something like

This happens because your router does not support NAT loopback, so it is unable to access the server inside your house with the public IP address that you use from outside your house. Most home routers lack this feature.

If it does not work for you is because this is happening

The solution to this is to set up your own DNS server inside your house, and point all of your devices to it.

You then have the ability to configure it to direct any queries to to .

Your new situation would be like this

For this, we will use the dnsmasq daemon. It is a very compact little server that also has the ability to provide DHCP and more, but here we will use it as a DNS redirect server with cache.

A nice upside is that we will achieve DNS caching, so we will accelerate all the internet lookups inside our home! More on that later.


There are two options for configuration, depending on wether you are installing it in your already set up and running Raspberry Pi ( online installation ), or if you use the NextCloudPi image. See details below, but the configuration is exactly the same.

  • DOMAIN is the URL to access from outside and inside your house. Use the same one you signed up with or any other DDNS provider.
  • IP is the local IP of your Raspberry Pi in your network. In my case is
  • DNSSERVER is your ISP’s DNS server preferably. If you do not know this IP try to figure out which one it is. Maybe it will show up if you write cat /etc/resolv.conf , maybe it will be on your modem-router administration URL.
  • CACHESIZE is the number of DNS URLs to keep in cache. 150 is the default, I have 1000.

If you cannot discover your ISP DNS, Google DNS ( and ) will always work for your, but the one provided by your ISP will always be faster, not to talk about the privacy implications of Google knowing every single URL you use.

On some modem-routers, you can set your RPi local address as the primary DNS provider. Keep your ISP DNS provider as secondary. If you can do this, no further configuration is needed.

Otherwise, you will need to configure your devices to use your Raspberry Pi’s address for DNS lookups.

For your PC, configure it in Network Manager if that is what you use, or set it up in /etc/resolv.conf like this

nameserver      # point this to your RPi local IP 
nameserver            # this one should be your ISP DNS

For your Android, you will sadly need to configure a static address. Configure your Raspberry Pi as your primary DNS provider and your ISP as your second.

Whenever you are outside of your house, the local address will have no configured route, so it will use the secondary DNS provider without any speed penalty.


Get it already made

I have included this in the latest release of my NextCloudPi, a ready to use Raspbian 8 image featuring NextCloud 11, HTTP2, PHP7 and more.

Follow the instructions provided. Once up and running, from your Raspberry Pi write

sudo nextcloudpi-config
Do it yourself

First, clone the repo

git clone
Online installation through SSH

Use the generic software installer with the script


Adjust to the IP address of your Raspberry Pi.

If you do not want to be asked for the username and password, and you changed the default password for user pi, you can specify username and/or password in the command line.

PIUSER=nacho PIPASS=ownyourbits ./
Offline installation

You can do this process offline using QEMU.

Extract the SD card and copy the image to your computer (adjust sdx).

 sudo dd if=/dev/sdx of=my_rpi.img bs=4M


./ my_rpi.img

Once done, you can copy it back (adjust sdx).

sudo dd if=my_rpi.img if=/dev/sdx bs=4M


In order to check that it works, you can use the dig utility from the bind-tools package.

Try it out with any URL

$ dig             

; <<>> DiG 9.11.0-P3 <<>>
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54427
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 4, ADDITIONAL: 9

; EDNS: version: 0, flags:; udp: 512
;                        IN      A

;; ANSWER SECTION:         60      IN      A         60      IN      A

;; AUTHORITY SECTION:         142798  IN      NS         142798  IN      NS         142798  IN      NS         142798  IN      NS

;; ADDITIONAL SECTION:    39359   IN      A    163713  IN      AAAA    2600:9000:5300:5b00::1  143513  IN      A  165815  IN      AAAA    2600:9000:5303:f500::1  143072  IN      A  162489  IN      AAAA    2600:9000:5305:5000::1 144060 IN      A 168270 IN      AAAA    2600:9000:5306:de00::1

;; Query time: 38 msec
;; WHEN: jue mar 02 00:01:05 CET 2017
;; MSG SIZE  rcvd: 388

You can verify that the query went through your dnsmasq server in  and took 38 milliseconds.

You can also see that because the query was not cached, your RPi had to ask your ISP provider for the IP address associated with this URL.

Let’s do the same query a second time

$ dig                         

; <<>> DiG 9.11.0-P3 <<>>
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 7710
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

; EDNS: version: 0, flags:; udp: 4096
;                        IN      A

;; ANSWER SECTION:         47      IN      A         47      IN      A

;; Query time: 0 msec
;; WHEN: jue mar 02 00:01:18 CET 2017
;; MSG SIZE  rcvd: 75

This time the query is cached, so our RPi will answer directly with the IP associated to the URL, and it will be way faster, we went down to 0 milliseconds!

Rich content websites can be constantly querying different URLs and a single website can be loaded by the combination of many HTTP requests. In this cases, the performance benefit of having cached DNS results will be more noticeable.


If you would like to provide a URL for a particular IP in your local network, you can specify this in two ways.

  • dnsmasq can read the contents of /etc/hosts  in your Raspberry Pi, so just by adding entries there, those URLs will be available in you local network.
  • you can also specify the DNS rule in /etc/dnsmasq.conf using a line like this

This behaviour can be modified by other configuration parameters in /etc/dnsmasq.conf.

You can also set up dnsmasq as a local DNS cache for your computer. The main configuration options to change in /etc/dnsmasq.conf  are




# dnsmasq DNS server with cache installation on Raspbian 
# Tested with 2017-01-11-raspbian-jessie.img (and lite)
# Copyleft 2017 by Ignacio Nunez Hernanz <nacho _a_t_ ownyourbits _d_o_t_ com>
# GPL licensed (see end of file) * Use at your own risk!
# Usage:
#   ./ <IP> (<img>)
# See instructions for details
DESCRIPTION="DNS server with cache"

  apt-get update
  apt-get install -y dnsmasq
  update-rc.d dnsmasq disable

  cat > /etc/dnsmasq.conf <<EOF
domain-needed         # Never forward plain names (without a dot or domain part)
bogus-priv            # Never forward addresses in the non-routed address spaces.
no-poll               # Don't poll for changes in /etc/resolv.conf
no-resolv             # Don't use /etc/resolv.conf or any other file
address=/$DOMAIN_/$IP_  # This is optional if we add it to /etc/hosts

  cat >> /etc/hosts <<EOF
$IP_ $DOMAIN_ # This is optional if we add it to dnsmasq.conf, but doesn't harm

  cat >> /etc/default/dnsmasq <<EOF
  update-rc.d dnsmasq defaults
  service dnsmasq start
  cd /var/www/nextcloud
  sudo -u www-data php occ config:system:set trusted_domains 2 --value=$DOMAIN_

  apt-get autoremove -y
  apt-get clean
  rm /var/lib/apt/lists/* -r
  rm -f /home/pi/.bash_history
  systemctl disable ssh

# License
# This script is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# This script is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this script; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
# Boston, MA  02111-1307  USA


Author: nachoparker

Humbly sharing things that I find useful [ github dockerhub ]


  1. what should be put in /etc/network/interfaces?

    Before this, I had google’s and as dns-nameservers, but I feel this should be changed now. Can I set the RPI’s address here as well?

  2. Thank you for all your work on NextCloudPi; I have managed to get NextCloud working on my Pi 3 but…
    Having successfully set up dnsmasq on the Pi (or so it appears), exactly how do I get my in-home PC (in my case running Ubuntu 16.04) to use it (so that I can access NextCloud using the same URL as I do outside the home). I have not found any method in the forum or on the web in general that works – everything seems to send me to (what I think is) a help page for my router.
    (A detail: the file /etc/resolv.conf has at its head the warning tnot to modify the file by hand, the changes will be overwritten. Ignoring the warning I did change it by hand and yes it did get overwritten!)
    Thanks for your help

  3. This works but then suddenly stops working with timeout errors. So it’s not very reliable, likely due to IPv6 prioritized over IPv4 by Windows. (Source: ) So apparently disabling IPv6 solved many people’s issues. However, my router doesn’t have that feature, so what I did was another solution, edit the /etc/hosts files (see the 4th or 5th post here: )

    This reliably solved my problem.

Leave a Reply

Your email address will not be published. Required fields are marked *