A toy to deal DNS over HTTPS and more!
Dealdoh is a powerful DNS-over-HTTPS (DoH) proxy server written in PHP.
It can be use as a DoH proxy server or a client.
Dealdoh also attempts to provide a low-level abstraction layer for DNS messaging.
Dealdoh can be use in different manners and for different purposes. It attempts to achieve the following goals:
- provide a DoH middleware PSR-15 compliant which can be use in any PHP application to act as a DNS proxy server.
- provide a variety of DNS stub resolver.
- provide a large panel of DNS clients.
- provide a low-level abstraction layer for development around DNS.
Dealdoh also comes with a dealdoh-client embedding the following features:
- an application implementing Dealdoh middleware and ready to be run as a micro-service.
- a DNS CLI client to make DNS queries, configure DNS upstreams, etc...
- Provide a DoH proxy server which can be simply plug as a middleware on any PHP 7.3 application. Only require a web-server.
- Create and forward DNS messages in different format to different type of DNS upstream resolvers.
- Use a pool of DNS upstream resolvers to send queries with a fallback mechanism.
- Compatible with a variety of DNS protocols: RFC-1035 (TCP/UDP), RFC-8484 (DoH), Google DoH API.
- Provide a DNS low-level abstraction layer for DNS development.
- Make DNS query from the command-line and provide results in JSON
- Improve robustness and compliance of current DNS clients
- Ability to choose a DNS upstream fallback/selection strategy
- Good documentation
If you wish to get started quickly, you might want to use dealdoh-client which offers a ready-to-use implementation.
- PHP 7.3
- Web server
- HTTPS enabled with valid certificates (self-signed certificates can work but it depends of the DOH client)
To get trusted certificates in a local environment, I recommend you to use mkcert which generate for you a local Certificate Authority, and create locally trusted certificates with it. Take 3 minutes to check its really simple documentation for your OS. (since installation differs on each OS)
- Install Dealdoh as a dependency:
composer require noglitchyo/dealdoh
-
You will need a PSR-7 ServerRequest if you wish to directly use the
DohProxy::forward()
method. Please check those cool implementations below:- https://github.com/Nyholm/psr7 -
composer require nyholm/psr7
- https://github.com/guzzle/psr7 -
composer require guzzle/psr7
- https://github.com/zendframework/zend-diactoros -
composer require zendframework/zend-diactoros
- https://github.com/Nyholm/psr7 -
-
Configure your middleware/entrypoint to call Dealdoh's
DohProxy::forward()
As stated before, DohProxy::forward()
method consumes PSR-7 ServerRequest to make the integration easier.
The example below illustrates how to use two DNS upstream resolvers which are using different protocols. In this example, the used protocols are TCP/UDP (RFC-1035) and DoH (RFC-8484). Two types of DNS client who can handle each of the DNS protocols used by our upstreams are injected to handle those upstreams.
<?php
$dnsMessageFactory = new \NoGlitchYo\Dealdoh\Factory\Dns\MessageFactory();
$dnsResolver = new \NoGlitchYo\Dealdoh\Service\DnsPoolResolver(
new \NoGlitchYo\Dealdoh\Entity\DnsUpstreamPool([
'dns://8.8.8.8:53',
'https://cloudflare-dns.com/dns-query',
]),
[
new \NoGlitchYo\Dealdoh\Client\DohClient(
new \Http\Adapter\Guzzle6\Client(new \GuzzleHttp\Client()),
$dnsMessageFactory
),
new \NoGlitchYo\Dealdoh\Client\StdClient(
new \Socket\Raw\Factory(),
$dnsMessageFactory
),
]
);
$dnsProxy = new \NoGlitchYo\Dealdoh\DohProxy(
$dnsResolver,
$dnsMessageFactory,
new \NoGlitchYo\Dealdoh\Factory\DohHttpMessageFactory($dnsMessageFactory)
);
/** @var $response \Psr\Http\Message\ResponseInterface */
$response = $dnsProxy->forward(/* Expect a \Psr\Http\Message\RequestInterface object */);
- Testing the installation
First, be aware that usually, DoH client/server will send/receive DNS requests on the following path:
/dns-query
as recommended in RFC-8484.
Make sure your Dealdoh's entrypoint has been configured to listen on this route or configure your client accordingly if it is possible.
A large variety of client already exists than you can easily find on Internet. For testing purpose, I advise the one below:
-
Using dealdoh-client
-
Using the doh-client from Facebook Experimental
To make it easier, I created a Docker image that you can directly pull and run by running:
docker run --name dohfb -it noglitchyo/facebookexperimental-doh-proxy doh-client --domain <DEALDOH_ENTRYPOINT> --qname google.com --dnssec --insecure
Replace the <DEALDOH_ENTRYPOINT> with the host of your entrypoint for Dealdoh.
(Tips: pass the --insecure option to doh-client if you are using self-signed certificates #notDocumented)
Please, check how to use the client.
- Using client from Web Browser
Mozilla Firefox provides a Trusted Recursive Resolver who can be configured to query DoH servers.
I advise you to read this really good article from Daniel Stenberg which will give you lot of details about this TRR and how to configure it like a pro.
Please check the browser implementations list.
Checkout some really simple integration examples to get a glimpse on how it can be done:
If you wish to run the test, checkout the project and run the test with:
composer test
Get started here CONTRIBUTING.md.
This project is licensed under the MIT License - see the LICENSE.md file for details
Dealdoh was created for development purpose. I wanted to reach my Docker containers from the browser by their hostnames. So I started to use a Docker image who discover services and register their hostname into a DNS exposed on port 53. But I encountered the following issues:
- I could not change the /etc/hosts file
- I could not change the DNS for my computer (restrictions issue)
I ended up with the following solution: use the DoH client from Firefox and proxy every DNS query to a DoH proxy: Dealdoh.
- https://github.com/reactphp/dns for their really good DNS wire format codec.
- https://github.com/mageddo/dns-proxy-server for its amazing container hostname discovery & DNS Docker image. Combined with Dealdoh it is amazing.
- https://github.com/facebookexperimental/doh-proxy, because their doh-client rocks!