This is a Rest/API DNS proxy following the Google JSON/DNS/API spec,
AKA DoH or DNS over HTTPS. Implemented using Flask and dnspython to do the heavy lifting.
Google also supports sending binary DNS query packets to their service. This does not.
It allows you to issue JSON DNS queries and get JSON responses, with the DNS done using an underlying UDP client socket. It really should be ASGI, but its currently WSGI.
In addition to the Google Supported Parameters
, this API also supports the parameter servers as a comma separated list of DNS servers you want your query sent to.
Each server can be specified as either a name or IPv4 address. Names will be resolved using your server's default resolution mechanism
(i.e. the same as the command line).
If you do not specify a servers option, it will default to 8.8.8.8,8.8.4.4 (Google). If you
set the environment variable DOH_SERVERS as a comma separated list of IP Addresses, this will be used instead.
When more than one server is specified, your query will be sent to all the servers, and the
response you get will be the first one received, as specified in the Responder property.
I've added in the property Responder into the JSON reply, with the IP Address of the server that responded.
It will also return the flags AA and QR,
although QR must always be True as this is checked for in the code.
There is also the property Flags which is an array listing which flags are True.
You can run it in the basic Flask HTTP server, but running ./dnsflsk.py and it will answer queries on http://127.0.0.1:5000
e.g.
$ curl 'http://127.0.0.1:5000/dns/api/v1.0/resolv?name=www.google.com'
Note: This form of execution is not suitable for production use, see below.
You can also test out just the resolver code, using the command line utility cmdresolv.py. The only required parameter is -n <name>.
usage: cmdresolv.py [-h] [-s SERVERS] [-t RDTYPE] [-n NAME] [-d] [-c]
Process some integers.
optional arguments:
-h, --help show this help message and exit
-s SERVERS, --servers SERVERS
Comma separated list of server ip addresses
-t RDTYPE, --rdtype RDTYPE
Record type to query (number or name), default=A
-n NAME, --name NAME Name to look-up
-d, --do Set DO bit
-c, --cd Same as --do
For production use, I strongly recommend you simply use the container jamesstevens / doh, or build the container yourself by running
./dkmk.
By default, the container will send its queries to the Google rsolvers 8.8.8.8 & 8.4.4.8. By default
it will also run 5 python/gunicorn threads and load-balance them using nginx.
The number of sessions and the destination DNS servers can be changed using the environment variables
DOH_SESSIONS and DOH_SERVERS, which can be specified at the command line (using docker run -e) or in a file
using docket run --env-file=.
DOH_SERVERS is a comma separated list of IP Addresses.
DOH_SESSIONS is simply a positive integer.
nginx will also do the SSL using the key & certificate in the file certkey.pem, which has been created using a private
certificate authority. The public key for this private CA is in the file myCA.pem.
The server name for the key is doh.jrcs.net which should resolve to 127.0.0.1, so if you start the container with ./dkrun, then run
curl --cacert myCA.pem https://doh.jrcs.net:800/dns/api/v1.0/resolv?name=www.google.com
then it should work fine, but for production use I would recommend you replace the certificate with a publicly verifiable one.
NOTE: the container is designed to run read-only so we would recommend you use this. e.g.
docker run --read-only -it -p 800:800 doh
Content type
Image
Digest
Size
28 MB
Last updated
almost 6 years ago
docker pull jamesstevens/doh