Pull request 2371: AGDNS-2714-tls-manager

Merge in DNS/adguard-home from AGDNS-2714-tls-manager to master

Squashed commit of the following:

commit 5c7cd1fa6d8a9bc1fd0f891818589b48bee641dc
Merge: 381f7666b 810ae9483
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Mar 26 14:13:49 2025 +0300

    Merge branch 'master' into AGDNS-2714-tls-manager

commit 381f7666b063d225b114976a280e65df736495fe
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Mar 25 19:53:12 2025 +0300

    home: imp code

commit 20be72abd449fcc76417381edf7d375248a11e9e
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Mar 25 19:19:51 2025 +0300

    home: imp code

commit b5a06e6a15b0f8511819267133a551a56e051499
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Mar 24 21:45:41 2025 +0300

    home: imp code

commit a6a5ba727ebbc59d6de4d3762ac196d2cf194875
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Mar 20 21:06:34 2025 +0300

    home: imp docs

commit 71d379bafc3f42377ce72add2cab3a56a796941d
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Mar 20 20:47:15 2025 +0300

    all: upd chlog

commit be69a5b85d4cd4295a9b68e1c2c2205179a3e7f2
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Mar 19 20:14:20 2025 +0300

    home: imp docs

commit 85b28db73b59b90365ff23fc5fc90dc1a10cc152
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Mar 19 20:07:59 2025 +0300

    home: imp code

commit c11e4c9e500f7ead96a84575dac08e198569c14d
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Mar 19 19:11:59 2025 +0300

    home: imp code

commit 60eff2c66369ca8705a6bb859b5a65d3e6d0df5e
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Mar 18 21:27:49 2025 +0300

    home: imp code

commit fa9d57b2834fe3df85630d95b9eb022f1db372b1
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Mar 18 21:14:56 2025 +0300

    home: imp docs

commit 3f561b64750ab57ef83793522a0b313225245e1e
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Mar 18 20:59:59 2025 +0300

    home: imp code

commit 927296c49f861d102dad8d24e8b67e6204a6c17a
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Mar 18 18:19:22 2025 +0300

    home: imp naming

commit e35f742e42a7304993a924928b51f2452634e258
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Mar 18 17:53:17 2025 +0300

    home: tls manager web api

commit 85a4de7931fea68464fe36c1fb27686eb5b50066
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Mar 18 15:06:34 2025 +0300

    home: tls manager config

commit 515b26d6bd6d837d3db937354f74d895b5793206
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Mar 17 22:15:25 2025 +0300

    home: tls manager
This commit is contained in:
Stanislav Chzhen
2025-03-26 14:26:57 +03:00
parent 810ae94832
commit 8b4768aadd
8 changed files with 420 additions and 208 deletions

View File

@@ -3,7 +3,6 @@ package home
import (
"context"
"crypto/x509"
"fmt"
"io/fs"
"log/slog"
@@ -22,7 +21,6 @@ import (
"github.com/AdguardTeam/AdGuardHome/internal/aghalg"
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
"github.com/AdguardTeam/AdGuardHome/internal/aghos"
"github.com/AdguardTeam/AdGuardHome/internal/aghtls"
"github.com/AdguardTeam/AdGuardHome/internal/arpdb"
"github.com/AdguardTeam/AdGuardHome/internal/dhcpd"
"github.com/AdguardTeam/AdGuardHome/internal/dnsforward"
@@ -81,10 +79,6 @@ type homeContext struct {
workDir string // Location of our directory, used to protect against CWD being somewhere else
pidFileName string // PID file name. Empty if no PID file was created.
controlLock sync.Mutex
tlsRoots *x509.CertPool // list of root CAs for TLSv1.2
// tlsCipherIDs are the ID of the cipher suites that AdGuard Home must use.
tlsCipherIDs []uint16
// firstRun, if true, tells AdGuard Home to only start the web interface
// service, and only serve the first-run APIs.
@@ -142,7 +136,6 @@ func Main(clientBuildFS fs.FS) {
func setupContext(opts options) (err error) {
globalContext.firstRun = detectFirstRun()
globalContext.tlsRoots = aghtls.SystemRootCAs()
globalContext.mux = http.NewServeMux()
if !opts.noEtcHosts {
@@ -274,18 +267,13 @@ func setupOpts(opts options) (err error) {
return nil
}
// initContextClients initializes Context clients and related fields.
// initContextClients initializes Context clients and related fields. All
// arguments must not be nil.
func initContextClients(
ctx context.Context,
logger *slog.Logger,
sigHdlr *signalHandler,
) (err error) {
err = setupDNSFilteringConf(ctx, logger, config.Filtering)
if err != nil {
// Don't wrap the error, because it's informative enough as is.
return err
}
//lint:ignore SA1019 Migration is not over.
config.DHCP.WorkDir = globalContext.workDir
config.DHCP.DataDir = globalContext.getDataDir()
@@ -358,11 +346,13 @@ func setupBindOpts(opts options) (err error) {
return nil
}
// setupDNSFilteringConf sets up DNS filtering configuration settings.
// setupDNSFilteringConf sets up DNS filtering configuration settings. All
// arguments must not be nil.
func setupDNSFilteringConf(
ctx context.Context,
baseLogger *slog.Logger,
conf *filtering.Config,
tlsMgr *tlsManager,
) (err error) {
const (
dnsTimeout = 3 * time.Second
@@ -388,7 +378,7 @@ func setupDNSFilteringConf(
conf.Filters = slices.Clone(config.Filters)
conf.WhitelistFilters = slices.Clone(config.WhitelistFilters)
conf.UserRules = slices.Clone(config.UserRules)
conf.HTTPClient = httpClient()
conf.HTTPClient = httpClient(tlsMgr)
cacheTime := time.Duration(conf.CacheTime) * time.Minute
@@ -630,6 +620,23 @@ func run(opts options, clientBuildFS fs.FS, done chan struct{}, sigHdlr *signalH
err = initContextClients(ctx, slogLogger, sigHdlr)
fatalOnError(err)
tlsMgrLogger := slogLogger.With(slogutil.KeyPrefix, "tls_manager")
tlsMgr, err := newTLSManager(ctx, &tlsManagerConfig{
logger: tlsMgrLogger,
configModified: onConfigModified,
tlsSettings: config.TLS,
servePlainDNS: config.DNS.ServePlainDNS,
})
if err != nil {
tlsMgrLogger.ErrorContext(ctx, "initializing", slogutil.KeyError, err)
onConfigModified()
}
globalContext.tls = tlsMgr
err = setupDNSFilteringConf(ctx, slogLogger, config.Filtering, tlsMgr)
fatalOnError(err)
err = setupOpts(opts)
fatalOnError(err)
@@ -642,7 +649,7 @@ func run(opts options, clientBuildFS fs.FS, done chan struct{}, sigHdlr *signalH
// TODO(e.burkov): This could be made earlier, probably as the option's
// effect.
cmdlineUpdate(ctx, slogLogger, opts, upd)
cmdlineUpdate(ctx, slogLogger, opts, upd, tlsMgr)
if !globalContext.firstRun {
// Save the updated config.
@@ -664,19 +671,14 @@ func run(opts options, clientBuildFS fs.FS, done chan struct{}, sigHdlr *signalH
globalContext.auth, err = initUsers()
fatalOnError(err)
tlsMgrLogger := slogLogger.With(slogutil.KeyPrefix, "tls_manager")
tlsMgr, err := newTLSManager(ctx, tlsMgrLogger, config.TLS, config.DNS.ServePlainDNS)
if err != nil {
log.Error("initializing tls: %s", err)
onConfigModified()
}
globalContext.tls = tlsMgr
sigHdlr.addTLSManager(tlsMgr)
globalContext.web, err = initWeb(ctx, opts, clientBuildFS, upd, slogLogger, tlsMgr, customURL)
web, err := initWeb(ctx, opts, clientBuildFS, upd, slogLogger, tlsMgr, customURL)
fatalOnError(err)
globalContext.web = web
tlsMgr.setWebAPI(web)
sigHdlr.addTLSManager(tlsMgr)
statsDir, querylogDir, err := checkStatsAndQuerylogDirs(&globalContext, config)
fatalOnError(err)
@@ -706,7 +708,7 @@ func run(opts options, clientBuildFS fs.FS, done chan struct{}, sigHdlr *signalH
checkPermissions(ctx, slogLogger, globalContext.workDir, confPath, dataDir, statsDir, querylogDir)
}
globalContext.web.start(ctx)
web.start(ctx)
// Wait for other goroutines to complete their job.
<-done
@@ -1058,8 +1060,15 @@ type jsonError struct {
Message string `json:"message"`
}
// cmdlineUpdate updates current application and exits. l must not be nil.
func cmdlineUpdate(ctx context.Context, l *slog.Logger, opts options, upd *updater.Updater) {
// cmdlineUpdate updates current application and exits. l and tlsMgr must not
// be nil.
func cmdlineUpdate(
ctx context.Context,
l *slog.Logger,
opts options,
upd *updater.Updater,
tlsMgr *tlsManager,
) {
if !opts.performUpdate {
return
}
@@ -1069,7 +1078,7 @@ func cmdlineUpdate(ctx context.Context, l *slog.Logger, opts options, upd *updat
//
// TODO(e.burkov): We could probably initialize the internal resolver
// separately.
err := initDNSServer(nil, nil, nil, nil, nil, nil, &tlsConfigSettings{}, l)
err := initDNSServer(nil, nil, nil, nil, nil, nil, &tlsConfigSettings{}, tlsMgr, l)
fatalOnError(err)
l.InfoContext(ctx, "performing update via cli")