title: DNS not working within docker containers when host uses dnsmasq and Google's DNS server are firewalled?
body: <p>The symptom is: the host machine has proper network access, but programs running within containers can't resolve DNS names (which may appear to be &quot;can't access the network&quot; before investigating more).</p>
  <pre><code>$ sudo docker run -ti mmoy/ubuntu-netutils /bin/bash
  root@082bd4ead733:/# ping www.example.com
  ... nothing happens (timeout) ... ^C
  root@082bd4ead733:/# host www.example.com
  ... nothing happens (timeout) ... ^C
  </code></pre>
  <p>(The docker image <a href="https://hub.docker.com/r/mmoy/ubuntu-netutils/" rel="nofollow noreferrer">mmoy/ubuntu-netutils</a> is a simple image based on Ubuntu with <code>ping</code> and <code>host</code> included, convenient here since the network is broken and we can't <code>apt install</code> these tools)</p>
  <p>The issue comes from the fact that docker automatically configured Google's public DNS as DNS server within the container:</p>
  <pre><code>root@082bd4ead733:/# cat /etc/resolv.conf 
  # Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
  #     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
  
  nameserver 8.8.8.8
  nameserver 8.8.4.4
  </code></pre>
  <p>This just works in many configurations, but obviously doesn't when the host runs on a network where Google's public DNS are filtered by some firewall rules.</p>
  <p>The reason this happened is:</p>
  <ul>
  <li>Docker first tries configuring the same DNS server(s) on the host and within the container.</li>
  <li>The host runs <a href="http://www.thekelleys.org.uk/dnsmasq/doc.html" rel="nofollow noreferrer">dnsmasq</a>, a DNS caching service. dnsmasq acts as a proxy for DNS requests, hence the apparent DNS server in the host's <code>/etc/resolve.conf</code> is <code>nameserver 127.0.1.1</code>, i.e. localhost.</li>
  <li>The host's dnsmasq listens only for requests comming from localhost and blocks requests coming from the docker container.</li>
  <li>Since using <code>127.0.1.1</code> within docker doesn't work, docker falls back to Google's public DNS, which do not work either.</li>
  </ul>
  <p>There may be several reasons why DNS is broken within docker containers. This question (and answers) covers the case where:</p>
  <ul>
  <li>dnsmasq is used. To check whether this is the case:
  <ul>
  <li>Run <code>ps -e | grep dnsmasq</code> on the host. If the output is empty, you're not running dnsmasq.</li>
  <li>Check the host's resolv.conf, it probably contains an entry like <code>nameserver 127.0.1.1</code>. If it contains <code>nameserver 127.0.0.53</code>, you're probably running <code>systemd-resolved</code> instead of dnsmasq. If so, you won't be able to use the solution forwading DNS requests to dnsmasq (the one using <code>listen-address=172.17.0.1</code>). <a href="https://unix.stackexchange.com/questions/445782/how-to-allow-systemd-resolved-to-listen-to-an-interface-other-than-loopback">systemd-resolved versions earlier than 247 hardcoded the fact that it listens only on the 'lo' interface hence there's no easy way to adapt this solution with these versions</a>. Other answers below will work with systemd-resolved.</li>
  </ul>
  </li>
  <li>Google's public DNS is filtered. Run <code>host www.example.com 8.8.8.8</code>. If it fails or times out, then you are in this situation.</li>
  </ul>
  <p>What are the solutions to get a proper DNS configuration in this configuration?</p>