diff --git a/internal/aghtls/aghtls.go b/internal/aghtls/aghtls.go index 5dc7a382..209bef1d 100644 --- a/internal/aghtls/aghtls.go +++ b/internal/aghtls/aghtls.go @@ -1,7 +1,12 @@ // Package aghtls contains utilities for work with TLS. package aghtls -import "crypto/tls" +import ( + "crypto/tls" + + "github.com/AdguardTeam/golibs/log" + "golang.org/x/exp/slices" +) // SaferCipherSuites returns a set of default cipher suites with vulnerable and // weak cipher suites removed. @@ -28,3 +33,14 @@ func SaferCipherSuites() (safe []uint16) { return safe } + +func UserPreferredCipherSuites(ciphers []string) (userCiphers []uint16) { + for _, s := range tls.CipherSuites() { + if slices.Contains(ciphers, s.Name) { + userCiphers = append(userCiphers, s.ID) + log.Debug("user specified cipher : %s, ID : %d", s.Name, s.ID) + } + } + + return userCiphers +} diff --git a/internal/dnsforward/config.go b/internal/dnsforward/config.go index f8e51ff0..3a70bbeb 100644 --- a/internal/dnsforward/config.go +++ b/internal/dnsforward/config.go @@ -165,6 +165,9 @@ type TLSConfig struct { cert tls.Certificate // DNS names from certificate (SAN) or CN value from Subject dnsNames []string + + // ciphers specified by user + TLSCiphers []string `yaml:"tls_ciphers" json:"-"` } // DNSCryptConfig is the DNSCrypt server configuration struct. diff --git a/internal/home/home.go b/internal/home/home.go index 42c44249..0b325298 100644 --- a/internal/home/home.go +++ b/internal/home/home.go @@ -383,6 +383,7 @@ func initWeb(args options, clientBuildFS fs.FS) (web *Web, err error) { clientBetaFS: clientBetaFS, serveHTTP3: config.DNS.ServeHTTP3, + tlsCiphers: config.TLS.TLSCiphers, } web = newWeb(&webConf) diff --git a/internal/home/web.go b/internal/home/web.go index 3e248d80..d1193885 100644 --- a/internal/home/web.go +++ b/internal/home/web.go @@ -57,6 +57,9 @@ type webConfig struct { firstRun bool serveHTTP3 bool + + // ciphers specified by user + tlsCiphers []string } // httpsServer contains the data for the HTTPS server. @@ -288,6 +291,14 @@ func (web *Web) tlsServerLoop() { web.httpsServer.cond.L.Unlock() + var cipher []uint16 + + if len(web.conf.tlsCiphers) == 0 { + cipher = aghtls.SaferCipherSuites() + } else { + cipher = aghtls.UserPreferredCipherSuites(web.conf.tlsCiphers) + } + addr := netutil.JoinHostPort(web.conf.BindHost.String(), web.conf.PortHTTPS) web.httpsServer.server = &http.Server{ ErrorLog: log.StdLog("web: https", log.DEBUG), @@ -295,7 +306,7 @@ func (web *Web) tlsServerLoop() { TLSConfig: &tls.Config{ Certificates: []tls.Certificate{web.httpsServer.cert}, RootCAs: Context.tlsRoots, - CipherSuites: aghtls.SaferCipherSuites(), + CipherSuites: cipher, MinVersion: tls.VersionTLS12, }, Handler: withMiddlewares(Context.mux, limitRequestBody),