by warther


Build Status Code Coverage Go Report Card GolangCI Go Doc

一键部署 v2ray 到 heroku


DNS Proxy

A simple DNS proxy server that supports all existing DNS protocols including DNS-over-TLS, DNS-over-HTTPS, and DNSCrypt.

Moreover, it can work as a DNS-over-HTTPS and/or DNS-over-TLS server.

How to build

You will need go v1.11 or later.

$ go build


  dnsproxy [OPTIONS]

Application Options:
  -v, --verbose     Verbose output (optional)
  -o, --output=     Path to the log file. If not set, write to stdout.
  -l, --listen=     Listen address (default:
  -p, --port=       Listen port. Zero value disables TCP and UDP listeners (default: 53)
  -h, --https-port= Listen port for DNS-over-HTTPS (default: 0)
  -t, --tls-port=   Listen port for DNS-over-TLS (default: 0)
  -c, --tls-crt=    Path to a file with the certificate chain
  -k, --tls-key=    Path to a file with the private key
  -b, --bootstrap=  Bootstrap DNS for DoH and DoT, can be specified multiple times (default:
  -r, --ratelimit=  Ratelimit (requests per second) (default: 0)
  -z, --cache       If specified, DNS cache is enabled
  -e  --cache-size= Maximum number of elements in the cache. Default size: 1000
  -a, --refuse-any  If specified, refuse ANY requests
  -u, --upstream=   An upstream to be used (can be specified multiple times)
  -f, --fallback=   Fallback resolvers to use when regular ones are unavailable, can be specified multiple times
  -s, --all-servers Use parallel queries to speed up resolving by querying all upstream servers simultaneously

Help Options:
  -h, --help        Show this help message
  --version         Print DNS proxy version


Simple options

Runs a DNS proxy on with a single upstream - Google DNS.

./dnsproxy -u

The same proxy with verbose logging enabled writing it to the file log.txt.

./dnsproxy -u -v -o log.txt

Runs a DNS proxy on with multiple upstreams.

./dnsproxy -l -p 5353 -u -u

Encrypted upstreams

DNS-over-TLS upstream:

./dnsproxy -u tls://

DNS-over-HTTPS upstream with specified bootstrap DNS:

./dnsproxy -u -b

DNSCrypt upstream (DNS Stamp of AdGuard DNS):

./dnsproxy -u sdns://AQIAAAAAAAAAFDE3Ni4xMDMuMTMwLjEzMDo1NDQzINErR_JS3PLCu_iZEIbq95zkSV2LFsigxDIuUso_OQhzIjIuZG5zY3J5cHQuZGVmYXVsdC5uczEuYWRndWFyZC5jb20

DNS-over-HTTPS upstream (DNS Stamp of Cloudflare DNS):

./dnsproxy -u sdns://AgcAAAAAAAAABzEuMC4wLjGgENk8mGSlIfMGXMOlIlCcKvq7AVgcrZxtjon911-ep0cg63Ul-I8NlFj4GplQGb_TTLiczclX57DvMV8Q-JdjgRgSZG5zLmNsb3VkZmxhcmUuY29tCi9kbnMtcXVlcnk

DNS-over-TLS upstream with two fallback servers (to be used when the main upstream is not available):

./dnsproxy -u tls:// -f -f

Encrypted DNS server

Runs a DNS-over-TLS proxy on

./dnsproxy -l --tls-port=853 --tls-crt=example.crt --tls-key=example.key -u -p 0 

Runs a DNS-over-HTTPS proxy on

./dnsproxy -l --https-port=443 --tls-crt=example.crt --tls-key=example.key -u -p 0 

Additional features

Runs a DNS proxy on with rate limit set to 10 rps, enabled DNS cache, and that refuses type=ANY requests.

./dnsproxy -u -r 10 --cache --refuse-any

Runs a DNS proxy on with multiple upstreams and enable parallel queries to all configured upstream servers

./dnsproxy -l -p 5353 -u -u -u tls:// --all-servers

Specifying upstreams for domains

You can specify upstreams that will be used for a specific domain(s). We use the dnsmasq-like syntax (see --server description here).

Syntax: [/[domain1][/../domainN]/]upstreamString

If one or more domains are specified, that upstream (upstreamString) is used only for those domains. Usually, it is used for private nameservers. For instance, if you have a nameserver on your network which deals with xxx.internal.local at then you can specify [/internal.local/], and dnsproxy will send all queries to that nameserver. Everything else will be sent to the default upstreams (which are mandatory!).

  1. An empty domain specification, // has the special meaning of "unqualified names only" ie names without any dots in them.
  2. More specific domains take precedence over less specific domains, so: --upstream=[/] --upstream=[/] will send queries for * to, except *, which will go to
  3. The special server address '#' means, "use the standard servers", so: --upstream=[/] --upstream=[/]# will send queries for * to, except * which will be forwarded as usual.


Sends queries for *.local domains to Other queries are sent to

./dnsproxy -u -u [/local/]

Sends queries for * to except for * which are sent to (as long as other queries).

./dnsproxy -u -u [/] -u [/]#`


  • Configure fallback resolver
  • Listen on TCP/TLS as well
  • gomobile/gobind builds
  • Listen on HTTPS
  • DNSSEC validation
  • 1.0.0 release