From 229ef780857120ca62b2f4ab6249c1529e18d1e7 Mon Sep 17 00:00:00 2001 From: Eugene Bujak Date: Tue, 12 Feb 2019 17:23:38 +0300 Subject: [PATCH] Activate DNS-over-TLS server when certificates, keys and ports are configured. --- config.go | 12 ++++++------ dns.go | 5 +++++ dnsforward/dnsforward.go | 18 ++++++++++++++++++ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/config.go b/config.go index 73d26155..21700586 100644 --- a/config.go +++ b/config.go @@ -63,12 +63,12 @@ var defaultDNS = []string{"tls://1.1.1.1", "tls://1.0.0.1"} // field ordering is important -- yaml fields will mirror ordering from here type tlsConfig struct { - ServerName string `yaml:"server_name" json:"server_name,omitempty"` - ForceHTTPS bool `yaml:"force_https" json:"force_https,omitempty"` - PortHTTPS int `yaml:"port_https" json:"port_https,omitempty"` - PortDNSOverTLS int `yaml:"port_dns_over_tls" json:"port_dns_over_tls,omitempty"` - CertificateChain string `yaml:"certificate_chain" json:"certificate_chain"` - PrivateKey string `yaml:"private_key" json:"private_key"` + ServerName string `yaml:"server_name" json:"server_name,omitempty"` + ForceHTTPS bool `yaml:"force_https" json:"force_https,omitempty"` + PortHTTPS int `yaml:"port_https" json:"port_https,omitempty"` + PortDNSOverTLS int `yaml:"port_dns_over_tls" json:"port_dns_over_tls,omitempty"` + + dnsforward.TLSConfig `yaml:",inline" json:",inline"` // only for API, no need to be stored in config StatusCertificate string `yaml:"status_cert" json:"status_cert,omitempty"` diff --git a/dns.go b/dns.go index 3e800892..4a5102d5 100644 --- a/dns.go +++ b/dns.go @@ -51,6 +51,11 @@ func generateServerConfig() dnsforward.ServerConfig { Filters: filters, } + newconfig.TLSConfig = config.TLS.TLSConfig + if config.TLS.PortDNSOverTLS != 0 { + newconfig.TLSListenAddr = &net.TCPAddr{IP: net.ParseIP(config.DNS.BindHost), Port: config.TLS.PortDNSOverTLS} + } + for _, u := range config.DNS.UpstreamDNS { dnsUpstream, err := upstream.AddressToUpstream(u, config.DNS.BootstrapDNS, dnsforward.DefaultTimeout) if err != nil { diff --git a/dnsforward/dnsforward.go b/dnsforward/dnsforward.go index e1006f83..54695c6f 100644 --- a/dnsforward/dnsforward.go +++ b/dnsforward/dnsforward.go @@ -1,6 +1,7 @@ package dnsforward import ( + "crypto/tls" "errors" "fmt" "net" @@ -55,6 +56,7 @@ func NewServer(baseDir string) *Server { } // FilteringConfig represents the DNS filtering configuration of AdGuard Home +// The zero FilteringConfig is empty and ready for use. type FilteringConfig struct { ProtectionEnabled bool `yaml:"protection_enabled"` // whether or not use any of dnsfilter features FilteringEnabled bool `yaml:"filtering_enabled"` // whether or not use filter lists @@ -68,6 +70,12 @@ type FilteringConfig struct { dnsfilter.Config `yaml:",inline"` } +type TLSConfig struct { + TLSListenAddr *net.TCPAddr `yaml:"-" json:"-"` + CertificateChain string `yaml:"certificate_chain" json:"certificate_chain"` + PrivateKey string `yaml:"private_key" json:"private_key"` +} + // ServerConfig represents server configuration. // The zero ServerConfig is empty and ready for use. type ServerConfig struct { @@ -77,6 +85,7 @@ type ServerConfig struct { Filters []dnsfilter.Filter // A list of filters to use FilteringConfig + TLSConfig } // if any of ServerConfig values are zero, then default values from below are used @@ -154,6 +163,15 @@ func (s *Server) startInternal(config *ServerConfig) error { Handler: s.handleDNSRequest, } + if s.TLSListenAddr != nil && s.CertificateChain != "" && s.PrivateKey != "" { + proxyConfig.TLSListenAddr = s.TLSListenAddr + keypair, err := tls.X509KeyPair([]byte(s.CertificateChain), []byte(s.PrivateKey)) + if err != nil { + return errorx.Decorate(err, "Failed to parse TLS keypair") + } + proxyConfig.TLSConfig = &tls.Config{Certificates: []tls.Certificate{keypair}} + } + if proxyConfig.UDPListenAddr == nil { proxyConfig.UDPListenAddr = defaultValues.UDPListenAddr }