Skip to content

Commit

Permalink
feat: add queryLog.ignore.sudn option to ignore SUDN responses
Browse files Browse the repository at this point in the history
  • Loading branch information
ThinkChaos committed Apr 4, 2024
1 parent c56f0f9 commit ed947e8
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 7 deletions.
11 changes: 11 additions & 0 deletions config/query_log.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"net/url"
"strings"

"github.com/0xERR0R/blocky/log"
"github.com/sirupsen/logrus"
)

Expand All @@ -16,6 +17,11 @@ type QueryLog struct {
CreationCooldown Duration `yaml:"creationCooldown" default:"2s"`
Fields []QueryLogField `yaml:"fields"`
FlushInterval Duration `yaml:"flushInterval" default:"30s"`
Ignore QueryLogIgnore `yaml:"ignore"`
}

type QueryLogIgnore struct {
SUDN bool `yaml:"sudn" default:"false"`
}

// SetDefaults implements `defaults.Setter`.
Expand Down Expand Up @@ -43,6 +49,11 @@ func (c *QueryLog) LogConfig(logger *logrus.Entry) {
logger.Debugf("creationCooldown: %s", c.CreationCooldown)
logger.Infof("flushInterval: %s", c.FlushInterval)
logger.Infof("fields: %s", c.Fields)

logger.Infof("ignore:")
log.WithIndent(logger, " ", func(e *logrus.Entry) {
logger.Infof("sudn: %t", c.Ignore.SUDN)
})
}

func (c *QueryLog) censoredTarget() string {
Expand Down
1 change: 1 addition & 0 deletions config/query_log_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ var _ = Describe("QueryLogConfig", func() {

Expect(hook.Calls).ShouldNot(BeEmpty())
Expect(hook.Messages).Should(ContainElement(ContainSubstring("logRetentionDays:")))
Expect(hook.Messages).Should(ContainElement(ContainSubstring("sudn:")))
})

DescribeTable("secret censoring", func(target string) {
Expand Down
20 changes: 16 additions & 4 deletions resolver/query_logging_resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,20 +115,32 @@ func (r *QueryLoggingResolver) Resolve(ctx context.Context, request *model.Reque
ctx, logger := r.log(ctx)

start := time.Now()

resp, err := r.next.Resolve(ctx, request)

duration := time.Since(start).Milliseconds()

if err == nil {
if err != nil {
return nil, err
}

if !r.ignore(resp) {
select {
case r.logChan <- r.createLogEntry(request, resp, start, duration):
default:
logger.Error("query log writer is too slow, log entry will be dropped")
}
}

return resp, err
return resp, nil
}

func (r *QueryLoggingResolver) ignore(response *model.Response) bool {
cfg := r.cfg.Ignore

if cfg.SUDN && response.RType == model.ResponseTypeSPECIAL {
return true
}

return false
}

func (r *QueryLoggingResolver) createLogEntry(request *model.Request, response *model.Response,
Expand Down
51 changes: 48 additions & 3 deletions resolver/query_logging_resolver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
. "github.com/0xERR0R/blocky/helpertest"
"github.com/0xERR0R/blocky/log"
"github.com/0xERR0R/blocky/querylog"
"github.com/stretchr/testify/mock"

"github.com/0xERR0R/blocky/config"
. "github.com/0xERR0R/blocky/model"
Expand All @@ -21,7 +22,6 @@ import (
"github.com/miekg/dns"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/stretchr/testify/mock"
)

type SlowMockWriter struct {
Expand All @@ -43,6 +43,7 @@ var _ = Describe("QueryLoggingResolver", func() {
sutConfig config.QueryLog
m *mockResolver
tmpDir *TmpFolder
mockRType ResponseType
mockAnswer *dns.Msg

ctx context.Context
Expand All @@ -59,6 +60,12 @@ var _ = Describe("QueryLoggingResolver", func() {
ctx, cancelFn = context.WithCancel(context.Background())
DeferCleanup(cancelFn)

var err error

sutConfig, err = config.WithDefaults[config.QueryLog]()
Expect(err).Should(Succeed())

mockRType = ResponseTypeRESOLVED
mockAnswer = new(dns.Msg)
tmpDir = NewTmpFolder("queryLoggingResolver")
})
Expand All @@ -69,8 +76,15 @@ var _ = Describe("QueryLoggingResolver", func() {
}

sut = NewQueryLoggingResolver(ctx, sutConfig)
m = &mockResolver{}
m.On("Resolve", mock.Anything).Return(&Response{Res: mockAnswer, Reason: "reason"}, nil)

m = &mockResolver{
ResolveFn: func(context.Context, *Request) (*Response, error) {
return &Response{RType: mockRType, Res: mockAnswer, Reason: "reason"}, nil
},
}

m.On("Resolve", mock.Anything).Return(autoAnswer, nil)

sut.Next(m)
})

Expand Down Expand Up @@ -109,6 +123,37 @@ var _ = Describe("QueryLoggingResolver", func() {
m.AssertExpectations(GinkgoT())
})
})

Describe("ignore", func() {
JustBeforeEach(func() {
// Stop background goroutines
cancelFn()

ctx, cancelFn = context.WithCancel(context.Background())
DeferCleanup(cancelFn)

sut.logChan = make(chan *querylog.LogEntry, 16)
})

It("should not log SUDN responses", func() {
sut.cfg.Ignore.SUDN = true

req := newRequestWithClient("example.com.", A, "192.168.178.25", "client1")

mockRType = ResponseTypeSPECIAL
_, err := sut.Resolve(ctx, req)
Expect(err).Should(Succeed())

Expect(sut.logChan).Should(BeEmpty())

mockRType = ResponseTypeBLOCKED
_, err = sut.Resolve(ctx, req)
Expect(err).Should(Succeed())

Expect(sut.logChan).ShouldNot(BeEmpty())
})
})

When("Configuration with logging per client", func() {
BeforeEach(func() {
sutConfig = config.QueryLog{
Expand Down

0 comments on commit ed947e8

Please sign in to comment.