Skip to content

Commit c0fdca0

Browse files
committed
- Added DNSCrypt client
- Added DNSStamp factory - Refactored and reorganized code
1 parent 7a17bb8 commit c0fdca0

File tree

87 files changed

+3002
-759
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+3002
-759
lines changed

README.md

+80-114
Original file line numberDiff line numberDiff line change
@@ -1,148 +1,122 @@
11
# Dealdoh
2-
> A toy to deal DNS over HTTPS and more!
2+
> Play with DNS over HTTPS and much more!
33
4-
Dealdoh is a powerful DNS-over-HTTPS (DoH) proxy server written in PHP.
5-
6-
It can be use as a DoH proxy server or a client.
7-
8-
Dealdoh also attempts to provide a low-level abstraction layer for DNS messaging.
4+
Dealdoh is a DNS-over-HTTPS (DoH) proxy and a library around DNS messaging written in PHP.
95

106
![PHP from Packagist](https://img.shields.io/packagist/php-v/noglitchyo/dealdoh.svg)
117
[![Build Status](https://travis-ci.org/noglitchyo/dealdoh.svg?branch=master)](https://travis-ci.org/noglitchyo/dealdoh)
128
[![codecov](https://codecov.io/gh/noglitchyo/dealdoh/branch/master/graph/badge.svg)](https://codecov.io/gh/noglitchyo/dealdoh)
139
![Scrutinizer code quality (GitHub/Bitbucket)](https://img.shields.io/scrutinizer/quality/g/noglitchyo/dealdoh.svg)
1410
![Packagist](https://img.shields.io/packagist/l/noglitchyo/dealdoh.svg)
1511

16-
## Description
12+
## Overview
1713

18-
Dealdoh can be use in different manners and for different purposes. It attempts to achieve the following goals:
19-
- provide a DoH middleware PSR-15 compliant which can be use in any PHP application to act as a DNS proxy server.
20-
- provide a variety of DNS stub resolver.
21-
- provide a large panel of DNS clients.
22-
- provide a low-level abstraction layer for development around DNS.
14+
This library gives ability to proxy DoH requests and/or to send DNS queries with various modern DNS protocols: DNSCrypt, DoH, GoogleDNS...
2315

24-
Dealdoh also comes with a [dealdoh-client](https://github.com/noglitchyo/dealdoh-client/) embedding the following features:
25-
- an application implementing Dealdoh middleware and ready to be run as a micro-service.
26-
- a DNS CLI client to make DNS queries, configure DNS upstreams, etc...
16+
It attempts to achieve the following goals:
17+
- provide high-compatibility with a large variety of DNS protocols.
18+
- provide a well-designed abstraction layer for development around DNS in PHP.
2719

2820
## Features
2921

30-
- [x] Provide a DoH proxy server which can be simply plug as a middleware on any PHP 7.3 application. Only require a web-server.
31-
- [x] Create and forward DNS messages in different format to different type of DNS upstream resolvers.
32-
- [x] Use a pool of DNS upstream resolvers to send queries with a fallback mechanism.
33-
- [x] Compatible with a variety of DNS protocols: RFC-1035 (TCP/UDP), RFC-8484 (DoH), Google DoH API.
34-
- [x] Provide a DNS low-level abstraction layer for DNS development.
35-
- [x] Make DNS query from the command-line and provide results in JSON
22+
- [x] DoH proxy middleware PSR-15/PSR-7 compliant.
23+
- [x] Create and forward DNS messages to different type of DNS upstream resolvers.
24+
- [x] Forward DNS query through multiple DNS upstream resolvers.
25+
- [x] Compatible with DNS protocols: RFC-1035 (Plain DNS over TCP/UDP), RFC-8484 (DoH), Google DoH API, DNSCrypt
26+
- [x] Abstraction layer around DNS development.
27+
- [x] Read [DNS stamps](https://dnscrypt.info/stamps-specifications)
3628

37-
## Roadmap
29+
## Client
3830

39-
- [ ] Improve robustness and compliance of current DNS clients
40-
- [ ] Ability to choose a DNS upstream fallback/selection strategy
41-
- [ ] Good documentation
31+
[dealdoh-client](https://github.com/noglitchyo/dealdoh-client/) is a CLI utility which offers a ready-to-use implementation
32+
of this library to send and forward DNS queries.
4233

43-
## Getting started
44-
45-
If you wish to get started quickly, you might want to use [dealdoh-client](https://github.com/noglitchyo/dealdoh-client/)
46-
which offers a ready-to-use implementation.
34+
## Library
4735

4836
#### Requirements
4937

5038
- PHP 7.3
5139
- Web server
52-
- HTTPS enabled with valid certificates (self-signed certificates can work but it depends of the DOH client)
53-
54-
To get trusted certificates in a local environment, I recommend you to use [mkcert](https://github.com/FiloSottile/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)
40+
- Optional: HTTPS enabled with valid certificates (self-signed certificates can work but it depends of the DOH client making the queries)
5541

5642
#### Installation
5743

58-
- Install Dealdoh as a dependency:
44+
- Run `composer require noglitchyo/dealdoh`
5945

60-
`composer require noglitchyo/dealdoh`
61-
62-
- You will need a PSR-7 ServerRequest if you wish to directly use the `DohProxy::forward()` method.
63-
Please check those cool implementations below:
46+
- `DohResolverMiddleware::forward()` method consumes PSR-7 ServerRequest.
47+
Some compatible implementations which can be used:
6448
* https://github.com/Nyholm/psr7 - `composer require nyholm/psr7`
6549
* https://github.com/guzzle/psr7 - `composer require guzzle/psr7`
6650
* https://github.com/zendframework/zend-diactoros - `composer require zendframework/zend-diactoros`
67-
68-
- Configure your middleware/entrypoint to call Dealdoh's `DohProxy::forward()`
69-
70-
As stated before, `DohProxy::forward()` method consumes PSR-7 ServerRequest to make the integration easier.
71-
72-
The example below illustrates how to use two DNS upstream resolvers which are using different protocols.
73-
In this example, the used protocols are TCP/UDP (RFC-1035) and DoH (RFC-8484).
74-
Two types of DNS client who can handle each of the DNS protocols used by our upstreams are injected to handle those upstreams.
75-
76-
```php
77-
<?php
78-
$dnsMessageFactory = new \NoGlitchYo\Dealdoh\Factory\Dns\MessageFactory();
79-
$dnsResolver = new \NoGlitchYo\Dealdoh\Service\DnsPoolResolver(
80-
new \NoGlitchYo\Dealdoh\Entity\DnsUpstreamPool([
81-
'dns://8.8.8.8:53',
82-
'https://cloudflare-dns.com/dns-query',
83-
]),
84-
[
85-
new \NoGlitchYo\Dealdoh\Client\DohClient(
86-
new \Http\Adapter\Guzzle6\Client(new \GuzzleHttp\Client()),
87-
$dnsMessageFactory
88-
),
89-
new \NoGlitchYo\Dealdoh\Client\StdClient(
90-
new \Socket\Raw\Factory(),
91-
$dnsMessageFactory
92-
),
93-
]
94-
);
95-
96-
$dnsProxy = new \NoGlitchYo\Dealdoh\DohProxy(
97-
$dnsResolver,
98-
$dnsMessageFactory,
99-
new \NoGlitchYo\Dealdoh\Factory\DohHttpMessageFactory($dnsMessageFactory)
100-
);
101-
102-
/** @var $response \Psr\Http\Message\ResponseInterface */
103-
$response = $dnsProxy->forward(/* Expect a \Psr\Http\Message\RequestInterface object */);
104-
```
51+
- Configure your application to call `DohResolverMiddleware::forward()`
10552
- Testing the installation
10653

107-
First, be aware that usually, DoH client/server will send/receive DNS requests on the following path:
108-
`/dns-query` as recommended in RFC-8484.
109-
Make sure your Dealdoh's entrypoint has been configured to listen on this route or configure your client accordingly if it is possible.
110-
111-
A large variety of client already exists than you can easily find on Internet.
112-
For testing purpose, I advise the one below:
54+
As recommended in RFC-8484, usually, DoH client/server will send/receive DNS requests on the path: `/dns-query`.
55+
Your application should be configured to listen on this route.
11356

114-
* Using [dealdoh-client](https://github.com/noglitchyo/dealdoh-client/)
57+
A large variety of DoH client exists than can be used to test the installation.
11558

116-
* Using the doh-client from [Facebook Experimental](https://github.com/facebookexperimental/doh-proxy)
117-
118-
To make it easier, I created a [Docker image](https://hub.docker.com/) that you can directly pull and run by running:
119-
120-
`docker run --name dohfb -it noglitchyo/facebookexperimental-doh-proxy doh-client --domain <DEALDOH_ENTRYPOINT> --qname google.com --dnssec --insecure`
121-
122-
*Replace the <DEALDOH_ENTRYPOINT> with the host of your entrypoint for Dealdoh.*
123-
124-
(Tips: pass the --insecure option to doh-client if you are using self-signed certificates **#notDocumented**)
125-
126-
Please, check [how to use the client](https://github.com/facebookexperimental/doh-proxy#doh-client).
127-
59+
* [dealdoh-client](https://github.com/noglitchyo/dealdoh-client/)
60+
* [Facebook Experimental](https://github.com/facebookexperimental/doh-proxy)
61+
12862
* Using client from Web Browser
129-
13063
Mozilla Firefox provides a [Trusted Recursive Resolver](https://wiki.mozilla.org/Trusted_Recursive_Resolver) who can be configured to query DoH servers.
13164

132-
I advise you to read [this really good article from Daniel Stenberg](https://daniel.haxx.se/blog/2018/06/03/inside-firefoxs-doh-engine/)
133-
which will give you lot of details about this TRR and how to configure it like a pro.
65+
[This article from Daniel Stenberg](https://daniel.haxx.se/blog/2018/06/03/inside-firefoxs-doh-engine/)
66+
provides a lot of details about TRR and how to configure it.
67+
Please check also [the browser implementations list](https://github.com/curl/curl/wiki/DNS-over-HTTPS#supported-in-browsers-and-clients).
13468

135-
Please check [the browser implementations list](https://github.com/curl/curl/wiki/DNS-over-HTTPS#supported-in-browsers-and-clients).
69+
#### Example
70+
```php
71+
<?php
72+
use GuzzleHttp\Client as GuzzleClient;
73+
use Http\Adapter\Guzzle6\Client as GuzzleClientAdapter;
74+
use NoGlitchYo\Dealdoh\Dns\Client\DnsCryptClient;
75+
use NoGlitchYo\Dealdoh\Dns\Client\DohClient;
76+
use NoGlitchYo\Dealdoh\Dns\Client\PlainDnsClient;
77+
use NoGlitchYo\Dealdoh\Dns\Resolver\DnsUpstreamPoolResolver;
78+
use NoGlitchYo\Dealdoh\Entity\DnsUpstreamPool;
79+
use NoGlitchYo\Dealdoh\Mapper\DnsCrypt\AuthenticatedEncryptionMapper;
80+
use NoGlitchYo\Dealdoh\Mapper\HttpResponseMapper;
81+
use NoGlitchYo\Dealdoh\Mapper\MessageMapper;
82+
use NoGlitchYo\Dealdoh\Middleware\DohResolverMiddleware;
83+
use NoGlitchYo\Dealdoh\Repository\DnsCrypt\CertificateRepository;
84+
use Psr\Http\Message\ResponseInterface;
85+
86+
$messageMapper = new MessageMapper();
87+
88+
// Initialize the DNS clients to use with the resolver
89+
$dnsClients = [
90+
new DohClient(new GuzzleClientAdapter(new GuzzleClient()), $messageMapper),
91+
new PlainDnsClient($messageMapper),
92+
new DnsCryptClient(new AuthenticatedEncryptionMapper(), new CertificateRepository(), $messageMapper)
93+
];
94+
95+
// Initialize the list of DNS upstreams to use to resolve the DNS queries
96+
$dnsUpstreamPool = new DnsUpstreamPool([
97+
'dns://8.8.8.8:53',
98+
'https://cloudflare-dns.com/dns-query',
99+
'sdns://AQcAAAAAAAAAFlsyMDAxOmJjODoxODI0OjczODo6MV0gAyfzz5J-mV9G-yOB4Hwcdk7yX12EQs5Iva7kV3oGtlEgMi5kbnNjcnlwdC1jZXJ0LmFjc2Fjc2FyLWFtcy5jb20',
100+
]);
101+
102+
// Initialize the DNS resolver with the list of upstreams and the list of clients able to exchange with the upstreams
103+
$dnsResolver = new DnsUpstreamPoolResolver($dnsUpstreamPool, $dnsClients);
104+
105+
// Create the ResolverMiddleware with the created DnsResolver
106+
$dohMiddleware = new DohResolverMiddleware($dnsResolver, $messageMapper, new HttpResponseMapper($messageMapper));
107+
108+
/** @var $response ResponseInterface */
109+
$response = $dohMiddleware->forward(/* Expect a \Psr\Http\Message\RequestInterface object */);
110+
```
136111

137-
#### Examples
112+
#### More examples
138113

139114
Checkout some really simple integration examples to get a glimpse on how it can be done:
140115

141116
- [Slim Framework integration](examples/slim-integration/README.md)
142117
- [DoH + Docker + DNS + Hostname Discovery](examples/docker-firefox/README.md)
143118
- [dealdoh-client](https://github.com/noglitchyo/dealdoh-client/)
144119

145-
146120
## Testing
147121

148122
If you wish to run the test, checkout the project and run the test with:
@@ -157,22 +131,12 @@ Get started here [CONTRIBUTING.md](CONTRIBUTING.md).
157131

158132
This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details
159133

160-
## Why Dealdoh?
161-
162-
Dealdoh was created for development purpose. I wanted to reach my Docker containers from the browser by their hostnames.
163-
So I started to use a [Docker image who discover services and register their hostname into a DNS](https://github.com/mageddo/dns-proxy-server) exposed on port 53.
164-
But I encountered the following issues:
165-
- I could not change the /etc/hosts file
166-
- I could not change the DNS for my computer (restrictions issue)
167-
168-
I ended up with the following solution: use the DoH client from Firefox and proxy every DNS query to a DoH proxy: Dealdoh.
169-
170134
## Acknowledgments
171135

172-
* https://github.com/reactphp/dns for their really good DNS wire format codec.
173-
* https://github.com/mageddo/dns-proxy-server for its amazing container hostname discovery & DNS Docker image.
174-
Combined with Dealdoh it is amazing.
175-
* https://github.com/facebookexperimental/doh-proxy, because their doh-client rocks!
136+
* https://github.com/reactphp/dns
137+
* https://github.com/mageddo/dns-proxy-server
138+
* https://github.com/facebookexperimental/doh-proxy
139+
* https://github.com/DNSCrypt/dnscrypt-proxy
176140

177141
## References
178142

@@ -183,4 +147,6 @@ Combined with Dealdoh it is amazing.
183147
- [PSR-7](https://www.php-fig.org/psr/psr-7/)
184148
- [PSR-15](https://www.php-fig.org/psr/psr-15/)
185149
- [PSR-18](https://www.php-fig.org/psr/psr-18/)
150+
- [DNSCrypt](https://dnscrypt.info/protocol)
151+
- [DNS Stamps](https://dnscrypt.info/stamps-specifications)
186152
- [Wiki page DNS-over-HTTPS from Curl](https://github.com/curl/curl/wiki/DNS-over-HTTPS)

composer.json

+6-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
"dns-over-https",
88
"doh",
99
"dns-proxy",
10-
"dns-client"
10+
"dns-client",
11+
"dns-crypt"
1112
],
1213
"license": "MIT",
1314
"authors": [
@@ -17,16 +18,18 @@
1718
}
1819
],
1920
"require": {
20-
"clue/socket-raw": "^1.4",
2121
"ext-json": "*",
2222
"ext-sockets": "*",
23+
"ext-sodium": "*",
2324
"nyholm/psr7": "^1.1",
2425
"php": "^7.3",
2526
"psr/http-client": "*",
2627
"psr/log": "^1.1",
2728
"psr/http-server-middleware": "^1.0",
29+
"psr/http-server-handler": "^1.0",
2830
"php-http/guzzle6-adapter": "^2.0",
29-
"react/dns": "^1.3.0"
31+
"react/dns": "^1.3.0",
32+
"paragonie/sodium_compat": "^1.13"
3033
},
3134
"require-dev": {
3235
"react/datagram": "^1.5",

examples/docker-firefox/docker/src/public/index.php

+13-13
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
<?php declare(strict_types=1);
22

33
use Http\Adapter\Guzzle6\Client;
4-
use NoGlitchYo\Dealdoh\Client\DohClient;
5-
use NoGlitchYo\Dealdoh\Client\StdClient;
6-
use NoGlitchYo\Dealdoh\Client\Transport\DnsOverTcpTransport;
7-
use NoGlitchYo\Dealdoh\Client\Transport\DnsOverUdpTransport;
8-
use NoGlitchYo\Dealdoh\DohProxy;
4+
use NoGlitchYo\Dealdoh\Dns\Client\DohClient;
5+
use NoGlitchYo\Dealdoh\Dns\Client\PlainDnsClient;
6+
use NoGlitchYo\Dealdoh\Dns\Resolver\DnsUpstreamPoolResolver;
97
use NoGlitchYo\Dealdoh\Entity\DnsUpstreamPool;
10-
use NoGlitchYo\Dealdoh\Factory\Dns\MessageFactory;
11-
use NoGlitchYo\Dealdoh\Factory\DohHttpMessageFactory;
12-
use NoGlitchYo\Dealdoh\Service\DnsPoolResolver;
8+
use NoGlitchYo\Dealdoh\Mapper\HttpResponseMapper;
9+
use NoGlitchYo\Dealdoh\Mapper\MessageMapper;
10+
use NoGlitchYo\Dealdoh\Middleware\DohResolverMiddleware;
11+
use NoGlitchYo\Dealdoh\Service\Transport\DnsOverTcpTransport;
12+
use NoGlitchYo\Dealdoh\Service\Transport\DnsOverUdpTransport;
1313
use Psr\Http\Message\ResponseInterface;
1414
use Psr\Http\Message\ServerRequestInterface;
1515
use Slim\App;
@@ -21,8 +21,8 @@
2121
$app->any(
2222
'/dns-query',
2323
function (ServerRequestInterface $request, ResponseInterface $response, $args) {
24-
$dnsMessageFactory = new MessageFactory();
25-
$dnsResolver = new DnsPoolResolver(
24+
$dnsMessageFactory = new MessageMapper();
25+
$dnsResolver = new DnsUpstreamPoolResolver(
2626
new DnsUpstreamPool(
2727
[
2828
'dps:53',
@@ -37,18 +37,18 @@ function (ServerRequestInterface $request, ResponseInterface $response, $args) {
3737
),
3838
$dnsMessageFactory
3939
),
40-
new StdClient(
40+
new PlainDnsClient(
4141
$dnsMessageFactory,
4242
new DnsOverTcpTransport(),
4343
new DnsOverUdpTransport()
4444
),
4545
]
4646
);
4747

48-
$dnsProxy = new DohProxy(
48+
$dnsProxy = new DohResolverMiddleware(
4949
$dnsResolver,
5050
$dnsMessageFactory,
51-
new DohHttpMessageFactory($dnsMessageFactory)
51+
new HttpResponseMapper($dnsMessageFactory)
5252
);
5353

5454
return $dnsProxy->forward($request);

0 commit comments

Comments
 (0)