A docker image to host a simple instance of one's own DNS-over-HTTPS proxy.
Because browsers are beginning to migrate to DOH (DNS-over-HTTPS). Motivations for securing the DNS traffic make a lot of sense. But the risk to run towards a new monopoly is high. This project should encourage people to deploy one's own resolver.
This project is a patchwork of others:
- doh-proxy: a HTTP-to-DNS proxy written in Rust.
- letsencrypt: the Mozilla free certification authority (and the related certbot utility).
- nginx: a very nice HTTP server and reverse proxy.
All the above is glued together via docker and orchestrated by supervisord.
doh-proxy
is responsible to receive the HTTP request on a specific path and issue a
corresponding DNS request (and serve the response as HTTP response).
letsencrypt
provides a widely accepted certificate for TLS secure connection and
nginx
proxies the HTTP connection into a secure HTTP2 connection for the clients
to be used.
You need three things:
- A machine with a public ip address, ideally always up, capable of running docker and with TCP ports 80 and 443 reachable from the outside and able to DNS-query towards a chosen server.
- A domain that resolves on the said machine.
- An email to be able to obtain a valid TLS certificate from letsencrypt.
This translate directly in two environment variables to be passed to the running container:
DOMAINS
should be a space-separated list of domains to which your machine is reachable (can also be a single name).
Optionally you may tweak with the upstream dns resolver (i.e. where all the queries are sent, in the end - you may want to really change it from the default google resolver - 8.8.8.8:53) and the path to which the HTTP server responds:
UPSTREAM_DNS
should be a valid IP address plus the UDP port (defaults to google's8.8.8.8:53
).DOH_PATH
should be a path, that begins with a/
.
No, you don't. You may yet have a VPS with an HTTP server that you may want to use for the purpose. In this case, I invite you to take a look at doh-proxy and to use it directly.
$ docker run --restart unless-stopped \
-e DOMAINS="my.domain.org" \
-e EMAIL="[email protected]" \
--name="my-doh-resolver" \
leophys/doh-proxy
On the machine you want to run the resolver you'll need:
GNU make
git
docker
(of course)
Then run:
$ git clone https://github.com/leophys/doh-docker
$ cd doh-docker
$ make run -e DOH_DOMAINS="my.domain.com myother.domain.com" \
DOH_EMAIL="[email protected]"
If you don't trust me (you shouldn't), read the code.
This image supports the use of the host's letsencrypt default path. The use case is when another service on the host needs the same certificates as those inside the container. There are two possibilities then:
- Another service refreshes the certificates when they expire or
- the service inside the container takes care of renewing them
Both are supported. In the first case just mount the relevant paths onto the container:
$ docker run --restart unless-stopped \
-e DOMAINS="my.domain.org" \
-e EMAIL="[email protected]" \
-v /etc/letsencrypt/live/my.domain.tld:/etc/letsencrypt/live/my.domain.tld \
-v /etc/letsencrypt/archive/my.domain.tld:/etc/letsencrypt/archive/my.domain.tld \
--name="my-doh-resolver" \
leophys/doh-proxy
The relevant script with skip that domain (letsencrypt-wrapper.sh_).
If the certificates has to be renewed by an hosts service, just do the same, but take
care of touching a file named .doh-force
in the live
path:
$ touch /etc/letsencrypt/live/my.domain.tld/.doh-force
$ docker run --restart unless-stopped \
-e DOMAINS="my.domain.org" \
-e EMAIL="[email protected]" \
-v /etc/letsencrypt/live/my.domain.tld:/etc/letsencrypt/live/my.domain.tld \
-v /etc/letsencrypt/archive/my.domain.tld:/etc/letsencrypt/archive/my.domain.tld \
--name="my-doh-resolver" \
leophys/doh-proxy
See LICENCE.