mirror of
https://github.com/AdguardTeam/AdGuardHome.git
synced 2026-06-27 19:31:26 +00:00
Pull request: AGDNS-2848-upd-dnsproxy-doh
Squashed commit of the following: commit e06d9abfe4de16507d8a87e98b376a241729c010 Merge: 566afb9bf806855dc1Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Thu Mar 12 08:35:39 2026 +0700 Merge remote-tracking branch 'origin/master' into AGDNS-2848-upd-dnsproxy-doh commit 566afb9bf03d282fbe4f150e2db8664c6a0de23b Merge: 39688da82354ce04a5Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Wed Mar 11 17:58:44 2026 +0700 Merge remote-tracking branch 'origin/master' into AGDNS-2848-upd-dnsproxy-doh commit 39688da82e6f11e1c5e81fd6c0e0f1354bba0970 Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Wed Mar 11 08:17:37 2026 +0700 all: upd dnsproxy commit 168847c56ceabbf1afdff3ffe0a90102fb53643b Merge: 7463c0733a15c72493Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Wed Mar 11 08:09:55 2026 +0700 Merge remote-tracking branch 'origin/master' into AGDNS-2848-upd-dnsproxy-doh commit 7463c07339bd6c96ab3d8dd922ee6233aec50a88 Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Tue Mar 10 16:32:02 2026 +0700 all: upd dnsproxy commit c605ec946588cc2271d2ba83e71986917798c752 Merge: 07da0bbe5ad9cb3e8dAuthor: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Tue Mar 10 08:56:14 2026 +0700 Merge remote-tracking branch 'origin/master' into AGDNS-2848-upd-dnsproxy-doh commit 07da0bbe57b3a2836c870d522363f9233ee5dc75 Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Mon Mar 9 12:36:11 2026 +0700 all: imp code commit bfdf4a4467893ae4b445e8c947e0f60d12675e40 Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Fri Mar 6 15:58:20 2026 +0700 all: upd dnsproxy commit 097b64b450a2a89b09d8ff066a191fe7122e8de0 Merge: bff075daf01dd10e49Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Fri Mar 6 12:36:56 2026 +0700 Merge branch 'master' into AGDNS-2848-upd-dnsproxy-doh # Conflicts: # go.mod # go.sum # internal/dnsforward/config.go commit bff075dafbd8dc3482a5cf9d8eb24584713b109b Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Fri Mar 6 12:34:48 2026 +0700 all: upd dnsproxy commit 5956d01b0d87a84a6b1155608258dd37949eee4f Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Fri Mar 6 11:59:26 2026 +0700 all: upd dnsproxy commit 2e2091e3db9b0309faa476961d136fb1c9bd39e9 Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Wed Feb 25 11:31:12 2026 +0700 all: upd dnsproxy, rm beforerequest commit 44e5f1207e5201c6527f2f316ceafac2b3593868 Merge: d474280e982f2ac68aAuthor: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Fri Feb 20 10:38:45 2026 +0700 Merge remote-tracking branch 'origin/master' into AGDNS-3523-upd-dnsproxy commit d474280e944ecfab6bfd877089fc7ad79f3ecfed Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Thu Feb 19 20:07:13 2026 +0700 all: upd dnsproxy commit b19a7cd851c62fafafed340825e7ad269f5a578a Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Thu Feb 19 13:50:05 2026 +0700 all: upd dnsproxy commit 56b67426e0ff804880ac74536f01cdbc4db3605b Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Thu Feb 19 10:06:42 2026 +0700 all: imp code commit 716f8186bd5e74152b0677d57a26ca4fc2f991a9 Merge: 96c178bb394a3a4fa6Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Thu Feb 19 09:21:49 2026 +0700 Merge remote-tracking branch 'origin/master' into AGDNS-3523-upd-dnsproxy # Conflicts: # go.mod # go.sum commit 96c178bb3d2b6cfcd1cb9377b71c3c23987eab6e Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Tue Feb 17 10:27:27 2026 +0700 next: dnssvc todos commit f84834f68f399e6ce841c7c5765f3180acb3c417 Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Tue Feb 17 09:11:54 2026 +0700 all: upd dnsproxy commit 6ad1a30c087256374882b6e24f5c879121c34834 Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Mon Feb 16 13:17:09 2026 +0700 scripts: fix commit cc7c6d3181a427f4e79f4af686d3363f5c341001 Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Mon Feb 16 13:11:24 2026 +0700 all: upd golibs commit cd2662cf6bc52216c9b2ec55ffd34a8ade434170 Merge: d3d2bd6f2a165cdb68Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Mon Feb 16 11:49:19 2026 +0700 Merge remote-tracking branch 'refs/remotes/origin/master' into AGDNS-3523-upd-dnsproxy commit d3d2bd6f27de6b721f73a48e1c4c8e1187d51046 Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Fri Feb 6 12:23:43 2026 +0700 all: todo commit e16df07e1062e67cc3d085048c4399cf375997bf Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Fri Feb 6 12:06:37 2026 +0700 dnsforward: upd dnsproxy
This commit is contained in:
parent
806855dc1c
commit
5558089e7b
10 changed files with 188 additions and 153 deletions
2
go.mod
2
go.mod
|
|
@ -3,7 +3,7 @@ module github.com/AdguardTeam/AdGuardHome
|
|||
go 1.25.7
|
||||
|
||||
require (
|
||||
github.com/AdguardTeam/dnsproxy v0.79.0
|
||||
github.com/AdguardTeam/dnsproxy v0.80.0
|
||||
github.com/AdguardTeam/golibs v0.35.8
|
||||
github.com/AdguardTeam/urlfilter v0.23.2
|
||||
github.com/NYTimes/gziphandler v1.1.1
|
||||
|
|
|
|||
6
go.sum
6
go.sum
|
|
@ -4,12 +4,10 @@ cloud.google.com/go/auth v0.18.1 h1:IwTEx92GFUo2pJ6Qea0EU3zYvKnTAeRCODxfA/G5UWs=
|
|||
cloud.google.com/go/auth v0.18.1/go.mod h1:GfTYoS9G3CWpRA3Va9doKN9mjPGRS+v41jmZAhBzbrA=
|
||||
cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
|
||||
cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10=
|
||||
github.com/AdguardTeam/dnsproxy v0.79.0 h1:wvNTny4u6x95bWGRyyqr1PVkHbYyAhPsv4EvnqVlmf4=
|
||||
github.com/AdguardTeam/dnsproxy v0.79.0/go.mod h1:gwr+7Dc0e7QddQLC9JLGjL5NSKcqw0ESsNMRI5Q67Ps=
|
||||
github.com/AdguardTeam/dnsproxy v0.80.0 h1:PttgkZfnAe9itH8vGVhpOTS9FLGZq8A49Qa7l4+/11Q=
|
||||
github.com/AdguardTeam/dnsproxy v0.80.0/go.mod h1:gwr+7Dc0e7QddQLC9JLGjL5NSKcqw0ESsNMRI5Q67Ps=
|
||||
github.com/AdguardTeam/golibs v0.35.8 h1:KsyF3SWwj05Ey4GiAWU6FGD9oJTDNMp1ixVdS+Nw50M=
|
||||
github.com/AdguardTeam/golibs v0.35.8/go.mod h1:kuLQ0yNRTl0Em2FmmXtSri7ZdVT7p62oojyc51RvP38=
|
||||
github.com/AdguardTeam/urlfilter v0.23.2-0.20260226112426-a60617ec1594 h1:VoT4UKSgRcbIpsCGLuVenMWFFdi1834SUkc9+hp5Ivs=
|
||||
github.com/AdguardTeam/urlfilter v0.23.2-0.20260226112426-a60617ec1594/go.mod h1:JteAKoeka1Yr2oZ3P94dqYBfPOHWyFaOcu3uZa9Yl+I=
|
||||
github.com/AdguardTeam/urlfilter v0.23.2 h1:EiS/PQZO/X2S6cduFW6BBoRLyjd6SqZj1ZiFbU1KaFE=
|
||||
github.com/AdguardTeam/urlfilter v0.23.2/go.mod h1:JteAKoeka1Yr2oZ3P94dqYBfPOHWyFaOcu3uZa9Yl+I=
|
||||
github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk=
|
||||
|
|
|
|||
|
|
@ -1,127 +0,0 @@
|
|||
package dnsforward
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
|
||||
"github.com/AdguardTeam/dnsproxy/proxy"
|
||||
"github.com/AdguardTeam/golibs/errors"
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
// type check
|
||||
var _ proxy.BeforeRequestHandler = (*Server)(nil)
|
||||
|
||||
// HandleBefore is the handler that is called before any other processing,
|
||||
// including logs. It performs access checks and puts the ClientID, if there
|
||||
// is one, into the server's cache.
|
||||
//
|
||||
// TODO(d.kolyshev): Extract to separate package.
|
||||
func (s *Server) HandleBefore(
|
||||
_ *proxy.Proxy,
|
||||
pctx *proxy.DNSContext,
|
||||
) (err error) {
|
||||
// TODO(f.setrakov): Obtain context from arguments.
|
||||
ctx := context.TODO()
|
||||
clientID, err := s.clientIDFromDNSContext(ctx, pctx)
|
||||
if err != nil {
|
||||
return &proxy.BeforeRequestError{
|
||||
Err: fmt.Errorf("getting clientid: %w", err),
|
||||
Response: s.NewMsgSERVFAIL(pctx.Req),
|
||||
}
|
||||
}
|
||||
|
||||
blocked, _ := s.IsBlockedClient(pctx.Addr.Addr(), clientID)
|
||||
if blocked {
|
||||
return s.preBlockedResponse(pctx)
|
||||
}
|
||||
|
||||
if len(pctx.Req.Question) == 1 {
|
||||
q := pctx.Req.Question[0]
|
||||
qt := q.Qtype
|
||||
host := aghnet.NormalizeDomain(q.Name)
|
||||
if s.access.isBlockedHost(host, qt) {
|
||||
// TODO(s.chzhen): Pass context.
|
||||
s.logger.DebugContext(
|
||||
context.TODO(),
|
||||
"request is in access blocklist",
|
||||
"dns_type", dns.Type(qt),
|
||||
"host", host,
|
||||
)
|
||||
|
||||
return s.preBlockedResponse(pctx)
|
||||
}
|
||||
}
|
||||
|
||||
if clientID != "" {
|
||||
key := [8]byte{}
|
||||
binary.BigEndian.PutUint64(key[:], pctx.RequestID)
|
||||
s.clientIDCache.Set(key[:], []byte(clientID))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// clientIDFromDNSContext extracts the client's ID from the server name of the
|
||||
// client's DoT or DoQ request or the path of the client's DoH. If the protocol
|
||||
// is not one of these, clientID is an empty string and err is nil.
|
||||
func (s *Server) clientIDFromDNSContext(
|
||||
ctx context.Context,
|
||||
pctx *proxy.DNSContext,
|
||||
) (clientID string, err error) {
|
||||
proto := pctx.Proto
|
||||
if proto == proxy.ProtoHTTPS {
|
||||
clientID, err = clientIDFromDNSContextHTTPS(pctx)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("checking url: %w", err)
|
||||
} else if clientID != "" {
|
||||
return clientID, nil
|
||||
}
|
||||
|
||||
// Go on and check the domain name as well.
|
||||
} else if proto != proxy.ProtoTLS && proto != proxy.ProtoQUIC {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
hostSrvName := s.conf.TLSConf.ServerName
|
||||
if hostSrvName == "" {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
cliSrvName, err := clientServerName(ctx, s.logger, pctx, proto)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("getting client server-name: %w", err)
|
||||
}
|
||||
|
||||
clientID, err = clientIDFromClientServerName(
|
||||
hostSrvName,
|
||||
cliSrvName,
|
||||
s.conf.TLSConf.StrictSNICheck,
|
||||
)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("clientid check: %w", err)
|
||||
}
|
||||
|
||||
return clientID, nil
|
||||
}
|
||||
|
||||
// errAccessBlocked is a sentinel error returned when a request is blocked by
|
||||
// access settings.
|
||||
var errAccessBlocked errors.Error = "blocked by access settings"
|
||||
|
||||
// preBlockedResponse returns a protocol-appropriate response for a request that
|
||||
// was blocked by access settings.
|
||||
func (s *Server) preBlockedResponse(pctx *proxy.DNSContext) (err error) {
|
||||
if pctx.Proto == proxy.ProtoUDP || pctx.Proto == proxy.ProtoDNSCrypt {
|
||||
// Return nil so that dnsproxy drops the connection and thus
|
||||
// prevent DNS amplification attacks.
|
||||
return errAccessBlocked
|
||||
}
|
||||
|
||||
return &proxy.BeforeRequestError{
|
||||
Err: errAccessBlocked,
|
||||
Response: s.makeResponseREFUSED(pctx.Req),
|
||||
}
|
||||
}
|
||||
|
|
@ -205,7 +205,7 @@ type TLSConfig struct {
|
|||
// HTTPSListenAddrs should be the addresses AdGuard Home is listening on for
|
||||
// DoH connections. These addresses are announced with DDR. Each item in
|
||||
// the list must be non-nil.
|
||||
HTTPSListenAddrs []*net.TCPAddr
|
||||
HTTPSListenAddrs []netip.AddrPort
|
||||
|
||||
// ServerName is the hostname of the server. Currently, it is only being
|
||||
// used for ClientID checking and Discovery of Designated Resolvers (DDR).
|
||||
|
|
@ -322,6 +322,8 @@ const (
|
|||
)
|
||||
|
||||
// newProxyConfig creates and validates configuration for the main proxy.
|
||||
//
|
||||
// TODO(d.kolyshev): Improve maintainability.
|
||||
func (s *Server) newProxyConfig(ctx context.Context) (conf *proxy.Config, err error) {
|
||||
srvConf := s.conf
|
||||
trustedPrefixes := netutil.UnembedPrefixes(srvConf.TrustedProxies)
|
||||
|
|
@ -331,9 +333,13 @@ func (s *Server) newProxyConfig(ctx context.Context) (conf *proxy.Config, err er
|
|||
return nil, fmt.Errorf("ratelimit middleware: %w", err)
|
||||
}
|
||||
|
||||
httpConf := &proxy.HTTPConfig{
|
||||
ServerHeader: aghhttp.UserAgent(),
|
||||
InsecureEnabled: s.conf.TLSAllowUnencryptedDoH,
|
||||
}
|
||||
|
||||
conf = &proxy.Config{
|
||||
Logger: s.baseLogger.With(slogutil.KeyPrefix, aghslog.PrefixDNSProxy),
|
||||
HTTP3: srvConf.ServeHTTP3,
|
||||
RefuseAny: srvConf.RefuseAny,
|
||||
TrustedProxies: netutil.SliceSubnetSet(trustedPrefixes),
|
||||
CacheMinTTL: srvConf.CacheMinTTL,
|
||||
|
|
@ -343,9 +349,7 @@ func (s *Server) newProxyConfig(ctx context.Context) (conf *proxy.Config, err er
|
|||
CacheOptimisticMaxAge: time.Duration(srvConf.CacheOptimisticMaxAge),
|
||||
UpstreamConfig: srvConf.UpstreamConfig,
|
||||
PrivateRDNSUpstreamConfig: srvConf.PrivateRDNSUpstreamConfig,
|
||||
BeforeRequestHandler: s,
|
||||
RequestHandler: ratelimitMw.Wrap(s),
|
||||
HTTPSServerName: aghhttp.UserAgent(),
|
||||
RequestHandler: ratelimitMw.Wrap(s.Wrap(s)),
|
||||
EnableEDNSClientSubnet: srvConf.EDNSClientSubnet.Enabled,
|
||||
MaxGoroutines: srvConf.MaxGoroutines,
|
||||
UseDNS64: srvConf.UseDNS64,
|
||||
|
|
@ -356,6 +360,7 @@ func (s *Server) newProxyConfig(ctx context.Context) (conf *proxy.Config, err er
|
|||
PendingRequests: &proxy.PendingRequestsConfig{
|
||||
Enabled: srvConf.PendingRequestsEnabled,
|
||||
},
|
||||
HTTPConfig: httpConf,
|
||||
}
|
||||
|
||||
if srvConf.EDNSClientSubnet.UseCustom {
|
||||
|
|
@ -798,7 +803,7 @@ func (s *Server) preparePlain(ctx context.Context, proxyConf *proxy.Config) (err
|
|||
|
||||
lenEncrypted := len(proxyConf.DNSCryptTCPListenAddr) +
|
||||
len(proxyConf.DNSCryptUDPListenAddr) +
|
||||
len(proxyConf.HTTPSListenAddr) +
|
||||
len(proxyConf.HTTPConfig.ListenAddresses) +
|
||||
len(proxyConf.QUICListenAddr) +
|
||||
len(proxyConf.TLSListenAddr)
|
||||
if lenEncrypted == 0 {
|
||||
|
|
|
|||
137
internal/dnsforward/middleware.go
Normal file
137
internal/dnsforward/middleware.go
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
package dnsforward
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
|
||||
"github.com/AdguardTeam/dnsproxy/proxy"
|
||||
"github.com/AdguardTeam/golibs/logutil/slogutil"
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
// type check
|
||||
var _ proxy.Middleware = (*Server)(nil)
|
||||
|
||||
// Wrap implements the [proxy.Middleware] interface for *Server.
|
||||
//
|
||||
// TODO(d.kolyshev): Move to a dedicated package.
|
||||
func (s *Server) Wrap(h proxy.Handler) (wrapped proxy.Handler) {
|
||||
f := func(p *proxy.Proxy, pctx *proxy.DNSContext) (err error) {
|
||||
// TODO(f.setrakov): Obtain context from arguments.
|
||||
ctx := context.TODO()
|
||||
|
||||
clientID, err := s.clientIDFromDNSContext(ctx, pctx)
|
||||
if err != nil {
|
||||
s.logger.WarnContext(ctx, "resolving client id", slogutil.KeyError, err)
|
||||
|
||||
pctx.Res = s.NewMsgSERVFAIL(pctx.Req)
|
||||
pctx.Res.Compress = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
blocked, _ := s.IsBlockedClient(pctx.Addr.Addr(), clientID)
|
||||
if blocked {
|
||||
return s.serveBlockedResponse(pctx)
|
||||
}
|
||||
|
||||
blocked = s.isBlockedHost(ctx, pctx.Req.Question)
|
||||
if blocked {
|
||||
return s.serveBlockedResponse(pctx)
|
||||
}
|
||||
|
||||
if clientID != "" {
|
||||
key := [8]byte{}
|
||||
binary.BigEndian.PutUint64(key[:], pctx.RequestID)
|
||||
s.clientIDCache.Set(key[:], []byte(clientID))
|
||||
}
|
||||
|
||||
return h.ServeDNS(p, pctx)
|
||||
}
|
||||
|
||||
return proxy.HandlerFunc(f)
|
||||
}
|
||||
|
||||
// serveBlockedResponse sets a protocol-appropriate response for a request that
|
||||
// was blocked by access settings.
|
||||
func (s *Server) serveBlockedResponse(pctx *proxy.DNSContext) (err error) {
|
||||
if pctx.Proto == proxy.ProtoUDP || pctx.Proto == proxy.ProtoDNSCrypt {
|
||||
// Return nil so that dnsproxy drops the connection and thus prevent DNS
|
||||
// amplification attacks.
|
||||
return proxy.ErrDrop
|
||||
}
|
||||
|
||||
pctx.Res = s.makeResponseREFUSED(pctx.Req)
|
||||
pctx.Res.Compress = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// isBlockedHost checks if the request is in the access blocklist.
|
||||
func (s *Server) isBlockedHost(ctx context.Context, question []dns.Question) (blocked bool) {
|
||||
if len(question) != 1 {
|
||||
return false
|
||||
}
|
||||
|
||||
q := question[0]
|
||||
qt := q.Qtype
|
||||
host := aghnet.NormalizeDomain(q.Name)
|
||||
|
||||
if s.access.isBlockedHost(host, qt) {
|
||||
s.logger.DebugContext(
|
||||
ctx,
|
||||
"request is in access blocklist",
|
||||
"dns_type", dns.Type(qt),
|
||||
"host", host,
|
||||
)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// clientIDFromDNSContext extracts the client's ID from the server name of the
|
||||
// client's DoT or DoQ request or the path of the client's DoH. If the protocol
|
||||
// is not one of these, clientID is an empty string and err is nil.
|
||||
func (s *Server) clientIDFromDNSContext(
|
||||
ctx context.Context,
|
||||
pctx *proxy.DNSContext,
|
||||
) (clientID string, err error) {
|
||||
proto := pctx.Proto
|
||||
if proto == proxy.ProtoHTTPS {
|
||||
clientID, err = clientIDFromDNSContextHTTPS(pctx)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("checking url: %w", err)
|
||||
} else if clientID != "" {
|
||||
return clientID, nil
|
||||
}
|
||||
|
||||
// Go on and check the domain name as well.
|
||||
} else if proto != proxy.ProtoTLS && proto != proxy.ProtoQUIC {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
hostSrvName := s.conf.TLSConf.ServerName
|
||||
if hostSrvName == "" {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
cliSrvName, err := clientServerName(ctx, s.logger, pctx, proto)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("getting client server-name: %w", err)
|
||||
}
|
||||
|
||||
clientID, err = clientIDFromClientServerName(
|
||||
hostSrvName,
|
||||
cliSrvName,
|
||||
s.conf.TLSConf.StrictSNICheck,
|
||||
)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("clientid check: %w", err)
|
||||
}
|
||||
|
||||
return clientID, nil
|
||||
}
|
||||
|
|
@ -15,13 +15,15 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// Common constants for tests.
|
||||
const (
|
||||
blockedHost = "blockedhost.org"
|
||||
testFQDN = "example.org."
|
||||
blockedHost = "blockedhost.org"
|
||||
testFQDN = "example.org."
|
||||
|
||||
dnsClientTimeout = 200 * time.Millisecond
|
||||
)
|
||||
|
||||
func TestServer_HandleBefore_tls(t *testing.T) {
|
||||
func TestServer_middlewareTLS(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const clientID = "client-1"
|
||||
|
|
@ -165,7 +167,7 @@ func TestServer_HandleBefore_tls(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestServer_HandleBefore_udp(t *testing.T) {
|
||||
func TestServer_middlewareUDP(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const (
|
||||
|
|
@ -201,7 +201,7 @@ func (s *Server) makeDDRResponse(req *dns.Msg) (resp *dns.Msg) {
|
|||
for _, addr := range s.conf.TLSConf.HTTPSListenAddrs {
|
||||
values := []dns.SVCBKeyValue{
|
||||
&dns.SVCBAlpn{Alpn: []string{"h2"}},
|
||||
&dns.SVCBPort{Port: uint16(addr.Port)},
|
||||
&dns.SVCBPort{Port: addr.Port()},
|
||||
&dns.SVCBDoHPath{Template: "/dns-query{?dns}"},
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -244,12 +244,16 @@ func TestServer_ProcessDDRQuery(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
addrsDoH := []netip.AddrPort{netip.AddrPortFrom(netutil.IPv4Localhost(), 8044)}
|
||||
addrsDoT := []*net.TCPAddr{{Port: 8043}}
|
||||
addrsDoQ := []*net.UDPAddr{{Port: 8042}}
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
host string
|
||||
want []*dns.SVCB
|
||||
wantRes resultCode
|
||||
addrsDoH []*net.TCPAddr
|
||||
addrsDoH []netip.AddrPort
|
||||
addrsDoT []*net.TCPAddr
|
||||
addrsDoQ []*net.UDPAddr
|
||||
qtype uint16
|
||||
|
|
@ -260,14 +264,14 @@ func TestServer_ProcessDDRQuery(t *testing.T) {
|
|||
host: testQuestionTarget,
|
||||
qtype: dns.TypeSVCB,
|
||||
ddrEnabled: true,
|
||||
addrsDoH: []*net.TCPAddr{{Port: 8043}},
|
||||
addrsDoH: addrsDoH,
|
||||
}, {
|
||||
name: "pass_qtype",
|
||||
wantRes: resultCodeFinish,
|
||||
host: ddrHostFQDN,
|
||||
qtype: dns.TypeA,
|
||||
ddrEnabled: true,
|
||||
addrsDoH: []*net.TCPAddr{{Port: 8043}},
|
||||
addrsDoH: addrsDoH,
|
||||
}, {
|
||||
name: "pass_disabled_tls",
|
||||
wantRes: resultCodeFinish,
|
||||
|
|
@ -280,7 +284,7 @@ func TestServer_ProcessDDRQuery(t *testing.T) {
|
|||
host: ddrHostFQDN,
|
||||
qtype: dns.TypeSVCB,
|
||||
ddrEnabled: false,
|
||||
addrsDoH: []*net.TCPAddr{{Port: 8043}},
|
||||
addrsDoH: addrsDoH,
|
||||
}, {
|
||||
name: "dot",
|
||||
wantRes: resultCodeFinish,
|
||||
|
|
@ -288,7 +292,7 @@ func TestServer_ProcessDDRQuery(t *testing.T) {
|
|||
host: ddrHostFQDN,
|
||||
qtype: dns.TypeSVCB,
|
||||
ddrEnabled: true,
|
||||
addrsDoT: []*net.TCPAddr{{Port: 8043}},
|
||||
addrsDoT: addrsDoT,
|
||||
}, {
|
||||
name: "doh",
|
||||
wantRes: resultCodeFinish,
|
||||
|
|
@ -296,7 +300,7 @@ func TestServer_ProcessDDRQuery(t *testing.T) {
|
|||
host: ddrHostFQDN,
|
||||
qtype: dns.TypeSVCB,
|
||||
ddrEnabled: true,
|
||||
addrsDoH: []*net.TCPAddr{{Port: 8044}},
|
||||
addrsDoH: addrsDoH,
|
||||
}, {
|
||||
name: "doq",
|
||||
wantRes: resultCodeFinish,
|
||||
|
|
@ -304,7 +308,7 @@ func TestServer_ProcessDDRQuery(t *testing.T) {
|
|||
host: ddrHostFQDN,
|
||||
qtype: dns.TypeSVCB,
|
||||
ddrEnabled: true,
|
||||
addrsDoQ: []*net.UDPAddr{{Port: 8042}},
|
||||
addrsDoQ: addrsDoQ,
|
||||
}, {
|
||||
name: "dot_doh",
|
||||
wantRes: resultCodeFinish,
|
||||
|
|
@ -312,8 +316,8 @@ func TestServer_ProcessDDRQuery(t *testing.T) {
|
|||
host: ddrHostFQDN,
|
||||
qtype: dns.TypeSVCB,
|
||||
ddrEnabled: true,
|
||||
addrsDoT: []*net.TCPAddr{{Port: 8043}},
|
||||
addrsDoH: []*net.TCPAddr{{Port: 8044}},
|
||||
addrsDoT: addrsDoT,
|
||||
addrsDoH: addrsDoH,
|
||||
}}
|
||||
|
||||
_, certPem, keyPem := createServerTLSConfig(t)
|
||||
|
|
|
|||
|
|
@ -222,6 +222,21 @@ func ipsToTCPAddrs(ips []netip.Addr, port uint16) (tcpAddrs []*net.TCPAddr) {
|
|||
return tcpAddrs
|
||||
}
|
||||
|
||||
// ipsToAddrPorts converts a slice of [netip.Addr] into a slice of
|
||||
// [netip.AddrPort] with the given port.
|
||||
func ipsToAddrPorts(ips []netip.Addr, port uint16) (addrs []netip.AddrPort) {
|
||||
if ips == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
addrs = make([]netip.AddrPort, 0, len(ips))
|
||||
for _, ip := range ips {
|
||||
addrs = append(addrs, netip.AddrPortFrom(ip, port))
|
||||
}
|
||||
|
||||
return addrs
|
||||
}
|
||||
|
||||
func ipsToUDPAddrs(ips []netip.Addr, port uint16) (udpAddrs []*net.UDPAddr) {
|
||||
if ips == nil {
|
||||
return nil
|
||||
|
|
@ -323,7 +338,7 @@ func newDNSTLSConfig(
|
|||
}
|
||||
|
||||
if conf.PortHTTPS != 0 {
|
||||
dnsConf.HTTPSListenAddrs = ipsToTCPAddrs(addrs, conf.PortHTTPS)
|
||||
dnsConf.HTTPSListenAddrs = ipsToAddrPorts(addrs, conf.PortHTTPS)
|
||||
}
|
||||
|
||||
if conf.PortDNSOverTLS != 0 {
|
||||
|
|
|
|||
|
|
@ -635,6 +635,7 @@ func TestTLSManager_HandleTLSConfigure(t *testing.T) {
|
|||
res := &tlsConfig{
|
||||
tlsConfigStatus: &tlsConfigStatus{},
|
||||
}
|
||||
|
||||
err = json.NewDecoder(w.Body).Decode(res)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue