Dnscrypt with docker broken?

Hi, I’ve been trying to setup this simple dnscrypt container and use it to resolve the host’s DNS queries.

Original command to start the container: docker run -dt --dns 127.0.0.1 -p 53:53/udp -p 53:53/tcp --name dnscrypt-proxy --restart unless-stopped modem7/dnscrypt-proxy

This produces an error message saying: ‘Error starting dnscrypt proxy: listen tcp 0.0.0.0:53: bind: address already in use’

The maintainer recommends an alternate command to fix this: docker run -dt --dns 127.0.0.1 -p 5353:53/udp -p 5353:53/tcp --name dnscrypt-proxy --restart unless-stopped modem7/dnscrypt-proxy

This successfully starts the container and I can see connections being made to dnscrypt-proxy’s keyserver, where it pulls the cache and key file.

Listening on local 127.0.0.1:53 and 0.0.0.0:5353

Now I edit the host’s resolv.conf to say “nameserver 127.0.0.1” , but it’s not working.

I understand that normally a container’s local space is different from the host’s, but shouldn’t this “bridge” that gap?

Kind regards

When you start the container with -p 5353:53/udp -p 5353:53/tcp, the dns resolver on your host that is listening on 127.0.0.1:53 can not be the dnscrypt resolver, as you didn’t publish the container port to that host port.

You need to publish it on port 53 in order to be used as nameserver in resolv.conf

I see three possible solutions (the last two are just variations of the same solution):

  • remove the current dns resolver that binds 127.0.0.1:53 (Ubuntu is known to run a dns stub resolver, that prevents binding port 53 without specifying the ip)
  • publish the port and bind it to another ip of the host -p lan-ip:53:53/udp -p lan-ip:53:53/tcp
  • if your host does not have a static ip, add another loopback interface to your host with a different 127.0.0.x ip and publish the port to this ip -p 127.0.0.x:53:53/udp -p 127.0.0.x:53:53/tcp (not sure if this is possible with Windows)

Whatever ip you bind the host port to, should be the nameserver entry in /etc/resolv.conf.

Hello meyay, thank you for the detailed response.

I will try both of your solutions at once.

I assume the third solution is related to this fix which describes the creation of a dummy network?

You guys are amazing in this forum BTW. I don’t understand why the maintainer of that Dnscrypt-Proxy git didn’t add this vital information to the page. Nobody could use that container without doing all this prep work first.

Actually just a virtual network interface with an ip. So, yes, exact that approach. I would pick an ip from the 127.0.0.0/8 cidr range. Something like 127.0.0.5, if you only need it on the local machine.

I agree, the maintainer should have mentioned it, as it its high likely people run into that problem. Though, not every host runs a dns resolver.

Update: I should have read the article. I completely ignored that you might want to use dnscrypt from other containers as well. Of course a virtual network interface for another loopback adapter won’t be enough in that scenario.

Funny you mentioned it, I have a second topic here where I’m trying to resolve a jdownloader container’s queries with a Dnscrypt-Proxy container. I wanted to fully immerse myself in the subject matter and try out every possible solution before posting again and annoying the guy, who I now realize was actually you, lol.

But it turns out I couldn’t even run one of those containers separately.

I’ll try all of your suggested solutions to get this thing running and after that I am going to read everything there is on docker networking, guides how-tos etc. and tackle the main problem, to which you’ve already given me some great hints.

Thanks again, I really appreciate that you guys offer support to noobs like me. If you have projects or pages with a donate button, I’d be happy to.

Regards

1 Like

You are welcome!

It would be great if you keep us posted about the final solution you implement, so that others that stumble across this topic don’t just see the questions and discussion, but also find a solution they can adapt.

Have a great weekend!

Hi again, I’ve got it working and wanted to share meyay’s solution (1) with anyone else who might be looking.

This works with the following projects regarding docker + Dnscrypt-Proxy resolving on the host (I’ve tested them all):

Most of these builds use some variation of jedisct1’s Dnscrypt-Proxy (formerly unbound-dnscrypt-proxy) which incorporates unbound and encrypted-dns from crates.io

I am using Ubuntu 22.04, but it will probably be similar for most Linux distros.

1.)Edit the dnscrypt-proxy.toml
You need to add a private address in the 10.x.x.x or 192.168.x.x range to listen_addresses
Example: listen_addresses = [‘192.168.0.15:53’]
Addresses in the 172.x.x.x range fail with docker returning an error saying network un

2.)Disable systemd-resolved

3.)edit /etc/NetworkManager.conf
Under [main] add “dns=none”

4.)Execute the following:
echo ‘make_resolv_conf() { :; }’ > /etc/dhcp/dhclient-enter-hooks.d/leave_my_resolv_conf_alone
chmod 755 /etc/dhcp/dhclient-enter-hooks.d/leave_my_resolv_conf_alone
This will stop any attempts to overwrite your changes.

5.)Add the private address from 1.) to your host’s resolv.conf
nameserver 192.168.0.15

Now it should work.

One thing I noticed when analyzing traffic on the host’s interface while resolving with the dnscrypt container is that there is no outgoing connection to the designated provider in the dnscrypt-proxy.toml (in my case I chose google and cloudflare), but you’ll only see incoming traffic from 192.168.0.15 to your host’s interface.
Since I only tested with apt, I guess the dnscrypt-proxy image comes with a bunch of preloaded server IPs and domains, and won’t even make an outbound connection unless it can’t find the information locally.

1 Like

Thank you sharing your final result with us!

I moved your topic to the DockerEngine category, and flagged your last post as solution.