Pull request 2284: AG-32257-file-permission-mitigation

Squashed commit of the following:

commit 6e0e61ec2e95a563b04a622f46c6bbe2b2e12711
Merge: e3cccc01a 5b5b39713
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Oct 2 20:51:29 2024 +0300

    Merge branch 'master' into AG-32257-file-permission-mitigation

commit e3cccc01a9cbd382cec0fcd7f3685e43acb48424
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Oct 2 19:57:32 2024 +0300

    dnsforward: imp test

commit 16ecebbc2fd2f4afe2bf475774af1786fa7a02c0
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Oct 2 19:22:10 2024 +0300

    configmigrate: imp tests

commit da8777c3a7c81e17c0d08cfff4e3a9c8d2bbd649
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Oct 2 18:58:46 2024 +0300

    all: imp types, tests

commit 58822a0ef8aa2d944a667d1ba77fe23ff52af424
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Oct 2 18:28:37 2024 +0300

    all: imp chlog

commit 8ce81f918cc5cf43972e2045532a48c829257a2f
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Oct 2 18:09:57 2024 +0300

    all: improve permissions, add safe_fs_patterns
This commit is contained in:
Ainar Garipov
2024-10-02 21:00:15 +03:00
parent 5b5b397132
commit 355cec1d7b
31 changed files with 879 additions and 52 deletions

View File

@@ -9,6 +9,7 @@ import (
"sync"
"time"
"github.com/AdguardTeam/AdGuardHome/internal/aghos"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/netutil"
@@ -89,7 +90,7 @@ func InitAuth(
trustedProxies: trustedProxies,
}
var err error
a.db, err = bbolt.Open(dbFilename, 0o644, nil)
a.db, err = bbolt.Open(dbFilename, aghos.DefaultPermFile, nil)
if err != nil {
log.Error("auth: open DB: %s: %s", dbFilename, err)
if err.Error() == "invalid argument" {

View File

@@ -9,6 +9,7 @@ import (
"sync"
"github.com/AdguardTeam/AdGuardHome/internal/aghalg"
"github.com/AdguardTeam/AdGuardHome/internal/aghos"
"github.com/AdguardTeam/AdGuardHome/internal/aghtls"
"github.com/AdguardTeam/AdGuardHome/internal/configmigrate"
"github.com/AdguardTeam/AdGuardHome/internal/dhcpd"
@@ -26,9 +27,15 @@ import (
yaml "gopkg.in/yaml.v3"
)
// dataDir is the name of a directory under the working one to store some
// persistent data.
const dataDir = "data"
const (
// dataDir is the name of a directory under the working one to store some
// persistent data.
dataDir = "data"
// userFilterDataDir is the name of the directory used to store users'
// FS-based rule lists.
userFilterDataDir = "userfilters"
)
// logSettings are the logging settings part of the configuration file.
type logSettings struct {
@@ -520,6 +527,7 @@ func parseConfig() (err error) {
migrator := configmigrate.New(&configmigrate.Config{
WorkingDir: Context.workDir,
DataDir: Context.getDataDir(),
})
var upgraded bool
@@ -534,7 +542,7 @@ func parseConfig() (err error) {
confPath := configFilePath()
log.Debug("writing config file %q after config upgrade", confPath)
err = maybe.WriteFile(confPath, config.fileData, 0o644)
err = maybe.WriteFile(confPath, config.fileData, aghos.DefaultPermFile)
if err != nil {
return fmt.Errorf("writing new config: %w", err)
}
@@ -700,7 +708,7 @@ func (c *configuration) write() (err error) {
return fmt.Errorf("generating config file: %w", err)
}
err = maybe.WriteFile(confPath, buf.Bytes(), 0o644)
err = maybe.WriteFile(confPath, buf.Bytes(), aghos.DefaultPermFile)
if err != nil {
return fmt.Errorf("writing config file: %w", err)
}

View File

@@ -270,9 +270,9 @@ DNSStubListener=no
const resolvConfPath = "/etc/resolv.conf"
// Deactivate DNSStubListener
func disableDNSStubListener() error {
func disableDNSStubListener() (err error) {
dir := filepath.Dir(resolvedConfPath)
err := os.MkdirAll(dir, 0o755)
err = os.MkdirAll(dir, 0o755)
if err != nil {
return fmt.Errorf("os.MkdirAll: %s: %w", dir, err)
}
@@ -413,9 +413,12 @@ func (web *webAPI) handleInstallConfigure(w http.ResponseWriter, r *http.Request
copyInstallSettings(curConfig, config)
Context.firstRun = false
config.HTTPConfig.Address = netip.AddrPortFrom(req.Web.IP, req.Web.Port)
config.DNS.BindHosts = []netip.Addr{req.DNS.IP}
config.DNS.Port = req.DNS.Port
config.Filtering.SafeFSPatterns = []string{
filepath.Join(Context.workDir, userFilterDataDir, "*"),
}
config.HTTPConfig.Address = netip.AddrPortFrom(req.Web.IP, req.Web.Port)
u := &webUser{
Name: req.Username,

View File

@@ -47,14 +47,9 @@ func onConfigModified() {
// initDNS updates all the fields of the [Context] needed to initialize the DNS
// server and initializes it at last. It also must not be called unless
// [config] and [Context] are initialized. l must not be nil.
func initDNS(l *slog.Logger) (err error) {
func initDNS(l *slog.Logger, statsDir, querylogDir string) (err error) {
anonymizer := config.anonymizer()
statsDir, querylogDir, err := checkStatsAndQuerylogDirs(&Context, config)
if err != nil {
return err
}
statsConf := stats.Config{
Logger: l.With(slogutil.KeyPrefix, "stats"),
Filename: filepath.Join(statsDir, "stats.db"),

View File

@@ -31,6 +31,7 @@ import (
"github.com/AdguardTeam/AdGuardHome/internal/filtering"
"github.com/AdguardTeam/AdGuardHome/internal/filtering/hashprefix"
"github.com/AdguardTeam/AdGuardHome/internal/filtering/safesearch"
"github.com/AdguardTeam/AdGuardHome/internal/permcheck"
"github.com/AdguardTeam/AdGuardHome/internal/querylog"
"github.com/AdguardTeam/AdGuardHome/internal/stats"
"github.com/AdguardTeam/AdGuardHome/internal/updater"
@@ -630,9 +631,9 @@ func run(opts options, clientBuildFS fs.FS, done chan struct{}) {
}
}
dir := Context.getDataDir()
err = os.MkdirAll(dir, 0o755)
fatalOnError(errors.Annotate(err, "creating DNS data dir at %s: %w", dir))
dataDir := Context.getDataDir()
err = os.MkdirAll(dataDir, aghos.DefaultPermDir)
fatalOnError(errors.Annotate(err, "creating DNS data dir at %s: %w", dataDir))
GLMode = opts.glinetMode
@@ -649,8 +650,11 @@ func run(opts options, clientBuildFS fs.FS, done chan struct{}) {
Context.web, err = initWeb(opts, clientBuildFS, upd, slogLogger)
fatalOnError(err)
statsDir, querylogDir, err := checkStatsAndQuerylogDirs(&Context, config)
fatalOnError(err)
if !Context.firstRun {
err = initDNS(slogLogger)
err = initDNS(slogLogger, statsDir, querylogDir)
fatalOnError(err)
Context.tls.start()
@@ -671,6 +675,12 @@ func run(opts options, clientBuildFS fs.FS, done chan struct{}) {
}
}
if permcheck.NeedsMigration(confPath) {
permcheck.Migrate(Context.workDir, dataDir, statsDir, querylogDir, confPath)
}
permcheck.Check(Context.workDir, dataDir, statsDir, querylogDir, confPath)
Context.web.start()
// Wait for other goroutines to complete their job.
@@ -714,7 +724,12 @@ func (c *configuration) anonymizer() (ipmut *aghnet.IPMut) {
// startMods initializes and starts the DNS server after installation. l must
// not be nil.
func startMods(l *slog.Logger) (err error) {
err = initDNS(l)
statsDir, querylogDir, err := checkStatsAndQuerylogDirs(&Context, config)
if err != nil {
return err
}
err = initDNS(l, statsDir, querylogDir)
if err != nil {
return err
}