Categorygithub.com/qdm12/dns/v2
module
2.0.0-rc6
Repository: https://github.com/qdm12/dns.git
Documentation: pkg.go.dev

# README

DNS over TLS or HTTPs forwarding resolver

Resolver communicating with public DNS recursive servers over encrypted channels with TLS or HTTPs. It also does caching, filtering, split-horizon DNS, IPv6, Prometheus metrucs. It's fully coded in Go and is a single and cross platform binary program.

Announcement: I am currently working on a DNSSEC validator implementation to reach feature parity with the v1.x.x image using Unbound

The :v2.0.0-beta Docker image breaks compatibility with previous images based on v1.x.x versions

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

  • It can be connected to one or more of the following public resolvers over both DNS over TLS and DNS over HTTPS:
  • Random split-horizon DNS (an upstream resolver is picked at random for every request received)
  • Hostnames and IP addresses filtering šŸ›‘
    • for 3 categories: malicious, surveillance and ads
    • auto-update block lists periodically with minimal downtime
    • Specify custom hostnames and IP addresses
  • DNS rebinding protection
  • Prometheus Metrics
  • Container specific features šŸ‹
    • Tiny 16MB Docker image (uncompressed, amd64) based on the empty image scratch
    • Cross CPU architecture support: amd64, i686 (32 bit), ARM 64 bit, ARM 32 bit v7 and v6, ppc64le, s390x and riscv64
    • Running without root

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

Setup

Container setup

docker run -d -p 53:53/udp -p 53:53/tcp qmcgaw/dns:v2.0.0-beta

You can also use docker-compose.yml with:

docker-compose up -d

The image is also available as ghcr.io/qdm12/dns:v2.0.0-beta.

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).

Binary program setup

🚧 waiting for release v2.0.0

Download the prebuilt binary for your platform from the Assets section of the last release on the releases page.

If you run on Linux or OSX, make sure to make it executable with chmod +x dns.

You can then run it by clicking on it or in your terminal with ./dns.

Kubernetes setup

See the KUBERNETES.md document.

Further setup

Settings

The following table lists all environment variables available. For each variable exists a corresponding CLI flag with the same name but in lowercase and with underscores replaced by dashes. For example, the environment variable UPSTREAM_TYPE corresponds to the CLI flag --upstream-type.

Environment variableDefaultDescription
UPSTREAM_TYPEDoTUpstream DNS connection type: DoT for DNS over TLS or DoH for DNS over HTTPS
DOT_RESOLVERScloudflare,googleComma separated list of DNS-over-TLS resolver 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
DOH_RESOLVERScloudflare,googleComma separated list of DNS-over-HTTPS resolver 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
DOT_TIMEOUT3sDNS over TLS dial timeout
DOH_TIMEOUT3sDNS over HTTPs exchange timeout
BLOCK_MALICIOUSonon or off, to block malicious IP addresses and malicious hostnames from being resolved
BLOCK_SURVEILLANCEoffon or off, to block surveillance IP addresses and hostnames from being resolved
BLOCK_ADSoffon or off, to block ads IP addresses and hostnames from being resolved
BLOCK_HOSTNAMEScomma separated list of hostnames to block from being resolved
ALLOWED_HOSTNAMEScomma separated list of hostnames to leave unblocked
ALLOWED_IPScomma separated list of IP addresses to leave unblocked
ALLOWED_CIDRScomma separated list of IP networks (CIDRs) to leave unblocked
BLOCK_IPScomma separated list of IPs to block from being returned to clients
BLOCK_CIDRScomma separated list of IP networks (CIDRs) to block from being returned to clients
LOG_LEVELinfodebug, info, warning or error
LOG_CALLERhiddenhidden or short
MIDDLEWARE_LOG_ENABLEDoffon or off
MIDDLEWARE_LOG_DIRECTORY/var/log/dns/Any valid file path
MIDDLEWARE_LOG_REQUESTSoffon or off to log DNS requests to the file path specified
MIDDLEWARE_LOG_RESPONSESoffon or off to log DNS responses to the file path specified
DOT_TIMEOUT3sDuration string to specify the query timeout for DNS over TLS
DOH_TIMEOUT3sDuration string to specify the query timeout for DNS over HTTPS
LISTENING_ADDRESS:53DNS server listening address
CACHE_TYPElrulru or noop. LRU caches DNS responses by least recently used
CACHE_LRU_MAX_ENTRIES10000Number of elements to keep in the LRU cache.
METRICS_TYPEnoopnoop or prometheus
METRICS_PROMETHEUS_ADDRESS:9090HTTP Prometheus server listening address
METRICS_PROMETHEUS_SUBSYSTEMdnsPrometheus metrics prefix/subsystem
MIDDLEWARE_LOCALDNS_ENABLEDonEnable or disable the local DNS middleware
MIDDLEWARE_LOCALDNS_RESOLVERSLocal DNS serversComma separated list of local DNS resolvers to use for local names DNS requests
MIDDLEWARE_SUBSTITUTER_SUBSTITUTIONSJSON encoded list of substitutions. For example [{"name":"github.com","ips":["1.2.3.4"]}]. You can also specify the type, class and ttl, where they default respectively to A/AAAA, IN and 300.
CHECK_DNSonon or off. Check resolving github.com using 127.0.0.1:53 at start
UPDATE_PERIOD24hPeriod to update block lists and restart Unbound. Set to 0 to disable.

Migrate

The v2.x.x version of the image (starting with v2.0.0-beta) is a complete rewrite from scratch in Go.

There are several non-compatible changes between the v1 and v2 images:

  • The following environment variables are now unused: PRIVATE_ADDRESS, IPV4, IPV6. The program logs an explanation if any of these is set when running a v2.x.x image.
  • The following environment variables are now replaced: LISTENINGPORT, PROVIDERS, PROVIDER, CACHING, UNBLOCK, CHECK_UNBOUND, VERBOSITY, VERBOSITY_DETAILS, VALIDATION_LOGLEVEL. The program logs an explanation if any of these is set when running a v2.x.x image.
  • You can no longer bind mount an Unbound configuration file
  • Caching is enabled by default (in memory LRU cache with up to 10,000 items)

Golang API

If you want to use the Go code, you can see tiny examples of DoT and DoH resolvers and servers using the API developed. You can also implement your interfaces to pass as settings to existing constructors to further customize the behavior of the program.

The Go API exposed to the public (pkg/ directory) will stay stable and compatible for a long time and there is no reason so far to change it.

Connect clients to it

Option 1: Router (recommended)

All machines connected to your router will use the DNS server container by default.

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

  • Access your router page, usually at http://192.168.1.1 and login with your credentials
  • Change the DNS settings, which are usually located in Connection settings / Advanced / DNS server
  • If a secondary fallback DNS address is required, use a dull ip address such as the router's IP 192.168.1.1 to force traffic to only go through this container

Diagram router

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

  • Block the outbound UDP 53 port on your router firewall
  • Block the outbound TCP 53 port on your router firewall
  • Block the outbound TCP 853 port on your router firewall, except from your Docker host
  • If you have Deep packet inspection on your router, block DNS over HTTPs on port TCP 443

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
    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

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.

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/dns/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.

# Packages

No description provided by the author
No description provided by the author
No description provided by the author