qdm12 / dns

Docker DNS server on steroids to access DNS-over-TLS from Cloudflare, Google, Quad9, Quadrant or CleanBrowsing
https://hub.docker.com/r/qmcgaw/cloudflare-dns-server
MIT License
219 stars 37 forks source link
cleanbrowsing cloudflare-dns dns-over-tls dns-server docker google-dns quad9 quadrant unbound

DNS over TLS upstream server Docker container

DNS over TLS upstream server connected to DNS over TLS (IPv4 and IPv6) servers with DNSSEC, DNS rebinding protection, built-in Docker healthcheck and fine grain IPs + hostnames blocking

Announcement: *You can now try :v2.0.0-beta with this documentation.

The :latest Docker image might break compatibility in the coming days/weeks

Title

Build status

dockeri.co dockeri.co

Last release Last Docker tag Last release size GitHub last release date Commits since release

Latest size

GitHub last commit GitHub commit activity GitHub closed PRs GitHub issues GitHub closed issues

Lines of code Code size GitHub repo size Go version

MIT Visitors count

Features

Diagrams are shown for router and client-by-client configurations in the Connect clients to it section.

Setup

  1. ⚠️ Raspberry Pi users running 32 bit systems, you need to do this on your host to run the container.

  2. Launch the container with

    docker run -d -p 53:53/udp qmcgaw/dns

    You can also use docker-compose.yml with:

    docker-compose up -d

    More environment variables are described in the environment variables section.

  3. See the Connect clients to it section, you can also refer to the Verify DNS connection section if you want.

If you run an old Docker version or Kernel, you might want to run the container as root with --user="0" (see this issue for context).

Docker tags 🐳

Docker image Github release
qmcgaw/dns:latest Master branch
qmcgaw/dns:v1.5.1 v1.5.1
qmcgaw/dns:v1.4.1 v1.4.1
qmcgaw/dns:v1.2.1 v1.2.1
qmcgaw/dns:v1.1.1 v1.1.1
qmcgaw/cloudflare-dns-server:latest Master branch
qmcgaw/cloudflare-dns-server:v1.0.0 v1.0.0

💁 qmcgaw/cloudflare-dns-server:latest mirrors qmcgaw/dns:latest

Environment variables

Environment variable Default Description
PROVIDERS cloudflare Comma separated list of DNS-over-TLS providers from cira family, cira private, cira protected, cleanbrowsing adult, cleanbrowsing family, cleanbrowsing security, cloudflare, cloudflare family, cloudflare security, google, libredns, quad9, quad9 secured, quad9 unsecured and quadrant
VERBOSITY 1 From 0 (no log) to 5 (full debug log)
VERBOSITY_DETAILS 0 From 0 to 4 (higher means more details)
BLOCK_MALICIOUS on on or off, to block malicious IP addresses and malicious hostnames from being resolved
BLOCK_SURVEILLANCE off on or off, to block surveillance IP addresses and hostnames from being resolved
BLOCK_ADS off on or off, to block ads IP addresses and hostnames from being resolved
BLOCK_HOSTNAMES comma separated list of hostnames to block from being resolved
BLOCK_IPS comma separated list of IPs to block from being returned to clients
UNBLOCK comma separated list of hostnames to leave unblocked
LISTENINGPORT 53 UDP port on which the Unbound DNS server should listen to (internally)
CACHING on on or off. It can be useful if you have another DNS (i.e. Pihole) doing the caching as well on top of this container
PRIVATE_ADDRESS All IPv4 and IPv6 CIDRs private ranges Comma separated list of CIDRs or single IP addresses. Note that the default setting prevents DNS rebinding
CHECK_DNS on on or off. Check resolving github.com using 127.0.0.1:53 at start
IPV4 on on or off. Uses DNS resolution for IPV4
IPV6 off on or off. Uses DNS resolution for IPV6. Do not enable if you don't have IPV6
UPDATE_PERIOD 24h Period to update block lists and restart Unbound. Set to 0 to disable.

Extra configuration

You can bind mount an Unbound configuration file include.conf to be included in the Unbound server section with -v $(pwd)/include.conf:/unbound/include.conf:ro, see Unbound configuration documentation

Golang API

If you want to use the Go code I wrote, you can see tiny examples of DoT and DoH resolvers and servers using the API developed.

Connect clients to it

Option 1: Router (recommended)

All machines connected to your router will use the 1.1.1.1 encrypted DNS by default

Configure your router to use the LAN IP address of your Docker host as its primary DNS address.

Diagram router

To ensure network clients cannot use another DNS, you might want to

Option 2: Client, one by one

You have to configure each machine connected to your router to use the Docker host as their DNS server.

Diagram clients

Docker containers

Connect other Docker containers by specifying the DNS to be the host IP address 127.0.0.1:

docker run -it --rm --dns=127.0.0.1 alpine

For docker-compose.yml:

version: '3'
services:
  test:
    image: alpine:3.11
    network_mode: bridge
    dns:
      - 127.0.0.1

If the containers are in the same Docker network, you can simply set the dns to the LAN IP address of the DNS container (i.e. 10.0.0.5)

Windows

  1. Open the control panel and follow the instructions shown on the screenshots below.

Windows screenshot 1

Windows screenshot 2

Windows screenshot 3

Windows screenshot 4

Windows screenshot 5

Enter the IP Address of your Docker host as the Preferred DNS server (192.168.1.210 in my case) You can set the Cloudflare DNS server address 1.1.1.1 as an alternate DNS server although you might want to leave this blank so that no domain name request is in plaintext.

Windows screenshot 6

Windows screenshot 7

When closing, Windows should try to identify any potential problems. If everything is fine, you should see the following message:

Windows screenshot 8

Mac OS

Follow the instructions at https://support.apple.com/kb/PH25577

Linux

You probably know how to do that. Otherwise you can usually modify the first line of /etc/resolv.conf by changing the IP address of your DNS server.

Android

See this

iOS

See this

Firewall considerations

This container requires the following connections:

Verify DNS connection

  1. Verify that you use Cloudflare DNS servers: https://www.dnsleaktest.com with the Standard or Extended test
  2. Verify that DNS SEC is enabled: https://en.internet.nl/connection

Note that https://1.1.1.1/help does not work as the container is not a client to Cloudflare servers but a forwarder intermediary. Hence https://1.1.1.1/help does not detect a direct connection to them.

Go API

Some packages are exposed publicly through the pkg directory.

The API is at v1.x.x but (shame on me) is not stable and subject to change without changing major version. If you need it to be stable, please create an issue and I'll see what I can do.

For now, it is used by the gluetun project for its DNS over TLS usage.

Development

Development setup

Using VSCode and Docker

  1. Install Docker
    • On Windows, share a drive with Docker Desktop and have the project on that partition
    • On OSX, share your project directory with Docker Desktop
  2. With Visual Studio Code, install the remote containers extension
  3. In Visual Studio Code, press on F1 and select Remote-Containers: Open Folder in Container...
  4. Your dev environment is ready to go!... and it's running in a container :+1:

Locally

  1. Install Go, Docker and Git

  2. Install dependencies

    go mod download
  3. Install golangci-lint

Commands available

# Build the binary
go build cmd/main.go
# Test the code
go test ./...
# Lint the code
golangci-lint run
# Build the Docker image
docker build -t qmcgaw/dns .

See Contributing for more information on how to contribute to this repository.