* Add upstream selector, there are two selector now:
- random selector
- weight random selector
random selector will choose upstream at random; weight random selector will choose upstream at random with weight
Signed-off-by: Sherlock Holo <sherlockya@gmail.com>
* Rewrite config and config file example, prepare for weight round robbin selector
Signed-off-by: Sherlock Holo <sherlockya@gmail.com>
* Replace bad implement of weight random selector with weight round robbin selector, the algorithm is nginx weight round robbin like
Signed-off-by: Sherlock Holo <sherlockya@gmail.com>
* Use new config module
Signed-off-by: Sherlock Holo <sherlockya@gmail.com>
* Disable deprecated DualStack set
Signed-off-by: Sherlock Holo <sherlockya@gmail.com>
* Fix typo
Signed-off-by: Sherlock Holo <sherlockya@gmail.com>
* Optimize upstreamSelector judge
Signed-off-by: Sherlock Holo <sherlockya@gmail.com>
* Fix typo
Signed-off-by: Sherlock Holo <sherlockya@gmail.com>
* Add config timeout unit tips
Signed-off-by: Sherlock Holo <sherlockya@gmail.com>
* Set wrr http client timeout to replace http request timeout
Signed-off-by: Sherlock Holo <sherlockya@gmail.com>
* Add weight value range
Signed-off-by: Sherlock Holo <sherlockya@gmail.com>
* Add a line ending for .gitignore
Signed-off-by: Sherlock Holo <sherlockya@gmail.com>
* Optimize config file style
Signed-off-by: Sherlock Holo <sherlockya@gmail.com>
* Modify Weight type to int32
Signed-off-by: Sherlock Holo <sherlockya@gmail.com>
* Add upstreamError
Signed-off-by: Sherlock Holo <sherlockya@gmail.com>
* Rewrite Selector interface and wrr implement
Signed-off-by: Sherlock Holo <sherlockya@gmail.com>
* Use http module predefined constant to judge req.response.StatusCode
Signed-off-by: Sherlock Holo <sherlockya@gmail.com>
* Use Selector.ReportUpstreamError to report upstream error for evaluation loop in real time
Signed-off-by: Sherlock Holo <sherlockya@gmail.com>
* Make client selector field private
Signed-off-by: Sherlock Holo <sherlockya@gmail.com>
* Replace config file url to URL
Add miss space for 'weight= 50'
Signed-off-by: Sherlock Holo <sherlockya@gmail.com>
* Rewrite Selector.ReportUpstreamError to Selector.ReportUpstreamStatus, report upstream ok in real time
Signed-off-by: Sherlock Holo <sherlockya@gmail.com>
* Fix checkIETFResponse: if upstream OK, won't increase weight
Signed-off-by: Sherlock Holo <sherlockya@gmail.com>
* Fix typo
Signed-off-by: Sherlock Holo <sherlockya@gmail.com>
* Rewrite wrr evaluation, concurrent check upstream and reduce interval to 15s
Signed-off-by: Sherlock Holo <sherlockya@gmail.com>
* Add lvs wrr selector config
Signed-off-by: Sherlock Holo <sherlockya@gmail.com>
* Add DebugReporter interface, when client verbose is true and the selector implements it, will report all upstream weights every 15s
Signed-off-by: Sherlock Holo <sherlockya@gmail.com>
* Rename WeightRoundRobinSelector to NginxWRRSelector
Signed-off-by: Sherlock Holo <sherlockya@gmail.com>
* Add LVSSelector
Signed-off-by: Sherlock Holo <sherlockya@gmail.com>
* Remove useless log
Signed-off-by: Sherlock Holo <sherlockya@gmail.com>
DNS-over-HTTPS
Client and server software to query DNS over HTTPS, using Google DNS-over-HTTPS protocol and IETF DNS-over-HTTPS (RFC 8484).
Guide
Tutorial to setup your own DNS-over-HTTPS (DoH) server. (Thanks to Antoine Aflalo)
Installing
Install Go, at least version 1.10.
(Note for Debian/Ubuntu users: You need to set $GOROOT if you could not get your new version of Go selected by the Makefile.)
First create an empty directory, used for $GOPATH:
mkdir ~/gopath
export GOPATH=~/gopath
To build the program, type:
make
To install DNS-over-HTTPS as Systemd services, type:
sudo make install
By default, Google DNS over HTTPS is used. It should work for most users (except for People's Republic of China). If you need to modify the default settings, type:
sudoedit /etc/dns-over-https/doh-client.conf
To automatically start DNS-over-HTTPS client as a system service, type:
sudo systemctl start doh-client.service
sudo systemctl enable doh-client.service
Then, modify your DNS settings (usually with NetworkManager) to 127.0.0.1.
To test your configuration, type:
dig www.google.com
If it is OK, you will wee:
;; SERVER: 127.0.0.1#53(127.0.0.1)
Uninstalling
To uninstall, type:
sudo make uninstall
The configuration files are kept at /etc/dns-over-https. Remove them manually if you want.
Server Configuration
The following is a typical DNS-over-HTTPS architecture:
+--------------+ +------------------------+
| Application | | Recursive DNS Server |
+-------+------+ +-----------+------------+
| |
+-------+------+ +-----------+------------+
| Client side | | doh-server |
| cache (nscd) | +-----------+------------+
+-------+------+ |
| +--------------------------+ +-----------+------------+
+-------+------+ | HTTP cache server / | | HTTP service muxer |
| doh-client +--+ Content Delivery Network +--+ (Apache, Nginx, Caddy) |
+--------------+ +--------------------------+ +------------------------+
Although DNS-over-HTTPS can work alone, a HTTP service muxer would be useful as you can host DNS-over-HTTPS along with other HTTPS services.
HTTP/2 with at least TLS v1.3 is recommended. OCSP stapling must be enabled, otherwise DNS recursion may happen.
DNSSEC
DNS-over-HTTPS is compatible with DNSSEC, and requests DNSSEC signatures by
default. However signature validation is not built-in. It is highly recommended
that you install unbound or bind and pass results for them to validate DNS
records.
EDNS0-Client-Subnet (GeoDNS)
DNS-over-HTTPS supports EDNS0-Client-Subnet protocol, which submits part of the client's IP address (/24 for IPv4, /56 for IPv6 by default) to the upstream server. This is useful for GeoDNS and CDNs to work, and is exactly the same configuration as most public DNS servers.
Keep in mind that /24 is not enough to track a single user, although it is
precise enough to know the city where the user is located. If you think
EDNS0-Client-Subnet is affecting your privacy, you can set no_ecs = true in
/etc/dns-over-https/doh-client.conf, with the cost of slower video streaming
or software downloading speed.
To ultilize ECS, X-Forwarded-For or X-Real-IP should be enabled on your
HTTP service muxer. If your server is backed by unbound or bind, you
probably want to configure it to enable the EDNS0-Client-Subnet feature as
well.
Protocol compatibility
Google DNS-over-HTTPS Protocol
DNS-over-HTTPS uses a protocol compatible to Google DNS-over-HTTPS, except for absolute expire time is preferred to relative TTL value. Refer to json-dns/response.go for a complete description of the API.
IETF DNS-over-HTTPS Protocol
DNS-over-HTTPS uses a protocol compatible to IETF DNS-over-HTTPS (RFC 8484).
Supported features
Currently supported features are:
- IPv4 / IPv6
- EDNS0 large UDP packet (4 KiB by default)
- EDNS0-Client-Subnet (/24 for IPv4, /56 for IPv6 by default)
The name of the project
This project is named "DNS-over-HTTPS" because it was written before the IETF DoH project. Although this project is compatible with IETF DoH, the project is not affiliated with IETF.
To avoid confusion, you may also call this project "m13253/DNS-over-HTTPS" or anything you like.
License
DNS-over-HTTPS is licensed under the MIT License. You are encouraged to embed DNS-over-HTTPS into your other projects, as long as the license permits.
You are also encouraged to disclose your improvements to the public, so that others may benefit from your modification, in the same way you receive benefits from this project.