Pull request 2382: AGDNS-2714-tls-config

Merge in DNS/adguard-home from AGDNS-2714-tls-config to master

Squashed commit of the following:

commit 073e5ec367db02690e9527602a1da6bfd29321a0
Merge: 18f38c9d4 4d258972d
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Apr 16 18:25:23 2025 +0300

    Merge branch 'master' into AGDNS-2714-tls-config

commit 18f38c9d44337752c6d0f09142658f374de0979f
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Apr 11 15:02:00 2025 +0300

    dnsforward: imp docs

commit ed56d3c2bc239bdc9af000d847721c4c43d173a3
Merge: 3ef281ea2 1cc6c00e4
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Apr 10 17:25:08 2025 +0300

    Merge branch 'master' into AGDNS-2714-tls-config

commit 3ef281ea28dc1fcab0a1291fb3221e6324077a10
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Apr 10 17:24:29 2025 +0300

    all: imp docs

commit b75f2874a816d4814d218c3b062d532f02e26ca5
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Apr 7 17:16:59 2025 +0300

    dnsforward: imp code

commit 8ab17b96bca957a172062faaa23b72d5c7ed4d0d
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Apr 4 21:26:37 2025 +0300

    all: imp code

commit 1abce97b50fe0406dd1ec85b96a0f99b633325cc
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Apr 2 18:22:15 2025 +0300

    home: imp code

commit debf710f4ebbdfe3e4d2f15b1adcf6b86f8dfc0d
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Apr 1 14:52:21 2025 +0300

    home: imp code

commit 4aa26f15b721f2a3f32da29b3f664a02bc5a8608
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Apr 1 14:16:16 2025 +0300

    all: imp code

commit 1a3e72f7a1276f9f797caf9b615f8a552cc9e988
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Mar 31 21:22:40 2025 +0300

    all: imp code

commit 776ab824aef18ea27b59c02ebfc8620c715a867e
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Mar 27 14:00:33 2025 +0300

    home: tls config mu

commit 9ebf912f530181043df5c583e82291484996429a
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Mar 26 18:58:47 2025 +0300

    all: tls config
This commit is contained in:
Stanislav Chzhen
2025-04-16 18:57:04 +03:00
parent 4d258972d1
commit 3521e8ed9f
21 changed files with 412 additions and 293 deletions

View File

@@ -74,7 +74,7 @@ func (s *Server) clientIDFromDNSContext(pctx *proxy.DNSContext) (clientID string
return "", nil
}
hostSrvName := s.conf.ServerName
hostSrvName := s.conf.TLSConf.ServerName
if hostSrvName == "" {
return "", nil
}
@@ -87,7 +87,7 @@ func (s *Server) clientIDFromDNSContext(pctx *proxy.DNSContext) (clientID string
clientID, err = clientIDFromClientServerName(
hostSrvName,
cliSrvName,
s.conf.StrictSNICheck,
s.conf.TLSConf.StrictSNICheck,
)
if err != nil {
return "", fmt.Errorf("clientid check: %w", err)

View File

@@ -121,7 +121,7 @@ func TestServer_HandleBefore_tls(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
s, _ := createTestTLS(t, TLSConfig{
s, _ := createTestTLS(t, &TLSConfig{
TLSListenAddrs: []*net.TCPAddr{{}},
ServerName: tlsServerName,
})
@@ -259,6 +259,7 @@ func TestServer_HandleBefore_udp(t *testing.T) {
}, ServerConfig{
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
TLSConf: &TLSConfig{},
Config: Config{
AllowedClients: tc.allowedClients,
DisallowedClients: tc.disallowedClients,

View File

@@ -212,13 +212,13 @@ func TestServer_clientIDFromDNSContext(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
tlsConf := TLSConfig{
tlsConf := &TLSConfig{
ServerName: tc.confSrvName,
StrictSNICheck: tc.strictSNI,
}
srv := &Server{
conf: ServerConfig{TLSConfig: tlsConf},
conf: ServerConfig{TLSConf: tlsConf},
baseLogger: slogutil.NewDiscardLogger(),
}

View File

@@ -11,7 +11,6 @@ import (
"strings"
"time"
"github.com/AdguardTeam/AdGuardHome/internal/aghalg"
"github.com/AdguardTeam/AdGuardHome/internal/aghhttp"
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
"github.com/AdguardTeam/AdGuardHome/internal/aghtls"
@@ -168,43 +167,34 @@ type EDNSClientSubnet struct {
UseCustom bool `yaml:"use_custom"`
}
// TLSConfig is the TLS configuration for HTTPS, DNS-over-HTTPS, and DNS-over-TLS
// TLSConfig contains the TLS configuration settings for DNS-over-HTTPS (DoH),
// DNS-over-TLS (DoT), DNS-over-QUIC (DoQ), and Discovery of Designated
// Resolvers (DDR).
type TLSConfig struct {
cert tls.Certificate
// Cert is the TLS certificate used for TLS connections. It is nil if
// encryption is disabled.
Cert *tls.Certificate
TLSListenAddrs []*net.TCPAddr `yaml:"-" json:"-"`
QUICListenAddrs []*net.UDPAddr `yaml:"-" json:"-"`
HTTPSListenAddrs []*net.TCPAddr `yaml:"-" json:"-"`
// TLSListenAddrs are the addresses to listen on for DoT connections. Each
// item in the list must be non-nil if Cert is not nil.
TLSListenAddrs []*net.TCPAddr
// PEM-encoded certificates chain
CertificateChain string `yaml:"certificate_chain" json:"certificate_chain"`
// PEM-encoded private key
PrivateKey string `yaml:"private_key" json:"private_key"`
// QUICListenAddrs are the addresses to listen on for DoQ connections. Each
// item in the list must be non-nil if Cert is not nil.
QUICListenAddrs []*net.UDPAddr
CertificatePath string `yaml:"certificate_path" json:"certificate_path"`
PrivateKeyPath string `yaml:"private_key_path" json:"private_key_path"`
CertificateChainData []byte `yaml:"-" json:"-"`
PrivateKeyData []byte `yaml:"-" json:"-"`
// 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
// ServerName is the hostname of the server. Currently, it is only being
// used for ClientID checking and Discovery of Designated Resolvers (DDR).
ServerName string `yaml:"-" json:"-"`
// DNS names from certificate (SAN) or CN value from Subject
dnsNames []string
// OverrideTLSCiphers, when set, contains the names of the cipher suites to
// use. If the slice is empty, the default safe suites are used.
OverrideTLSCiphers []string `yaml:"override_tls_ciphers,omitempty" json:"-"`
ServerName string
// StrictSNICheck controls if the connections with SNI mismatching the
// certificate's ones should be rejected.
StrictSNICheck bool `yaml:"strict_sni_check" json:"-"`
// hasIPAddrs is set during the certificate parsing and is true if the
// configured certificate contains at least a single IP address.
hasIPAddrs bool
StrictSNICheck bool
}
// DNSCryptConfig is the DNSCrypt server configuration struct.
@@ -239,8 +229,11 @@ type ServerConfig struct {
// Remove that.
AddrProcConf *client.DefaultAddrProcConfig
// TLSConf is the TLS configuration for DNS-over-TLS, DNS-over-QUIC, and
// HTTPS. It must not be nil.
TLSConf *TLSConfig
Config
TLSConfig
DNSCryptConfig
TLSAllowUnencryptedDoH bool
@@ -608,45 +601,33 @@ func (conf *ServerConfig) ourAddrsSet() (m addrPortSet, err error) {
}
}
// prepareTLS - prepares TLS configuration for the DNS proxy
// prepareTLS sets up the TLS configuration for the DNS proxy.
func (s *Server) prepareTLS(proxyConfig *proxy.Config) (err error) {
if len(s.conf.CertificateChainData) == 0 || len(s.conf.PrivateKeyData) == 0 {
if s.conf.TLSConf.Cert == nil {
return
}
if s.conf.TLSConf.TLSListenAddrs == nil && s.conf.TLSConf.QUICListenAddrs == nil {
return nil
}
if s.conf.TLSListenAddrs == nil && s.conf.QUICListenAddrs == nil {
return nil
}
proxyConfig.TLSListenAddr = s.conf.TLSConf.TLSListenAddrs
proxyConfig.QUICListenAddr = s.conf.TLSConf.QUICListenAddrs
proxyConfig.TLSListenAddr = aghalg.CoalesceSlice(
s.conf.TLSListenAddrs,
proxyConfig.TLSListenAddr,
)
proxyConfig.QUICListenAddr = aghalg.CoalesceSlice(
s.conf.QUICListenAddrs,
proxyConfig.QUICListenAddr,
)
s.conf.cert, err = tls.X509KeyPair(s.conf.CertificateChainData, s.conf.PrivateKeyData)
if err != nil {
return fmt.Errorf("failed to parse TLS keypair: %w", err)
}
cert, err := x509.ParseCertificate(s.conf.cert.Certificate[0])
cert, err := x509.ParseCertificate(s.conf.TLSConf.Cert.Certificate[0])
if err != nil {
return fmt.Errorf("x509.ParseCertificate(): %w", err)
}
s.conf.hasIPAddrs = aghtls.CertificateHasIP(cert)
s.hasIPAddrs = aghtls.CertificateHasIP(cert)
if s.conf.StrictSNICheck {
if s.conf.TLSConf.StrictSNICheck {
if len(cert.DNSNames) != 0 {
s.conf.dnsNames = cert.DNSNames
s.dnsNames = cert.DNSNames
log.Debug("dns: using certificate's SAN as DNS names: %v", cert.DNSNames)
slices.Sort(s.conf.dnsNames)
slices.Sort(s.dnsNames)
} else {
s.conf.dnsNames = append(s.conf.dnsNames, cert.Subject.CommonName)
s.dnsNames = []string{cert.Subject.CommonName}
log.Debug("dns: using certificate's CN as DNS name: %s", cert.Subject.CommonName)
}
}
@@ -695,11 +676,11 @@ func anyNameMatches(dnsNames []string, sni string) (ok bool) {
// Called by 'tls' package when Client Hello is received
// If the server name (from SNI) supplied by client is incorrect - we terminate the ongoing TLS handshake.
func (s *Server) onGetCertificate(ch *tls.ClientHelloInfo) (*tls.Certificate, error) {
if s.conf.StrictSNICheck && !anyNameMatches(s.conf.dnsNames, ch.ServerName) {
if s.conf.TLSConf.StrictSNICheck && !anyNameMatches(s.dnsNames, ch.ServerName) {
log.Info("dns: tls: unknown SNI in Client Hello: %s", ch.ServerName)
return nil, fmt.Errorf("invalid SNI")
}
return &s.conf.cert, nil
return s.conf.TLSConf.Cert, nil
}
// preparePlain prepares the plain-DNS configuration for the DNS proxy.

View File

@@ -296,6 +296,7 @@ func TestServer_HandleDNSRequest_dns64(t *testing.T) {
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
UseDNS64: true,
TLSConf: &TLSConfig{},
Config: Config{
UpstreamMode: UpstreamModeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
@@ -335,6 +336,7 @@ func TestServer_dns64WithDisabledRDNS(t *testing.T) {
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
UseDNS64: true,
TLSConf: &TLSConfig{},
Config: Config{
UpstreamMode: UpstreamModeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},

View File

@@ -103,16 +103,26 @@ type SystemResolvers interface {
//
// The zero Server is empty and ready for use.
type Server struct {
// dnsProxy is the DNS proxy for forwarding client's DNS requests.
dnsProxy *proxy.Proxy
// addrProc, if not nil, is used to process clients' IP addresses with rDNS,
// WHOIS, etc.
addrProc client.AddressProcessor
// dnsFilter is the DNS filter for filtering client's DNS requests and
// responses.
dnsFilter *filtering.DNSFilter
// bootstrap is the resolver for upstreams' hostnames.
bootstrap upstream.Resolver
// clientIDCache is a temporary storage for ClientIDs that were extracted
// during the BeforeRequestHandler stage.
clientIDCache cache.Cache
// dhcpServer is the DHCP server for accessing lease data.
dhcpServer DHCP
// etcHosts contains the current data from the system's hosts files.
etcHosts upstream.Resolver
// privateNets is the configured set of IP networks considered private.
privateNets netutil.SubnetSet
// queryLog is the query log for client's DNS requests, responses and
// filtering results.
queryLog querylog.QueryLog
@@ -120,37 +130,43 @@ type Server struct {
// stats is the statistics collector for client's DNS usage data.
stats stats.Interface
// sysResolvers used to fetch system resolvers to use by default for private
// PTR resolving.
sysResolvers SystemResolvers
// access drops disallowed clients.
access *accessManager
// anonymizer masks the client's IP addresses if needed.
anonymizer *aghnet.IPMut
// baseLogger is used to create loggers for other entities. It should not
// have a prefix and must not be nil.
baseLogger *slog.Logger
// localDomainSuffix is the suffix used to detect internal hosts. It
// must be a valid domain name plus dots on each side.
localDomainSuffix string
// dnsFilter is the DNS filter for filtering client's DNS requests and
// responses.
dnsFilter *filtering.DNSFilter
// dnsProxy is the DNS proxy for forwarding client's DNS requests.
dnsProxy *proxy.Proxy
// internalProxy resolves internal requests from the application itself. It
// isn't started and so no listen ports are required.
internalProxy *proxy.Proxy
// ipset processes DNS requests using ipset data. It must not be nil after
// initialization. See [newIpsetHandler].
ipset *ipsetHandler
// privateNets is the configured set of IP networks considered private.
privateNets netutil.SubnetSet
// dns64Pref is the NAT64 prefix used for DNS64 response mapping. The major
// part of DNS64 happens inside the [proxy] package, but there still are
// some places where response mapping is needed (e.g. DHCP).
dns64Pref netip.Prefix
// addrProc, if not nil, is used to process clients' IP addresses with rDNS,
// WHOIS, etc.
addrProc client.AddressProcessor
// sysResolvers used to fetch system resolvers to use by default for private
// PTR resolving.
sysResolvers SystemResolvers
// etcHosts contains the current data from the system's hosts files.
etcHosts upstream.Resolver
// bootstrap is the resolver for upstreams' hostnames.
bootstrap upstream.Resolver
// localDomainSuffix is the suffix used to detect internal hosts. It
// must be a valid domain name plus dots on each side.
localDomainSuffix string
// bootResolvers are the resolvers that should be used for
// bootstrapping along with [etcHosts].
@@ -159,34 +175,26 @@ type Server struct {
// [upstream.Resolver] interface.
bootResolvers []*upstream.UpstreamResolver
// dns64Pref is the NAT64 prefix used for DNS64 response mapping. The major
// part of DNS64 happens inside the [proxy] package, but there still are
// some places where response mapping is needed (e.g. DHCP).
dns64Pref netip.Prefix
// anonymizer masks the client's IP addresses if needed.
anonymizer *aghnet.IPMut
// clientIDCache is a temporary storage for ClientIDs that were extracted
// during the BeforeRequestHandler stage.
clientIDCache cache.Cache
// internalProxy resolves internal requests from the application itself. It
// isn't started and so no listen ports are required.
internalProxy *proxy.Proxy
// isRunning is true if the DNS server is running.
isRunning bool
// protectionUpdateInProgress is used to make sure that only one goroutine
// updating the protection configuration after a pause is running at a time.
protectionUpdateInProgress atomic.Bool
// dnsNames are the DNS names from certificate (SAN) or CN value from
// Subject.
dnsNames []string
// conf is the current configuration of the server.
conf ServerConfig
// serverLock protects Server.
serverLock sync.RWMutex
// protectionUpdateInProgress is used to make sure that only one goroutine
// updating the protection configuration after a pause is running at a time.
protectionUpdateInProgress atomic.Bool
// isRunning is true if the DNS server is running.
isRunning bool
// hasIPAddrs is set during the certificate parsing and is true if the
// configured certificate contains at least a single IP address.
hasIPAddrs bool
}
// defaultLocalDomainSuffix is the default suffix used to detect internal hosts

View File

@@ -213,17 +213,23 @@ func createServerTLSConfig(t *testing.T) (*tls.Config, []byte, []byte) {
}, certPem, keyPem
}
func createTestTLS(t *testing.T, tlsConf TLSConfig) (s *Server, certPem []byte) {
func createTestTLS(t *testing.T, tlsConf *TLSConfig) (s *Server, certPem []byte) {
t.Helper()
var keyPem []byte
_, certPem, keyPem = createServerTLSConfig(t)
cert, err := tls.X509KeyPair(certPem, keyPem)
require.NoError(t, err)
tlsConf.Cert = &cert
s = createTestServer(t, &filtering.Config{
BlockingMode: filtering.BlockingModeDefault,
}, ServerConfig{
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
TLSConf: tlsConf,
Config: Config{
UpstreamMode: UpstreamModeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
@@ -232,10 +238,7 @@ func createTestTLS(t *testing.T, tlsConf TLSConfig) (s *Server, certPem []byte)
ServePlainDNS: true,
})
tlsConf.CertificateChainData, tlsConf.PrivateKeyData = certPem, keyPem
s.conf.TLSConfig = tlsConf
err := s.Prepare(&s.conf)
err = s.Prepare(&s.conf)
require.NoErrorf(t, err, "failed to prepare server: %s", err)
return s, certPem
@@ -354,6 +357,7 @@ func TestServer(t *testing.T) {
}, ServerConfig{
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
TLSConf: &TLSConfig{},
Config: Config{
UpstreamMode: UpstreamModeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
@@ -395,6 +399,7 @@ func TestServer_timeout(t *testing.T) {
t.Run("custom", func(t *testing.T) {
srvConf := &ServerConfig{
UpstreamTimeout: testTimeout,
TLSConf: &TLSConfig{},
Config: Config{
UpstreamMode: UpstreamModeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
@@ -422,6 +427,7 @@ func TestServer_timeout(t *testing.T) {
})
require.NoError(t, err)
s.conf.TLSConf = &TLSConfig{}
s.conf.Config.UpstreamMode = UpstreamModeLoadBalance
s.conf.Config.EDNSClientSubnet = &EDNSClientSubnet{
Enabled: false,
@@ -436,6 +442,7 @@ func TestServer_timeout(t *testing.T) {
func TestServer_Prepare_fallbacks(t *testing.T) {
srvConf := &ServerConfig{
TLSConf: &TLSConfig{},
Config: Config{
FallbackDNS: []string{
"#tls://1.1.1.1",
@@ -466,6 +473,7 @@ func TestServerWithProtectionDisabled(t *testing.T) {
}, ServerConfig{
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
TLSConf: &TLSConfig{},
Config: Config{
UpstreamMode: UpstreamModeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
@@ -487,7 +495,7 @@ func TestServerWithProtectionDisabled(t *testing.T) {
}
func TestDoTServer(t *testing.T) {
s, certPem := createTestTLS(t, TLSConfig{
s, certPem := createTestTLS(t, &TLSConfig{
TLSListenAddrs: []*net.TCPAddr{{}},
})
s.conf.UpstreamConfig.Upstreams = []upstream.Upstream{newGoogleUpstream()}
@@ -511,7 +519,7 @@ func TestDoTServer(t *testing.T) {
}
func TestDoQServer(t *testing.T) {
s, _ := createTestTLS(t, TLSConfig{
s, _ := createTestTLS(t, &TLSConfig{
QUICListenAddrs: []*net.UDPAddr{{IP: net.IP{127, 0, 0, 1}}},
})
s.conf.UpstreamConfig.Upstreams = []upstream.Upstream{newGoogleUpstream()}
@@ -596,6 +604,7 @@ func TestSafeSearch(t *testing.T) {
forwardConf := ServerConfig{
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
TLSConf: &TLSConfig{},
Config: Config{
UpstreamMode: UpstreamModeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{
@@ -690,6 +699,7 @@ func TestInvalidRequest(t *testing.T) {
}, ServerConfig{
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
TLSConf: &TLSConfig{},
Config: Config{
UpstreamMode: UpstreamModeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{
@@ -721,6 +731,7 @@ func TestBlockedRequest(t *testing.T) {
forwardConf := ServerConfig{
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
TLSConf: &TLSConfig{},
Config: Config{
UpstreamMode: UpstreamModeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{
@@ -758,6 +769,7 @@ func TestServerCustomClientUpstream(t *testing.T) {
forwardConf := ServerConfig{
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
TLSConf: &TLSConfig{},
Config: Config{
CacheSize: defaultCacheSize,
UpstreamMode: UpstreamModeLoadBalance,
@@ -838,6 +850,7 @@ func TestBlockCNAMEProtectionEnabled(t *testing.T) {
}, ServerConfig{
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
TLSConf: &TLSConfig{},
Config: Config{
UpstreamMode: UpstreamModeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{
@@ -873,6 +886,7 @@ func TestBlockCNAME(t *testing.T) {
forwardConf := ServerConfig{
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
TLSConf: &TLSConfig{},
Config: Config{
UpstreamMode: UpstreamModeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{
@@ -947,6 +961,7 @@ func TestClientRulesForCNAMEMatching(t *testing.T) {
forwardConf := ServerConfig{
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
TLSConf: &TLSConfig{},
Config: Config{
UpstreamMode: UpstreamModeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{
@@ -994,6 +1009,7 @@ func TestNullBlockedRequest(t *testing.T) {
forwardConf := ServerConfig{
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
TLSConf: &TLSConfig{},
Config: Config{
UpstreamMode: UpstreamModeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{
@@ -1064,6 +1080,7 @@ func TestBlockedCustomIP(t *testing.T) {
conf := &ServerConfig{
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
TLSConf: &TLSConfig{},
Config: Config{
UpstreamDNS: []string{"8.8.8.8:53", "8.8.4.4:53"},
UpstreamMode: UpstreamModeLoadBalance,
@@ -1119,6 +1136,7 @@ func TestBlockedByHosts(t *testing.T) {
forwardConf := ServerConfig{
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
TLSConf: &TLSConfig{},
Config: Config{
UpstreamMode: UpstreamModeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{
@@ -1172,6 +1190,7 @@ func TestBlockedBySafeBrowsing(t *testing.T) {
forwardConf := ServerConfig{
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
TLSConf: &TLSConfig{},
Config: Config{
UpstreamMode: UpstreamModeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{
@@ -1235,6 +1254,7 @@ func TestRewrite(t *testing.T) {
assert.NoError(t, s.Prepare(&ServerConfig{
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
TLSConf: &TLSConfig{},
Config: Config{
UpstreamDNS: []string{"8.8.8.8:53"},
UpstreamMode: UpstreamModeLoadBalance,
@@ -1369,6 +1389,7 @@ func TestPTRResponseFromDHCPLeases(t *testing.T) {
s.conf.UDPListenAddrs = []*net.UDPAddr{{}}
s.conf.TCPListenAddrs = []*net.TCPAddr{{}}
s.conf.UpstreamDNS = []string{"127.0.0.1:53"}
s.conf.TLSConf = &TLSConfig{}
s.conf.Config.EDNSClientSubnet = &EDNSClientSubnet{Enabled: false}
s.conf.Config.ClientsContainer = EmptyClientsContainer{}
s.conf.Config.UpstreamMode = UpstreamModeLoadBalance
@@ -1457,6 +1478,7 @@ func TestPTRResponseFromHosts(t *testing.T) {
s.conf.UDPListenAddrs = []*net.UDPAddr{{}}
s.conf.TCPListenAddrs = []*net.TCPAddr{{}}
s.conf.UpstreamDNS = []string{"127.0.0.1:53"}
s.conf.TLSConf = &TLSConfig{}
s.conf.Config.EDNSClientSubnet = &EDNSClientSubnet{Enabled: false}
s.conf.Config.ClientsContainer = EmptyClientsContainer{}
s.conf.Config.UpstreamMode = UpstreamModeLoadBalance
@@ -1723,6 +1745,7 @@ func TestServer_Exchange(t *testing.T) {
srv := createTestServer(t, &filtering.Config{
BlockingMode: filtering.BlockingModeDefault,
}, ServerConfig{
TLSConf: &TLSConfig{},
Config: Config{
UpstreamDNS: []string{upsAddr},
UpstreamMode: UpstreamModeLoadBalance,
@@ -1746,6 +1769,7 @@ func TestServer_Exchange(t *testing.T) {
srv := createTestServer(t, &filtering.Config{
BlockingMode: filtering.BlockingModeDefault,
}, ServerConfig{
TLSConf: &TLSConfig{},
Config: Config{
UpstreamDNS: []string{upsAddr},
UpstreamMode: UpstreamModeLoadBalance,

View File

@@ -37,6 +37,7 @@ func TestServer_FilterDNSRewrite(t *testing.T) {
srv := createTestServer(t, &filtering.Config{
BlockingMode: filtering.BlockingModeDefault,
}, ServerConfig{
TLSConf: &TLSConfig{},
Config: Config{
UpstreamMode: UpstreamModeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},

View File

@@ -31,6 +31,7 @@ func TestHandleDNSRequest_handleDNSRequest(t *testing.T) {
forwardConf := ServerConfig{
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
TLSConf: &TLSConfig{},
Config: Config{
UpstreamMode: UpstreamModeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{

View File

@@ -76,6 +76,7 @@ func TestDNSForwardHTTP_handleGetConfig(t *testing.T) {
forwardConf := ServerConfig{
UDPListenAddrs: []*net.UDPAddr{},
TCPListenAddrs: []*net.TCPAddr{},
TLSConf: &TLSConfig{},
Config: Config{
UpstreamDNS: []string{"8.8.8.8:53", "8.8.4.4:53"},
FallbackDNS: []string{"9.9.9.10"},
@@ -159,6 +160,7 @@ func TestDNSForwardHTTP_handleSetConfig(t *testing.T) {
forwardConf := ServerConfig{
UDPListenAddrs: []*net.UDPAddr{},
TCPListenAddrs: []*net.TCPAddr{},
TLSConf: &TLSConfig{},
Config: Config{
UpstreamDNS: []string{"8.8.8.8:53", "8.8.4.4:53"},
RatelimitSubnetLenIPv4: 24,
@@ -369,6 +371,7 @@ func TestServer_HandleTestUpstreamDNS(t *testing.T) {
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
UpstreamTimeout: upsTimeout,
TLSConf: &TLSConfig{},
Config: Config{
UpstreamMode: UpstreamModeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},

View File

@@ -246,9 +246,9 @@ func (s *Server) makeDDRResponse(req *dns.Msg) (resp *dns.Msg) {
// TODO(e.burkov): Think about storing the FQDN version of the server's
// name somewhere.
domainName := dns.Fqdn(s.conf.ServerName)
domainName := dns.Fqdn(s.conf.TLSConf.ServerName)
for _, addr := range s.conf.HTTPSListenAddrs {
for _, addr := range s.conf.TLSConf.HTTPSListenAddrs {
values := []dns.SVCBKeyValue{
&dns.SVCBAlpn{Alpn: []string{"h2"}},
&dns.SVCBPort{Port: uint16(addr.Port)},
@@ -265,7 +265,7 @@ func (s *Server) makeDDRResponse(req *dns.Msg) (resp *dns.Msg) {
resp.Answer = append(resp.Answer, ans)
}
if s.conf.hasIPAddrs {
if s.hasIPAddrs {
// Only add DNS-over-TLS resolvers in case the certificate contains IP
// addresses.
//

View File

@@ -3,6 +3,7 @@ package dnsforward
import (
"cmp"
"context"
"crypto/tls"
"net"
"net/netip"
"testing"
@@ -77,6 +78,7 @@ func TestServer_ProcessInitial(t *testing.T) {
t.Parallel()
c := ServerConfig{
TLSConf: &TLSConfig{},
Config: Config{
AAAADisabled: tc.aaaaDisabled,
UpstreamMode: UpstreamModeLoadBalance,
@@ -177,6 +179,7 @@ func TestServer_ProcessFilteringAfterResponse(t *testing.T) {
t.Parallel()
c := ServerConfig{
TLSConf: &TLSConfig{},
Config: Config{
AAAADisabled: tc.aaaaDisabled,
UpstreamMode: UpstreamModeLoadBalance,
@@ -316,6 +319,8 @@ func TestServer_ProcessDDRQuery(t *testing.T) {
}}
_, certPem, keyPem := createServerTLSConfig(t)
cert, err := tls.X509KeyPair(certPem, keyPem)
require.NoError(t, err)
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
@@ -328,19 +333,18 @@ func TestServer_ProcessDDRQuery(t *testing.T) {
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
ClientsContainer: EmptyClientsContainer{},
},
TLSConfig: TLSConfig{
ServerName: ddrTestDomainName,
CertificateChainData: certPem,
PrivateKeyData: keyPem,
TLSListenAddrs: tc.addrsDoT,
HTTPSListenAddrs: tc.addrsDoH,
QUICListenAddrs: tc.addrsDoQ,
TLSConf: &TLSConfig{
ServerName: ddrTestDomainName,
Cert: &cert,
TLSListenAddrs: tc.addrsDoT,
HTTPSListenAddrs: tc.addrsDoH,
QUICListenAddrs: tc.addrsDoQ,
},
ServePlainDNS: true,
})
// TODO(e.burkov): Generate a certificate actually containing the
// IP addresses.
s.conf.hasIPAddrs = true
s.hasIPAddrs = true
req := createTestMessageWithType(tc.host, tc.qtype)
@@ -657,6 +661,7 @@ func TestServer_HandleDNSRequest_restrictLocal(t *testing.T) {
}, ServerConfig{
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
TLSConf: &TLSConfig{},
// TODO(s.chzhen): Add tests where EDNSClientSubnet.Enabled is true.
// Improve Config declaration for tests.
Config: Config{
@@ -789,6 +794,7 @@ func TestServer_ProcessUpstream_localPTR(t *testing.T) {
ServerConfig{
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
TLSConf: &TLSConfig{},
Config: Config{
UpstreamMode: UpstreamModeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
@@ -818,6 +824,7 @@ func TestServer_ProcessUpstream_localPTR(t *testing.T) {
ServerConfig{
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
TLSConf: &TLSConfig{},
Config: Config{
UpstreamMode: UpstreamModeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},

View File

@@ -16,6 +16,7 @@ func TestGenAnswerHTTPS_andSVCB(t *testing.T) {
s := createTestServer(t, &filtering.Config{
BlockingMode: filtering.BlockingModeDefault,
}, ServerConfig{
TLSConf: &TLSConfig{},
Config: Config{
UpstreamMode: UpstreamModeLoadBalance,
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},