Skip to content

Commit

Permalink
all: add querylog ecs backend
Browse files Browse the repository at this point in the history
  • Loading branch information
EugeneOne1 committed Feb 17, 2022
1 parent f131067 commit 8fb8052
Show file tree
Hide file tree
Showing 12 changed files with 94 additions and 60 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ and this project adheres to

### Added

- EDNS Client-Subnet information in query log request details ([#3978]).
- `windows/arm64` support ([#3057]).

### Changed
Expand Down Expand Up @@ -87,6 +88,7 @@ In this release, the schema version has changed from 12 to 13.
[#3367]: https://github.com/AdguardTeam/AdGuardHome/issues/3367
[#3381]: https://github.com/AdguardTeam/AdGuardHome/issues/3381
[#3503]: https://github.com/AdguardTeam/AdGuardHome/issues/3503
[#3978]: https://github.com/AdguardTeam/AdGuardHome/issues/3978
[#4216]: https://github.com/AdguardTeam/AdGuardHome/issues/4216
[#4221]: https://github.com/AdguardTeam/AdGuardHome/issues/4221
[#4238]: https://github.com/AdguardTeam/AdGuardHome/issues/4238
Expand Down
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.17

require (
github.com/AdguardTeam/dnsproxy v0.41.1
github.com/AdguardTeam/golibs v0.10.5
github.com/AdguardTeam/golibs v0.10.6
github.com/AdguardTeam/urlfilter v0.15.2
github.com/NYTimes/gziphandler v1.1.1
github.com/ameshkov/dnscrypt/v2 v2.2.3
Expand Down Expand Up @@ -64,3 +64,5 @@ require (
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
honnef.co/go/tools v0.2.2 // indirect
)

replace github.com/AdguardTeam/dnsproxy v0.41.1 => ../../dnsproxy/head
7 changes: 2 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,11 @@ dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBr
dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
github.com/AdguardTeam/dnsproxy v0.41.1 h1:sDWami83ZNp0XNdWsLECwIX/hPI5UnVrotRtPnrgDuo=
github.com/AdguardTeam/dnsproxy v0.41.1/go.mod h1:PZ9l22h3Er+5mxFQB7oHZMTvx+aa9R6LbzA/ikXQlS0=
github.com/AdguardTeam/golibs v0.4.0/go.mod h1:skKsDKIBB7kkFflLJBpfGX+G8QFTx0WKUzB6TIgtUj4=
github.com/AdguardTeam/golibs v0.4.2/go.mod h1:skKsDKIBB7kkFflLJBpfGX+G8QFTx0WKUzB6TIgtUj4=
github.com/AdguardTeam/golibs v0.10.3/go.mod h1:rSfQRGHIdgfxriDDNgNJ7HmE5zRoURq8R+VdR81Zuzw=
github.com/AdguardTeam/golibs v0.10.4/go.mod h1:rSfQRGHIdgfxriDDNgNJ7HmE5zRoURq8R+VdR81Zuzw=
github.com/AdguardTeam/golibs v0.10.5 h1:4/nl1yIBJOv5luVu9SURW8LfgOjI3zQ2moIUy/1k0y4=
github.com/AdguardTeam/golibs v0.10.5/go.mod h1:rSfQRGHIdgfxriDDNgNJ7HmE5zRoURq8R+VdR81Zuzw=
github.com/AdguardTeam/golibs v0.10.6 h1:6UG6LxWFnG7TfjNzeApw+T68Kqqov0fcDYk9RjhTdhc=
github.com/AdguardTeam/golibs v0.10.6/go.mod h1:rSfQRGHIdgfxriDDNgNJ7HmE5zRoURq8R+VdR81Zuzw=
github.com/AdguardTeam/gomitmproxy v0.2.0/go.mod h1:Qdv0Mktnzer5zpdpi5rAwixNJzW2FN91LjKJCkVbYGU=
github.com/AdguardTeam/urlfilter v0.15.2 h1:LZGgrm4l4Ys9eAqB+UUmZfiC6vHlDlYFhx0WXqo6LtQ=
github.com/AdguardTeam/urlfilter v0.15.2/go.mod h1:46YZDOV1+qtdRDuhZKVPSSp7JWWes0KayqHrKAFBdEI=
Expand Down
84 changes: 47 additions & 37 deletions internal/dnsforward/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,55 +41,65 @@ func (s *Server) processQueryLogsAndStats(dctx *dnsContext) (rc resultCode) {
// uninitialized while in use. This can happen after proxy server has been
// stopped, but its workers haven't yet exited.
if shouldLog && s.queryLog != nil {
p := &querylog.AddParams{
Question: msg,
Answer: pctx.Res,
OrigAnswer: dctx.origResp,
Result: dctx.result,
Elapsed: elapsed,
ClientID: dctx.clientID,
ClientIP: ip,
AuthenticatedData: dctx.responseAD,
}

switch pctx.Proto {
case proxy.ProtoHTTPS:
p.ClientProto = querylog.ClientProtoDoH
case proxy.ProtoQUIC:
p.ClientProto = querylog.ClientProtoDoQ
case proxy.ProtoTLS:
p.ClientProto = querylog.ClientProtoDoT
case proxy.ProtoDNSCrypt:
p.ClientProto = querylog.ClientProtoDNSCrypt
default:
// Consider this a plain DNS-over-UDP or DNS-over-TCP request.
}

if pctx.Upstream != nil {
p.Upstream = pctx.Upstream.Address()
} else if cachedUps := pctx.CachedUpstreamAddr; cachedUps != "" {
p.Upstream = pctx.CachedUpstreamAddr
p.Cached = true
}

s.queryLog.Add(p)
s.logQuery(dctx, pctx, elapsed, ip)
}

s.updateStats(dctx, elapsed, *dctx.result, ip)
if s.stats != nil {
s.updateStats(dctx, elapsed, *dctx.result, ip)
}

return resultCodeSuccess
}

// logQuery pushes the request details into the query log.
func (s *Server) logQuery(
dctx *dnsContext,
pctx *proxy.DNSContext,
elapsed time.Duration,
ip net.IP,
) {
p := &querylog.AddParams{
Question: pctx.Req,
ReqECS: pctx.ReqECS,
Answer: pctx.Res,
OrigAnswer: dctx.origResp,
Result: dctx.result,
Elapsed: elapsed,
ClientID: dctx.clientID,
ClientIP: ip,
AuthenticatedData: dctx.responseAD,
}

switch pctx.Proto {
case proxy.ProtoHTTPS:
p.ClientProto = querylog.ClientProtoDoH
case proxy.ProtoQUIC:
p.ClientProto = querylog.ClientProtoDoQ
case proxy.ProtoTLS:
p.ClientProto = querylog.ClientProtoDoT
case proxy.ProtoDNSCrypt:
p.ClientProto = querylog.ClientProtoDNSCrypt
default:
// Consider this a plain DNS-over-UDP or DNS-over-TCP request.
}

if pctx.Upstream != nil {
p.Upstream = pctx.Upstream.Address()
} else if cachedUps := pctx.CachedUpstreamAddr; cachedUps != "" {
p.Upstream = pctx.CachedUpstreamAddr
p.Cached = true
}

s.queryLog.Add(p)
}

// updatesStats writes the request into statistics.
func (s *Server) updateStats(
ctx *dnsContext,
elapsed time.Duration,
res filtering.Result,
clientIP net.IP,
) {
if s.stats == nil {
return
}

pctx := ctx.proxyCtx
e := stats.Entry{}
e.Domain = strings.ToLower(pctx.Req.Question[0].Name)
Expand Down
12 changes: 11 additions & 1 deletion internal/querylog/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"github.com/miekg/dns"
)

type logEntryHandler (func(t json.Token, ent *logEntry) error)
type logEntryHandler func(t json.Token, ent *logEntry) error

var logEntryHandlers = map[string]logEntryHandler{
"CID": func(t json.Token, ent *logEntry) error {
Expand Down Expand Up @@ -109,6 +109,16 @@ var logEntryHandlers = map[string]logEntryHandler{

return err
},
"ECS": func(t json.Token, ent *logEntry) error {
v, ok := t.(string)
if !ok {
return nil
}

ent.ReqECS = v

return nil
},
"Cached": func(t json.Token, ent *logEntry) error {
v, ok := t.(bool)
if !ok {
Expand Down
2 changes: 2 additions & 0 deletions internal/querylog/decode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func TestDecodeLogEntry(t *testing.T) {
`"QT":"A",` +
`"QC":"IN",` +
`"CP":"",` +
`"ECS":"1.2.3.0/24",` +
`"Answer":"` + ansStr + `",` +
`"Cached":true,` +
`"AD":true,` +
Expand All @@ -58,6 +59,7 @@ func TestDecodeLogEntry(t *testing.T) {
QClass: "IN",
ClientID: "cli42",
ClientProto: "",
ReqECS: "1.2.3.0/24",
Answer: ans,
Cached: true,
Result: filtering.Result{
Expand Down
4 changes: 4 additions & 0 deletions internal/querylog/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ func (l *queryLog) entryToJSON(entry *logEntry, anonFunc aghnet.IPMutFunc) (json
jsonEntry["client_id"] = entry.ClientID
}

if entry.ReqECS != "" {
jsonEntry["ecs"] = entry.ReqECS
}

if len(entry.Result.Rules) > 0 {
if r := entry.Result.Rules[0]; len(r.Text) > 0 {
jsonEntry["rule"] = r.Text
Expand Down
6 changes: 6 additions & 0 deletions internal/querylog/qlog.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ type logEntry struct {
QType string `json:"QT"`
QClass string `json:"QC"`

ReqECS string `json:"ECS,omitempty"`

ClientID string `json:"CID,omitempty"`
ClientProto ClientProto `json:"CP"`

Expand Down Expand Up @@ -189,6 +191,10 @@ func (l *queryLog) Add(params *AddParams) {
AuthenticatedData: params.AuthenticatedData,
}

if params.ReqECS != nil {
entry.ReqECS = params.ReqECS.String()
}

if params.Answer != nil {
var a []byte
a, err = params.Answer.Pack()
Expand Down
4 changes: 4 additions & 0 deletions internal/querylog/querylog.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ type Config struct {
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

Expand Down
18 changes: 2 additions & 16 deletions internal/querylog/searchcriterion.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,24 +99,10 @@ func (c *searchCriterion) quickMatch(line string, findClient quickMatchClientFun
}

if c.strict {
return ctDomainOrClientCaseStrict(
c.value,
c.asciiVal,
clientID,
name,
host,
ip,
)
return ctDomainOrClientCaseStrict(c.value, c.asciiVal, clientID, name, host, ip)
}

return ctDomainOrClientCaseNonStrict(
c.value,
c.asciiVal,
clientID,
name,
host,
ip,
)
return ctDomainOrClientCaseNonStrict(c.value, c.asciiVal, clientID, name, host, ip)
case ctFilteringStatus:
// Go on, as we currently don't do quick matches against
// filtering statuses.
Expand Down
5 changes: 5 additions & 0 deletions openapi/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

## v0.107.3: API changes

### The new optional field `"ecs"` in `QueryLogItem`

* The new optional field `"ecs"` in `GET /control/querylog` contains the IP
network from an EDNS Client-Subnet option from the request message if any.

### The new possible status code in `/install/configure` response.

* The new status code `422 Unprocessable Entity` in the response for
Expand Down
6 changes: 6 additions & 0 deletions openapi/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1905,6 +1905,12 @@
- 'doq'
- 'dnscrypt'
- ''
'ecs':
'type': 'string'
'example': '192.168.0.0/16'
'description': >
The IP network defined by an EDNS Client-Subnet option in the
request message if any.
'elapsedMs':
'type': 'string'
'example': '54.023928'
Expand Down

0 comments on commit 8fb8052

Please sign in to comment.