mirror of
https://github.com/AdguardTeam/AdGuardHome.git
synced 2024-11-29 02:18:51 +03:00
Pull request: 4403-internal-proxy
Updates #4403. * commit 'd519929988575439c2238924ae5b1d96091445f7': dnsforward: imp code, fmt Also honor the user-defined UpstreamMode for the internal DNS proxy
This commit is contained in:
commit
a0c8aee3f7
7 changed files with 123 additions and 96 deletions
|
@ -163,10 +163,10 @@ type TLSConfig struct {
|
||||||
|
|
||||||
// DNSCryptConfig is the DNSCrypt server configuration struct.
|
// DNSCryptConfig is the DNSCrypt server configuration struct.
|
||||||
type DNSCryptConfig struct {
|
type DNSCryptConfig struct {
|
||||||
|
ResolverCert *dnscrypt.Cert
|
||||||
|
ProviderName string
|
||||||
UDPListenAddrs []*net.UDPAddr
|
UDPListenAddrs []*net.UDPAddr
|
||||||
TCPListenAddrs []*net.TCPAddr
|
TCPListenAddrs []*net.TCPAddr
|
||||||
ProviderName string
|
|
||||||
ResolverCert *dnscrypt.Cert
|
|
||||||
Enabled bool
|
Enabled bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,68 +214,67 @@ var defaultValues = ServerConfig{
|
||||||
FilteringConfig: FilteringConfig{BlockedResponseTTL: 3600},
|
FilteringConfig: FilteringConfig{BlockedResponseTTL: 3600},
|
||||||
}
|
}
|
||||||
|
|
||||||
// createProxyConfig creates and validates configuration for the main proxy
|
// createProxyConfig creates and validates configuration for the main proxy.
|
||||||
func (s *Server) createProxyConfig() (proxy.Config, error) {
|
func (s *Server) createProxyConfig() (conf proxy.Config, err error) {
|
||||||
proxyConfig := proxy.Config{
|
srvConf := s.conf
|
||||||
UDPListenAddr: s.conf.UDPListenAddrs,
|
conf = proxy.Config{
|
||||||
TCPListenAddr: s.conf.TCPListenAddrs,
|
UDPListenAddr: srvConf.UDPListenAddrs,
|
||||||
Ratelimit: int(s.conf.Ratelimit),
|
TCPListenAddr: srvConf.TCPListenAddrs,
|
||||||
RatelimitWhitelist: s.conf.RatelimitWhitelist,
|
Ratelimit: int(srvConf.Ratelimit),
|
||||||
RefuseAny: s.conf.RefuseAny,
|
RatelimitWhitelist: srvConf.RatelimitWhitelist,
|
||||||
TrustedProxies: s.conf.TrustedProxies,
|
RefuseAny: srvConf.RefuseAny,
|
||||||
CacheMinTTL: s.conf.CacheMinTTL,
|
TrustedProxies: srvConf.TrustedProxies,
|
||||||
CacheMaxTTL: s.conf.CacheMaxTTL,
|
CacheMinTTL: srvConf.CacheMinTTL,
|
||||||
CacheOptimistic: s.conf.CacheOptimistic,
|
CacheMaxTTL: srvConf.CacheMaxTTL,
|
||||||
UpstreamConfig: s.conf.UpstreamConfig,
|
CacheOptimistic: srvConf.CacheOptimistic,
|
||||||
|
UpstreamConfig: srvConf.UpstreamConfig,
|
||||||
BeforeRequestHandler: s.beforeRequestHandler,
|
BeforeRequestHandler: s.beforeRequestHandler,
|
||||||
RequestHandler: s.handleDNSRequest,
|
RequestHandler: s.handleDNSRequest,
|
||||||
EnableEDNSClientSubnet: s.conf.EnableEDNSClientSubnet,
|
EnableEDNSClientSubnet: srvConf.EnableEDNSClientSubnet,
|
||||||
MaxGoroutines: int(s.conf.MaxGoroutines),
|
MaxGoroutines: int(srvConf.MaxGoroutines),
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.conf.CacheSize != 0 {
|
if srvConf.CacheSize != 0 {
|
||||||
proxyConfig.CacheEnabled = true
|
conf.CacheEnabled = true
|
||||||
proxyConfig.CacheSizeBytes = int(s.conf.CacheSize)
|
conf.CacheSizeBytes = int(srvConf.CacheSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
proxyConfig.UpstreamMode = proxy.UModeLoadBalance
|
setProxyUpstreamMode(
|
||||||
if s.conf.AllServers {
|
&conf,
|
||||||
proxyConfig.UpstreamMode = proxy.UModeParallel
|
srvConf.AllServers,
|
||||||
} else if s.conf.FastestAddr {
|
srvConf.FastestAddr,
|
||||||
proxyConfig.UpstreamMode = proxy.UModeFastestAddr
|
srvConf.FastestTimeout.Duration,
|
||||||
proxyConfig.FastestPingTimeout = s.conf.FastestTimeout.Duration
|
)
|
||||||
}
|
|
||||||
|
|
||||||
for i, s := range s.conf.BogusNXDomain {
|
for i, s := range srvConf.BogusNXDomain {
|
||||||
subnet, err := netutil.ParseSubnet(s)
|
var subnet *net.IPNet
|
||||||
|
subnet, err = netutil.ParseSubnet(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("subnet at index %d: %s", i, err)
|
log.Error("subnet at index %d: %s", i, err)
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
proxyConfig.BogusNXDomain = append(proxyConfig.BogusNXDomain, subnet)
|
conf.BogusNXDomain = append(conf.BogusNXDomain, subnet)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TLS settings
|
err = s.prepareTLS(&conf)
|
||||||
err := s.prepareTLS(&proxyConfig)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return proxyConfig, err
|
return conf, fmt.Errorf("validating tls: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.conf.DNSCryptConfig.Enabled {
|
if c := srvConf.DNSCryptConfig; c.Enabled {
|
||||||
proxyConfig.DNSCryptUDPListenAddr = s.conf.DNSCryptConfig.UDPListenAddrs
|
conf.DNSCryptUDPListenAddr = c.UDPListenAddrs
|
||||||
proxyConfig.DNSCryptTCPListenAddr = s.conf.DNSCryptConfig.TCPListenAddrs
|
conf.DNSCryptTCPListenAddr = c.TCPListenAddrs
|
||||||
proxyConfig.DNSCryptProviderName = s.conf.DNSCryptConfig.ProviderName
|
conf.DNSCryptProviderName = c.ProviderName
|
||||||
proxyConfig.DNSCryptResolverCert = s.conf.DNSCryptConfig.ResolverCert
|
conf.DNSCryptResolverCert = c.ResolverCert
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate proxy config
|
if conf.UpstreamConfig == nil || len(conf.UpstreamConfig.Upstreams) == 0 {
|
||||||
if proxyConfig.UpstreamConfig == nil || len(proxyConfig.UpstreamConfig.Upstreams) == 0 {
|
return conf, errors.Error("no default upstream servers configured")
|
||||||
return proxyConfig, errors.Error("no default upstream servers configured")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return proxyConfig, nil
|
return conf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -381,14 +380,45 @@ func (s *Server) prepareUpstreamSettings() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// prepareIntlProxy - initializes DNS proxy that we use for internal DNS queries
|
// prepareInternalProxy initializes the DNS proxy that is used for internal DNS
|
||||||
func (s *Server) prepareIntlProxy() {
|
// queries, such at client PTR resolving and udpater hostname resolving.
|
||||||
s.internalProxy = &proxy.Proxy{
|
func (s *Server) prepareInternalProxy() {
|
||||||
Config: proxy.Config{
|
conf := &proxy.Config{
|
||||||
CacheEnabled: true,
|
CacheEnabled: true,
|
||||||
CacheSizeBytes: 4096,
|
CacheSizeBytes: 4096,
|
||||||
UpstreamConfig: s.conf.UpstreamConfig,
|
UpstreamConfig: s.conf.UpstreamConfig,
|
||||||
},
|
MaxGoroutines: int(s.conf.MaxGoroutines),
|
||||||
|
}
|
||||||
|
|
||||||
|
srvConf := s.conf
|
||||||
|
setProxyUpstreamMode(
|
||||||
|
conf,
|
||||||
|
srvConf.AllServers,
|
||||||
|
srvConf.FastestAddr,
|
||||||
|
srvConf.FastestTimeout.Duration,
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO(a.garipov): Make a proper constructor for proxy.Proxy.
|
||||||
|
s.internalProxy = &proxy.Proxy{
|
||||||
|
Config: *conf,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// setProxyUpstreamMode sets the upstream mode and related settings in conf
|
||||||
|
// based on provided parameters.
|
||||||
|
func setProxyUpstreamMode(
|
||||||
|
conf *proxy.Config,
|
||||||
|
allServers bool,
|
||||||
|
fastestAddr bool,
|
||||||
|
fastestTimeout time.Duration,
|
||||||
|
) {
|
||||||
|
if allServers {
|
||||||
|
conf.UpstreamMode = proxy.UModeParallel
|
||||||
|
} else if fastestAddr {
|
||||||
|
conf.UpstreamMode = proxy.UModeFastestAddr
|
||||||
|
conf.FastestPingTimeout = fastestTimeout
|
||||||
|
} else {
|
||||||
|
conf.UpstreamMode = proxy.UModeLoadBalance
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@ type hostToIPTable = map[string]net.IP
|
||||||
// Server is the main way to start a DNS server.
|
// Server is the main way to start a DNS server.
|
||||||
//
|
//
|
||||||
// Example:
|
// Example:
|
||||||
|
//
|
||||||
// s := dnsforward.Server{}
|
// s := dnsforward.Server{}
|
||||||
// err := s.Start(nil) // will start a DNS server listening on default port 53, in a goroutine
|
// err := s.Start(nil) // will start a DNS server listening on default port 53, in a goroutine
|
||||||
// err := s.Reconfigure(ServerConfig{UDPListenAddr: &net.UDPAddr{Port: 53535}}) // will reconfigure running DNS server to listen on UDP port 53535
|
// err := s.Reconfigure(ServerConfig{UDPListenAddr: &net.UDPAddr{Port: 53535}}) // will reconfigure running DNS server to listen on UDP port 53535
|
||||||
|
@ -176,18 +177,6 @@ func NewServer(p DNSCreateParams) (s *Server, err error) {
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCustomServer creates a new instance of *Server with custom internal proxy.
|
|
||||||
func NewCustomServer(internalProxy *proxy.Proxy) *Server {
|
|
||||||
s := &Server{
|
|
||||||
recDetector: newRecursionDetector(0, 1),
|
|
||||||
}
|
|
||||||
if internalProxy != nil {
|
|
||||||
s.internalProxy = internalProxy
|
|
||||||
}
|
|
||||||
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close gracefully closes the server. It is safe for concurrent use.
|
// Close gracefully closes the server. It is safe for concurrent use.
|
||||||
//
|
//
|
||||||
// TODO(e.burkov): A better approach would be making Stop method waiting for all
|
// TODO(e.burkov): A better approach would be making Stop method waiting for all
|
||||||
|
@ -488,7 +477,7 @@ func (s *Server) Prepare(config *ServerConfig) error {
|
||||||
|
|
||||||
// Prepare a DNS proxy instance that we use for internal DNS queries
|
// Prepare a DNS proxy instance that we use for internal DNS queries
|
||||||
// --
|
// --
|
||||||
s.prepareIntlProxy()
|
s.prepareInternalProxy()
|
||||||
|
|
||||||
s.access, err = newAccessCtx(s.conf.AllowedClients, s.conf.DisallowedClients, s.conf.BlockedHosts)
|
s.access, err = newAccessCtx(s.conf.AllowedClients, s.conf.DisallowedClients, s.conf.BlockedHosts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1217,13 +1217,17 @@ func TestServer_Exchange(t *testing.T) {
|
||||||
errUpstream := aghtest.NewErrorUpstream()
|
errUpstream := aghtest.NewErrorUpstream()
|
||||||
nonPtrUpstream := aghtest.NewBlockUpstream("some-host", true)
|
nonPtrUpstream := aghtest.NewBlockUpstream("some-host", true)
|
||||||
|
|
||||||
srv := NewCustomServer(&proxy.Proxy{
|
srv := &Server{
|
||||||
|
recDetector: newRecursionDetector(0, 1),
|
||||||
|
internalProxy: &proxy.Proxy{
|
||||||
Config: proxy.Config{
|
Config: proxy.Config{
|
||||||
UpstreamConfig: &proxy.UpstreamConfig{
|
UpstreamConfig: &proxy.UpstreamConfig{
|
||||||
Upstreams: []upstream.Upstream{extUpstream},
|
Upstreams: []upstream.Upstream{extUpstream},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
},
|
||||||
|
}
|
||||||
|
|
||||||
srv.conf.ResolveClients = true
|
srv.conf.ResolveClients = true
|
||||||
srv.conf.UsePrivateRDNS = true
|
srv.conf.UsePrivateRDNS = true
|
||||||
|
|
||||||
|
|
|
@ -711,10 +711,15 @@ func (s *Server) handleTestUpstreamDNS(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleDoH is the DNS-over-HTTPs handler.
|
||||||
|
//
|
||||||
// Control flow:
|
// Control flow:
|
||||||
// web
|
//
|
||||||
// -> dnsforward.handleDoH -> dnsforward.ServeHTTP
|
// HTTP server
|
||||||
// -> proxy.ServeHTTP -> proxy.handleDNSRequest
|
// -> dnsforward.handleDoH
|
||||||
|
// -> dnsforward.ServeHTTP
|
||||||
|
// -> proxy.ServeHTTP
|
||||||
|
// -> proxy.handleDNSRequest
|
||||||
// -> dnsforward.handleDNSRequest
|
// -> dnsforward.handleDNSRequest
|
||||||
func (s *Server) handleDoH(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) handleDoH(w http.ResponseWriter, r *http.Request) {
|
||||||
if !s.conf.TLSAllowUnencryptedDoH && r.TLS == nil {
|
if !s.conf.TLSAllowUnencryptedDoH && r.TLS == nil {
|
||||||
|
|
|
@ -280,10 +280,10 @@ func newDNSCrypt(hosts []net.IP, tlsConf tlsConfigSettings) (dnscc dnsforward.DN
|
||||||
}
|
}
|
||||||
|
|
||||||
return dnsforward.DNSCryptConfig{
|
return dnsforward.DNSCryptConfig{
|
||||||
UDPListenAddrs: ipsToUDPAddrs(hosts, tlsConf.PortDNSCrypt),
|
|
||||||
TCPListenAddrs: ipsToTCPAddrs(hosts, tlsConf.PortDNSCrypt),
|
|
||||||
ResolverCert: cert,
|
ResolverCert: cert,
|
||||||
ProviderName: rc.ProviderName,
|
ProviderName: rc.ProviderName,
|
||||||
|
UDPListenAddrs: ipsToUDPAddrs(hosts, tlsConf.PortDNSCrypt),
|
||||||
|
TCPListenAddrs: ipsToTCPAddrs(hosts, tlsConf.PortDNSCrypt),
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,6 @@ const (
|
||||||
// fmtModule returns formatted information about module. The result looks like:
|
// fmtModule returns formatted information about module. The result looks like:
|
||||||
//
|
//
|
||||||
// github.com/Username/module@v1.2.3 (sum: someHASHSUM=)
|
// github.com/Username/module@v1.2.3 (sum: someHASHSUM=)
|
||||||
//
|
|
||||||
func fmtModule(m *debug.Module) (formatted string) {
|
func fmtModule(m *debug.Module) (formatted string) {
|
||||||
if m == nil {
|
if m == nil {
|
||||||
return ""
|
return ""
|
||||||
|
|
Loading…
Reference in a new issue