diff --git a/dnsforward/config.go b/dnsforward/config.go index 5d06b9dc..4c86a2ff 100644 --- a/dnsforward/config.go +++ b/dnsforward/config.go @@ -154,10 +154,6 @@ func (s *Server) createProxyConfig() (proxy.Config, error) { MaxGoroutines: int(s.conf.MaxGoroutines), } - if s.conf.QUICListenAddr != nil { - proxyConfig.QUICListenAddr = []*net.UDPAddr{s.conf.QUICListenAddr} - } - if s.conf.CacheSize != 0 { proxyConfig.CacheEnabled = true proxyConfig.CacheSizeBytes = int(s.conf.CacheSize) @@ -240,34 +236,49 @@ func (s *Server) prepareIntlProxy() { // prepareTLS - prepares TLS configuration for the DNS proxy func (s *Server) prepareTLS(proxyConfig *proxy.Config) error { - if s.conf.TLSListenAddr != nil && len(s.conf.CertificateChainData) != 0 && len(s.conf.PrivateKeyData) != 0 { + if len(s.conf.CertificateChainData) == 0 || len(s.conf.PrivateKeyData) == 0 { + return nil + } + + if s.conf.TLSListenAddr == nil && + s.conf.QUICListenAddr == nil { + return nil + } + + if s.conf.TLSListenAddr != nil { proxyConfig.TLSListenAddr = []*net.TCPAddr{s.conf.TLSListenAddr} - var err error - s.conf.cert, err = tls.X509KeyPair(s.conf.CertificateChainData, s.conf.PrivateKeyData) + } + + if s.conf.QUICListenAddr != nil { + proxyConfig.QUICListenAddr = []*net.UDPAddr{s.conf.QUICListenAddr} + } + + var err error + s.conf.cert, err = tls.X509KeyPair(s.conf.CertificateChainData, s.conf.PrivateKeyData) + if err != nil { + return errorx.Decorate(err, "Failed to parse TLS keypair") + } + + if s.conf.StrictSNICheck { + x, err := x509.ParseCertificate(s.conf.cert.Certificate[0]) if err != nil { - return errorx.Decorate(err, "Failed to parse TLS keypair") + return errorx.Decorate(err, "x509.ParseCertificate(): %s", err) } - - if s.conf.StrictSNICheck { - x, err := x509.ParseCertificate(s.conf.cert.Certificate[0]) - if err != nil { - return errorx.Decorate(err, "x509.ParseCertificate(): %s", err) - } - if len(x.DNSNames) != 0 { - s.conf.dnsNames = x.DNSNames - log.Debug("DNS: using DNS names from certificate's SAN: %v", x.DNSNames) - sort.Strings(s.conf.dnsNames) - } else { - s.conf.dnsNames = append(s.conf.dnsNames, x.Subject.CommonName) - log.Debug("DNS: using DNS name from certificate's CN: %s", x.Subject.CommonName) - } - } - - proxyConfig.TLSConfig = &tls.Config{ - GetCertificate: s.onGetCertificate, - MinVersion: tls.VersionTLS12, + if len(x.DNSNames) != 0 { + s.conf.dnsNames = x.DNSNames + log.Debug("DNS: using DNS names from certificate's SAN: %v", x.DNSNames) + sort.Strings(s.conf.dnsNames) + } else { + s.conf.dnsNames = append(s.conf.dnsNames, x.Subject.CommonName) + log.Debug("DNS: using DNS name from certificate's CN: %s", x.Subject.CommonName) } } + + proxyConfig.TLSConfig = &tls.Config{ + GetCertificate: s.onGetCertificate, + MinVersion: tls.VersionTLS12, + } + upstream.RootCAs = s.conf.TLSv12Roots upstream.CipherSuites = s.conf.TLSCiphers return nil diff --git a/dnsforward/dnsforward_test.go b/dnsforward/dnsforward_test.go index a3eb94f1..a183d786 100644 --- a/dnsforward/dnsforward_test.go +++ b/dnsforward/dnsforward_test.go @@ -8,6 +8,7 @@ import ( "crypto/x509" "crypto/x509/pkix" "encoding/pem" + "fmt" "math/big" "net" "sort" @@ -128,6 +129,41 @@ func TestDotServer(t *testing.T) { } } +func TestDoqServer(t *testing.T) { + // Prepare the proxy server + _, certPem, keyPem := createServerTLSConfig(t) + s := createTestServer(t) + + s.conf.TLSConfig = TLSConfig{ + QUICListenAddr: &net.UDPAddr{Port: 0}, + CertificateChainData: certPem, + PrivateKeyData: keyPem, + } + + _ = s.Prepare(nil) + // Starting the server + err := s.Start() + assert.Nil(t, err) + + // Create a DNS-over-QUIC upstream + addr := s.dnsProxy.Addr(proxy.ProtoQUIC) + opts := upstream.Options{InsecureSkipVerify: true} + u, err := upstream.AddressToUpstream(fmt.Sprintf("quic://%s", addr), opts) + assert.Nil(t, err) + + // Send the test message + req := createGoogleATestMessage() + res, err := u.Exchange(req) + assert.Nil(t, err) + assertGoogleAResponse(t, res) + + // Stop the proxy + err = s.Stop() + if err != nil { + t.Fatalf("DNS server failed to stop: %s", err) + } +} + func TestServerRace(t *testing.T) { s := createTestServer(t) err := s.Start() diff --git a/go.sum b/go.sum index d1e535fa..60b7eda0 100644 --- a/go.sum +++ b/go.sum @@ -290,6 +290,7 @@ golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -382,6 +383,7 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=