nelexa/guzzle-doh-middleware

适用于Guzzle >= 6.0的DNS over Https (DoH)中间件

1.0.1 2022-03-04 10:32 UTC

This package is auto-updated.

Last update: 2024-09-06 10:15:10 UTC


README

nelexa/guzzle-doh-middleware

guzzle-doh-middleware

一个针对Guzzle的DNS over HTTPS (DoH)中间件。

Latest Stable Version PHP Version Require Tests Analysis Build Status Scrutinizer Code Quality Code Coverage License

目标

  • 在发送HTTP请求之前,通过DoH解析域名。
  • 通过DNS数据包欺骗绕过被屏蔽的网站。
  • 支持通过PSR-6和PSR-16兼容的包缓存DNS响应。
  • 支持多个DoH提供商。

安装

composer require nelexa/guzzle-doh-middleware

用法

use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use Nelexa\Doh\DohMiddleware;

// Create default HandlerStack
$stack = HandlerStack::create();

// Add this middleware to the top with `push`
$stack->push(DohMiddleware::create(), 'doh');

// Initialize the client with the handler option
$client = new Client(['handler' => $stack]);

设置缓存

配置DNS请求的缓存非常重要,这样您就不必在每个HTTP请求中都联系DNS服务器来解析域名。

安装一个PSR-6或PSR-16兼容的缓存包。

例如,您可以安装流行的symfony/cache包。

composer require symfony/cache

PSR-6 redis缓存初始化示例

$cache = new \Symfony\Component\Cache\Adapter\RedisAdapter(
    \Symfony\Component\Cache\Adapter\RedisAdapter::createConnection()
);

PSR-16 redis缓存初始化示例

$cache = new \Symfony\Component\Cache\Psr16Cache(
    new \Symfony\Component\Cache\Adapter\RedisAdapter(
        \Symfony\Component\Cache\Adapter\RedisAdapter::createConnection()
    )
);

在创建中间件时,您可以将配置的缓存作为第一个参数传递。
如果您没有传递参数或传递null,则缓存将仅存储在PHP进程的生命周期内。

$stack->push(DohMiddleware::create($cache), 'doh');

设置DoH服务器

在创建中间件时,您可以通过第二个参数指定要使用的DoH服务器。它们将以随机顺序选择。

默认值为Cloudflare (for Mozilla)Google

示例

$dohServers = [
    'https://mozilla.cloudflare-dns.com/dns-query',
    'https://dns.google/dns-query',
    'https://doh.cleanbrowsing.org/doh/security-filter',
    \Nelexa\Doh\DohServers::SERVER_ADGUARD_FAMILY,
    'https://doh.opendns.com/dns-query',
];
$stack->push(DohMiddleware::create($cache, $dohServers), 'doh');

设置日志器和调试

在创建中间件时,您可以将PSR-3兼容的日志器作为第三个参数添加。

use Monolog\Logger;
use Monolog\Handler\StreamHandler;

$logger = new Logger('doh');
$logger->pushHandler(new StreamHandler('path/to/doh.log', Logger::DEBUG));

$stack->push(DohMiddleware::create(
    cache: $cache,
    logger: $logger
), 'doh');

要调试并将所有DoH请求的输出到控制台,在创建中间件时将第四个参数传递为true

$stack->push(DohMiddleware::create(
    cache: $cache,
    debug: true,
), 'doh');
示例调试信息
*   Trying 104.16.248.249:443...
* TCP_NODELAY set
* connect to 104.16.248.249 port 443 failed: Connection refused
*   Trying 104.16.249.249:443...
* TCP_NODELAY set
* Connected to mozilla.cloudflare-dns.com (104.16.249.249) port 443 (#0)
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: C=US; ST=California; L=San Francisco; O=Cloudflare, Inc.; CN=cloudflare-dns.com
*  start date: Oct 25 00:00:00 2021 GMT
*  expire date: Oct 25 23:59:59 2022 GMT
*  subjectAltName: host "mozilla.cloudflare-dns.com" matched cert's "*.cloudflare-dns.com"
*  issuer: C=US; O=DigiCert Inc; CN=DigiCert TLS Hybrid ECC SHA384 2020 CA1
*  SSL certificate verify ok.
> GET /dns-query?dns=q80BAAABAAAAAAAACmdvb2dsZW1haWwBbAZnb29nbGUDY29tAAABAAE HTTP/1.1
Host: mozilla.cloudflare-dns.com
Accept: application/dns-udpwireformat, application/dns-message
User-Agent: DoH-Client

* old SSL session ID is stale, removing
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: cloudflare
< Date: Thu, 03 Mar 2022 09:58:15 GMT
< Content-Type: application/dns-message
< Connection: keep-alive
< Access-Control-Allow-Origin: *
< Content-Length: 105
< CF-RAY: 6e6183398ec716f0-DME
< 
* Connection #0 to host mozilla.cloudflare-dns.com left intact

请求选项

您可以使用请求选项配置客户端创建和发送的请求。

选项 "doh"

摘要

设置为false以禁用通过DoH解析域名。

类型
  • bool
默认值

true

常量

\Nelexa\Doh\DohMiddleware::OPTION_DOH_ENABLED

// Disable DoH for concrete request
$client->request('GET', 'https://...', [
    'doh' => false,
]);

要默认禁用DoH中间件,在创建HTTP客户端时传递false作为doh选项。

$stack = HandlerStack::create();
$stack->push(DohMiddleware::create($cache), 'doh');
$client = new Client([
    'handler' => $stack,
    'doh' => false,
]);

选项 "doh_ttl"

摘要

强制设置解析结果缓存时间。如果未传递此选项或传递null,则使用DNS服务器的缓存时间。

类型
  • integer
  • \DateInterval
  • null
默认值

null

常量

\Nelexa\Doh\DohMiddleware::OPTION_DOH_TTL

$client->request('GET', 'https://...', [
    'doh_ttl' => \DateInterval::createFromDateString('1 hour'),
]);

选项 "doh_shuffle"

摘要

设置为true以在解析域名并收到多个IP地址作为结果时,以随机顺序对IP地址进行洗牌。

类型
  • bool
默认值

false

常量

\Nelexa\Doh\DohMiddleware::OPTION_DOH_SHUFFLE

// Enable shuffle ip addresses
$client->request('GET', 'https://...', [
    'doh_shuffle' => true,
]);

默认情况下启用对所有请求的IP混排,在创建HTTP客户端时,将true传递给ttl_shuffle选项。

$stack = HandlerStack::create();
$stack->push(DohMiddleware::create($cache), 'doh');
$client = new Client([
    'handler' => $stack,
    'doh_shuffle' => true,
]);

Symfony配置DI

# config/services.yaml
parameters:
    
    doh.servers:
        - 'https://mozilla.cloudflare-dns.com/dns-query',
        - 'https://dns.google/dns-query',
        - 'https://doh.opendns.com/dns-query'

services:

    app.client.doh_middleware:
        factory: Nelexa\Doh\DohMiddleware::create
        class: Nelexa\Doh\DohMiddleware
        arguments:
            - '@cache.app'
            - '%doh.servers%'
            - '@logger'
            - '%kernel.debug%'

    app.client.handler_stack:
        factory: GuzzleHttp\HandlerStack::create
        class: GuzzleHttp\HandlerStack
        calls:
            - [ push, [ '@app.client.doh_middleware' ] ]

    app.client:
        class: GuzzleHttp\Client
        arguments:
            app.client:
            class: GuzzleHttp\Client
            arguments:
                - handler: '@app.client.handler_stack'
                  doh: true
                  # doh_ttl: 3600
                  # doh_shuffle: true

    # Aliases
    GuzzleHttp\Client: '@app.client'

致谢

变更日志

变更记录在发布页面中。

许可证

MIT许可证(MIT)。更多信息请参阅LICENSE