diff --git a/CHANGELOG.md b/CHANGELOG.md index 97b119be..e8af7f0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ and this project adheres to ## Added +- The new optional `tls.override_tls_ciphers` property, which allows + overriding TLS ciphers used by AdGuard Home ([#4925], [#4990]). - The ability to serve DNS on link-local IPv6 addresses ([#2926]). - The ability to put [ClientIDs][clientid] into DNS-over-HTTPS hostnames as opposed to URL paths ([#3418]). Note that AdGuard Home checks the server name @@ -36,8 +38,10 @@ and this project adheres to [#2926]: https://github.com/AdguardTeam/AdGuardHome/issues/2926 [#3418]: https://github.com/AdguardTeam/AdGuardHome/issues/3418 +[#4925]: https://github.com/AdguardTeam/AdGuardHome/issues/4925 [#4942]: https://github.com/AdguardTeam/AdGuardHome/issues/4942 [#4986]: https://github.com/AdguardTeam/AdGuardHome/issues/4986 +[#4990]: https://github.com/AdguardTeam/AdGuardHome/issues/4990 [#4993]: https://github.com/AdguardTeam/AdGuardHome/issues/4993 [#5010]: https://github.com/AdguardTeam/AdGuardHome/issues/5010 @@ -50,7 +54,7 @@ and this project adheres to See also the [v0.107.17 GitHub milestone][ms-v0.107.17]. -[ms-v0.107.17]: https://github.com/AdguardTeam/AdGuardHome/milestone/52?closed=1 +[ms-v0.107.17]: https://github.com/AdguardTeam/AdGuardHome/milestone/52?closed=1 --> diff --git a/internal/dnsforward/config.go b/internal/dnsforward/config.go index f8e51ff0..caad6547 100644 --- a/internal/dnsforward/config.go +++ b/internal/dnsforward/config.go @@ -12,7 +12,6 @@ import ( "github.com/AdguardTeam/AdGuardHome/internal/aghalg" "github.com/AdguardTeam/AdGuardHome/internal/aghhttp" - "github.com/AdguardTeam/AdGuardHome/internal/aghtls" "github.com/AdguardTeam/AdGuardHome/internal/filtering" "github.com/AdguardTeam/dnsproxy/proxy" "github.com/AdguardTeam/dnsproxy/upstream" @@ -165,6 +164,10 @@ type TLSConfig struct { cert tls.Certificate // 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:"-"` } // DNSCryptConfig is the DNSCrypt server configuration struct. @@ -193,7 +196,9 @@ type ServerConfig struct { UpstreamTimeout time.Duration TLSv12Roots *x509.CertPool // list of root CAs for TLSv1.2 - TLSCiphers []uint16 // list of TLS ciphers to use + + // TLSCiphers are the IDs of TLS cipher suites to use. + TLSCiphers []uint16 // Called when the configuration is changed by HTTP request ConfigModified func() @@ -348,17 +353,13 @@ func UpstreamHTTPVersions(http3 bool) (v []upstream.HTTPVersion) { // prepareUpstreamSettings - prepares upstream DNS server settings func (s *Server) prepareUpstreamSettings() error { - // We're setting a customized set of RootCAs - // The reason is that Go default mechanism of loading TLS roots - // does not always work properly on some routers so we're - // loading roots manually and pass it here. - // See "util.LoadSystemRootCAs" + // We're setting a customized set of RootCAs. The reason is that Go default + // mechanism of loading TLS roots does not always work properly on some + // routers so we're loading roots manually and pass it here. + // + // See [aghtls.SystemRootCAs]. upstream.RootCAs = s.conf.TLSv12Roots - - // See util.InitTLSCiphers -- removed unsafe ciphers - if len(s.conf.TLSCiphers) > 0 { - upstream.CipherSuites = s.conf.TLSCiphers - } + upstream.CipherSuites = s.conf.TLSCiphers // Load upstreams either from the file, or from the settings var upstreams []string @@ -494,7 +495,7 @@ func (s *Server) prepareTLS(proxyConfig *proxy.Config) error { proxyConfig.TLSConfig = &tls.Config{ GetCertificate: s.onGetCertificate, - CipherSuites: aghtls.SaferCipherSuites(), + CipherSuites: s.conf.TLSCiphers, MinVersion: tls.VersionTLS12, } diff --git a/internal/home/config.go b/internal/home/config.go index 7df4f853..c7198d93 100644 --- a/internal/home/config.go +++ b/internal/home/config.go @@ -9,6 +9,7 @@ import ( "sync" "github.com/AdguardTeam/AdGuardHome/internal/aghalg" + "github.com/AdguardTeam/AdGuardHome/internal/aghtls" "github.com/AdguardTeam/AdGuardHome/internal/dhcpd" "github.com/AdguardTeam/AdGuardHome/internal/dnsforward" "github.com/AdguardTeam/AdGuardHome/internal/filtering" @@ -380,6 +381,7 @@ func parseConfig() (err error) { // we add support for HTTP/3 for web admin interface. addPorts(udpPorts, udpPort(config.TLS.PortDNSOverQUIC)) } + if err = tcpPorts.Validate(); err != nil { return fmt.Errorf("validating tcp ports: %w", err) } else if err = udpPorts.Validate(); err != nil { @@ -394,6 +396,11 @@ func parseConfig() (err error) { config.DNS.UpstreamTimeout = timeutil.Duration{Duration: dnsforward.DefaultTimeout} } + err = setContextTLSCipherIDs() + if err != nil { + return err + } + return nil } @@ -496,3 +503,23 @@ func (c *configuration) write() (err error) { return nil } + +// setContextTLSCipherIDs sets the TLS cipher suite IDs to use. +func setContextTLSCipherIDs() (err error) { + if len(config.TLS.OverrideTLSCiphers) == 0 { + log.Info("tls: using default ciphers") + + Context.tlsCipherIDs = aghtls.SaferCipherSuites() + + return nil + } + + log.Info("tls: overriding ciphers: %s", config.TLS.OverrideTLSCiphers) + + Context.tlsCipherIDs, err = aghtls.ParseCiphers(config.TLS.OverrideTLSCiphers) + if err != nil { + return fmt.Errorf("parsing override ciphers: %w", err) + } + + return nil +} diff --git a/internal/home/home.go b/internal/home/home.go index 70697a12..5d3582e9 100644 --- a/internal/home/home.go +++ b/internal/home/home.go @@ -84,6 +84,10 @@ type homeContext struct { transport *http.Transport client *http.Client appSignalChannel chan os.Signal // Channel for receiving OS signals by the console app + + // tlsCipherIDs are the ID of the cipher suites that AdGuard Home must use. + tlsCipherIDs []uint16 + // runningAsService flag is set to true when options are passed from the service runner runningAsService bool } @@ -153,7 +157,7 @@ func setupContext(opts options) { Proxy: getHTTPProxy, TLSClientConfig: &tls.Config{ RootCAs: Context.tlsRoots, - CipherSuites: aghtls.SaferCipherSuites(), + CipherSuites: Context.tlsCipherIDs, MinVersion: tls.VersionTLS12, }, } diff --git a/internal/home/web.go b/internal/home/web.go index 3cd04630..7836355f 100644 --- a/internal/home/web.go +++ b/internal/home/web.go @@ -11,7 +11,6 @@ import ( "github.com/AdguardTeam/AdGuardHome/internal/aghhttp" "github.com/AdguardTeam/AdGuardHome/internal/aghnet" - "github.com/AdguardTeam/AdGuardHome/internal/aghtls" "github.com/AdguardTeam/golibs/errors" "github.com/AdguardTeam/golibs/log" "github.com/AdguardTeam/golibs/netutil" @@ -298,7 +297,7 @@ func (web *Web) tlsServerLoop() { TLSConfig: &tls.Config{ Certificates: []tls.Certificate{web.httpsServer.cert}, RootCAs: Context.tlsRoots, - CipherSuites: aghtls.SaferCipherSuites(), + CipherSuites: Context.tlsCipherIDs, MinVersion: tls.VersionTLS12, }, Handler: withMiddlewares(Context.mux, limitRequestBody), @@ -332,7 +331,7 @@ func (web *Web) mustStartHTTP3(address string) { TLSConfig: &tls.Config{ Certificates: []tls.Certificate{web.httpsServer.cert}, RootCAs: Context.tlsRoots, - CipherSuites: aghtls.SaferCipherSuites(), + CipherSuites: Context.tlsCipherIDs, MinVersion: tls.VersionTLS12, }, Handler: withMiddlewares(Context.mux, limitRequestBody),