9a764b9b82
Merge in DNS/adguard-home from 3978-ecs-ip to master
Updates #3978.
Squashed commit of the following:
commit 915b94afa4b6d90169f73d4fa171bc81bcc267a7
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Thu Mar 3 17:46:40 2022 +0300
all: rm dot
commit 2dd2ed081b199de7e5d8269dae5d08d53b5eea6d
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Thu Mar 3 17:42:45 2022 +0300
client: imp txt
commit 8d5a23df739f0b650f9f3870141fd83e8fa0c1e0
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Thu Mar 3 14:36:04 2022 +0300
client: imp text
commit 69c856749a20144822ef3f1f67c5f3e3c24f5374
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Thu Mar 3 14:24:56 2022 +0300
client: imp description
commit cd0150128ad29d1874492735a5d621c0803ad0bd
Merge: 28181fbc e0b557ed
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Wed Mar 2 21:02:16 2022 +0300
Merge branch 'master' into 3978-ecs-ip
commit 28181fbc79eb22e7fd13cbd1d5a3c040af9fa2a4
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date: Wed Mar 2 20:45:50 2022 +0300
client: show ecs
commit cdc5e7f8c4155b798426d815eed0da547ef6efb7
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Thu Feb 17 20:15:56 2022 +0300
openapi: fix milestone
commit 404d6d822fa1ba4ed4cd41d92d4c1b805342fe55
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Thu Feb 17 20:08:21 2022 +0300
all: fix deps, docs
commit 8fb80526f1e251d3b7b193c53a4a6dee0e22c145
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Thu Feb 17 19:39:34 2022 +0300
all: add querylog ecs backend
163 lines
3.8 KiB
Go
163 lines
3.8 KiB
Go
package querylog
|
|
|
|
import (
|
|
"net"
|
|
"net/http"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
|
|
"github.com/AdguardTeam/AdGuardHome/internal/filtering"
|
|
"github.com/AdguardTeam/golibs/errors"
|
|
"github.com/AdguardTeam/golibs/log"
|
|
"github.com/AdguardTeam/golibs/timeutil"
|
|
"github.com/miekg/dns"
|
|
)
|
|
|
|
// QueryLog - main interface
|
|
type QueryLog interface {
|
|
Start()
|
|
|
|
// Close query log object
|
|
Close()
|
|
|
|
// Add a log entry
|
|
Add(params *AddParams)
|
|
|
|
// WriteDiskConfig - write configuration
|
|
WriteDiskConfig(c *Config)
|
|
}
|
|
|
|
// Config - configuration object
|
|
type Config struct {
|
|
// ConfigModified is called when the configuration is changed, for
|
|
// example by HTTP requests.
|
|
ConfigModified func()
|
|
|
|
// HTTPRegister registers an HTTP handler.
|
|
HTTPRegister func(string, string, func(http.ResponseWriter, *http.Request))
|
|
|
|
// FindClient returns client information by their IDs.
|
|
FindClient func(ids []string) (c *Client, err error)
|
|
|
|
// BaseDir is the base directory for log files.
|
|
BaseDir string
|
|
|
|
// RotationIvl is the interval for log rotation. After that period, the
|
|
// old log file will be renamed, NOT deleted, so the actual log
|
|
// retention time is twice the interval. The value must be one of:
|
|
//
|
|
// 6 * time.Hour
|
|
// 1 * timeutil.Day
|
|
// 7 * timeutil.Day
|
|
// 30 * timeutil.Day
|
|
// 90 * timeutil.Day
|
|
//
|
|
RotationIvl time.Duration
|
|
|
|
// MemSize is the number of entries kept in a memory buffer before they
|
|
// are flushed to disk.
|
|
MemSize uint32
|
|
|
|
// Enabled tells if the query log is enabled.
|
|
Enabled bool
|
|
|
|
// FileEnabled tells if the query log writes logs to files.
|
|
FileEnabled bool
|
|
|
|
// AnonymizeClientIP tells if the query log should anonymize clients' IP
|
|
// addresses.
|
|
AnonymizeClientIP bool
|
|
|
|
// Anonymizer processes the IP addresses to anonymize those if needed.
|
|
Anonymizer *aghnet.IPMut
|
|
}
|
|
|
|
// AddParams is the parameters for adding an entry.
|
|
type AddParams struct {
|
|
Question *dns.Msg
|
|
|
|
// ReqECS is the IP network extracted from EDNS Client-Subnet option of a
|
|
// request.
|
|
ReqECS *net.IPNet
|
|
|
|
// Answer is the response which is sent to the client, if any.
|
|
Answer *dns.Msg
|
|
|
|
// OrigAnswer is the response from an upstream server. It's only set if the
|
|
// answer has been modified by filtering.
|
|
OrigAnswer *dns.Msg
|
|
|
|
// Result is the filtering result (optional).
|
|
Result *filtering.Result
|
|
|
|
// Elapsed is the time spent for processing the request.
|
|
Elapsed time.Duration
|
|
|
|
ClientID string
|
|
|
|
ClientIP net.IP
|
|
|
|
// Upstream is the URL of the upstream DNS server.
|
|
Upstream string
|
|
|
|
ClientProto ClientProto
|
|
|
|
// Cached indicates if the response is served from cache.
|
|
Cached bool
|
|
|
|
// AuthenticatedData shows if the response had the AD bit set.
|
|
AuthenticatedData bool
|
|
}
|
|
|
|
// validate returns an error if the parameters aren't valid.
|
|
func (p *AddParams) validate() (err error) {
|
|
switch {
|
|
case p.Question == nil:
|
|
return errors.Error("question is nil")
|
|
case len(p.Question.Question) != 1:
|
|
return errors.Error("more than one question")
|
|
case len(p.Question.Question[0].Name) == 0:
|
|
return errors.Error("no host in question")
|
|
case p.ClientIP == nil:
|
|
return errors.Error("no client ip")
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// New creates a new instance of the query log.
|
|
func New(conf Config) (ql QueryLog) {
|
|
return newQueryLog(conf)
|
|
}
|
|
|
|
// newQueryLog crates a new queryLog.
|
|
func newQueryLog(conf Config) (l *queryLog) {
|
|
findClient := conf.FindClient
|
|
if findClient == nil {
|
|
findClient = func(_ []string) (_ *Client, _ error) {
|
|
return nil, nil
|
|
}
|
|
}
|
|
|
|
l = &queryLog{
|
|
findClient: findClient,
|
|
|
|
logFile: filepath.Join(conf.BaseDir, queryLogFileName),
|
|
anonymizer: conf.Anonymizer,
|
|
}
|
|
|
|
l.conf = &Config{}
|
|
*l.conf = conf
|
|
|
|
if !checkInterval(conf.RotationIvl) {
|
|
log.Info(
|
|
"querylog: warning: unsupported rotation interval %s, setting to 1 day",
|
|
conf.RotationIvl,
|
|
)
|
|
l.conf.RotationIvl = timeutil.Day
|
|
}
|
|
|
|
return l
|
|
}
|