Skip to content

Commit

Permalink
make full DNS packet logging optional
Browse files Browse the repository at this point in the history
  • Loading branch information
capnspacehook committed Jul 9, 2022
1 parent 1005678 commit 68a9906
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 62 deletions.
60 changes: 32 additions & 28 deletions filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ type FilterManager struct {

started bool

logger *zap.Logger
fullDNSLogging bool
logger *zap.Logger

queueNum4 uint16
queueNum6 uint16
Expand All @@ -63,7 +64,8 @@ type filter struct {

opts *FilterOptions

logger *zap.Logger
fullDNSLogging bool
logger *zap.Logger

dnsReqNF4 enforcer
dnsReqNF6 enforcer
Expand Down Expand Up @@ -117,14 +119,15 @@ type enforcerCreator func(ctx context.Context, logger *zap.Logger, queueNum uint

// CreateFilters creates packet filters. The returned FilterManager can
// be used to start or stop packet filtering.
func CreateFilters(ctx context.Context, logger *zap.Logger, config *Config) (*FilterManager, error) {
func CreateFilters(ctx context.Context, logger *zap.Logger, config *Config, fullDNSLogging bool) (*FilterManager, error) {
f := FilterManager{
ready: make(chan struct{}),
abort: make(chan struct{}),
logger: logger,
queueNum4: config.InboundDNSQueue.IPv4,
queueNum6: config.InboundDNSQueue.IPv6,
filters: make([]*filter, len(config.Filters)),
ready: make(chan struct{}),
abort: make(chan struct{}),
fullDNSLogging: fullDNSLogging,
logger: logger,
queueNum4: config.InboundDNSQueue.IPv4,
queueNum6: config.InboundDNSQueue.IPv6,
filters: make([]*filter, len(config.Filters)),
}

// if mock enforcers and resolver is not set, use real ones
Expand All @@ -148,7 +151,7 @@ func CreateFilters(ctx context.Context, logger *zap.Logger, config *Config) (*Fi

for i := range config.Filters {
isSelfFilter := config.SelfDNSQueue == config.Filters[i].DNSQueue
filter, err := createFilter(ctx, logger, &config.Filters[i], isSelfFilter, newEnforcer, res)
filter, err := createFilter(ctx, logger, &config.Filters[i], isSelfFilter, f.fullDNSLogging, newEnforcer, res)
if err != nil {
// TODO: stop other filters here
return nil, err
Expand Down Expand Up @@ -195,24 +198,25 @@ func (f *FilterManager) Stop() {
}
}

func createFilter(ctx context.Context, logger *zap.Logger, opts *FilterOptions, isSelfFilter bool, newEnforcer enforcerCreator, res resolver) (*filter, error) {
func createFilter(ctx context.Context, logger *zap.Logger, opts *FilterOptions, isSelfFilter, fullDNSLogging bool, newEnforcer enforcerCreator, res resolver) (*filter, error) {
filterLogger := logger
if opts.Name != "" {
filterLogger = filterLogger.With(zap.String("filter.name", opts.Name))
}

f := filter{
dnsReqReady: make(chan struct{}),
dnsReqAbort: make(chan struct{}),
genericReady: make(chan struct{}),
genericAbort: make(chan struct{}),
cachingReady: make(chan struct{}),
cachingAbort: make(chan struct{}),
opts: opts,
logger: filterLogger,
res: res,
connections: NewTimedCache[connectionID](logger, true),
isSelfFilter: isSelfFilter,
dnsReqReady: make(chan struct{}),
dnsReqAbort: make(chan struct{}),
genericReady: make(chan struct{}),
genericAbort: make(chan struct{}),
cachingReady: make(chan struct{}),
cachingAbort: make(chan struct{}),
opts: opts,
fullDNSLogging: fullDNSLogging,
logger: filterLogger,
res: res,
connections: NewTimedCache[connectionID](logger, true),
isSelfFilter: isSelfFilter,
}

if opts.TrafficQueue.eitherSet() {
Expand Down Expand Up @@ -495,7 +499,7 @@ func newDNSRequestCallback(f *filter, ipv6 bool) nfqueue.HookFunc {

// drop DNS replies, they shouldn't be going to this filter
if dns.QR || dns.ANCount > 0 {
logger.Warn("dropping DNS reply sent to DNS request filter", dnsFields(dns)...)
logger.Warn("dropping DNS reply sent to DNS request filter", dnsFields(dns, f.fullDNSLogging)...)
if err := dnsReqNF.SetVerdict(*attr.PacketID, nfqueue.NfDrop); err != nil {
logger.Error("error setting verdict", zap.String("error", err.Error()))
}
Expand All @@ -505,14 +509,14 @@ func newDNSRequestCallback(f *filter, ipv6 bool) nfqueue.HookFunc {
// validate DNS request questions are for allowed
// hostnames, drop them otherwise
if !f.opts.AllowAllHostnames && !f.validateDNSQuestions(logger, dns) {
logger.Warn("dropping DNS request", dnsFields(dns)...)
logger.Warn("dropping DNS request", dnsFields(dns, f.fullDNSLogging)...)
if err := dnsReqNF.SetVerdict(*attr.PacketID, nfqueue.NfDrop); err != nil {
logger.Error("error setting verdict", zap.NamedError("error", err))
}
return 0
}

logger.Info("allowing DNS request", dnsFields(dns)...)
logger.Info("allowing DNS request", dnsFields(dns, f.fullDNSLogging)...)

logger.Debug("adding connection")
f.connections.AddEntry(connID, dnsQueryTimeout)
Expand Down Expand Up @@ -706,7 +710,7 @@ func newDNSResponseCallback(f *FilterManager, ipv6 bool) nfqueue.HookFunc {
}
}
if connFilter == nil {
logger.Warn("dropping DNS response from unknown connection", dnsFields(dns)...)
logger.Warn("dropping DNS response from unknown connection", dnsFields(dns, f.fullDNSLogging)...)

if err := dnsRespNF.SetVerdict(*attr.PacketID, nfqueue.NfDrop); err != nil {
logger.Error("error setting verdict", zap.NamedError("error", err))
Expand All @@ -726,7 +730,7 @@ func newDNSResponseCallback(f *FilterManager, ipv6 bool) nfqueue.HookFunc {
// block requests for disallowed hostnames but it doesn't
// hurt to check
if !connFilter.validateDNSQuestions(logger, dns) {
logger.Info("dropping DNS reply", dnsFields(dns)...)
logger.Info("dropping DNS reply", dnsFields(dns, f.fullDNSLogging)...)
if err := dnsRespNF.SetVerdict(*attr.PacketID, nfqueue.NfDrop); err != nil {
logger.Error("error setting verdict", zap.NamedError("error", err))
}
Expand Down Expand Up @@ -788,7 +792,7 @@ func newDNSResponseCallback(f *FilterManager, ipv6 bool) nfqueue.HookFunc {
}
}

logger.Info("allowing DNS reply", dnsFields(dns)...)
logger.Info("allowing DNS reply", dnsFields(dns, f.fullDNSLogging)...)
if err := dnsRespNF.SetVerdict(*attr.PacketID, nfqueue.NfAccept); err != nil {
logger.Error("error setting verdict", zap.NamedError("error", err))
}
Expand Down
4 changes: 2 additions & 2 deletions filter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ allowedHostnames = [
initMockEnforcers()

ctx, cancel := context.WithCancel(context.Background())
f, err := CreateFilters(ctx, zap.NewNop(), config)
f, err := CreateFilters(ctx, zap.NewNop(), config, false)
is.NoErr(err)
t.Cleanup(func() {
cancel()
Expand Down Expand Up @@ -292,7 +292,7 @@ allowedHostnames = [
// use real nfqueues
config.enforcerCreator = nil
ctx, cancel := context.WithCancel(context.Background())
f, err := CreateFilters(ctx, zap.NewNop(), config)
f, err := CreateFilters(ctx, zap.NewNop(), config, false)
is.NoErr(err)

cancel()
Expand Down
2 changes: 1 addition & 1 deletion filter_test_bin_setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func initFilters(t *testing.T, configStr string, iptablesRules, ip6tablesRules [
iptablesCmd(t, true, command)
}

eddieCmd := exec.Command("./eddie", "-c", configPath, "-d", "-l", "stdout")
eddieCmd := exec.Command("./eddie", "-c", configPath, "-d", "-f", "-l", "stdout")
eddieCmd.Stdout = os.Stdout
eddieCmd.Stderr = os.Stderr
if err := eddieCmd.Start(); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion filter_test_setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func initFilters(t *testing.T, configStr string, iptablesRules, ip6tablesRules [
}

ctx, cancel := context.WithCancel(context.Background())
filters, err := CreateFilters(ctx, logger, config)
filters, err := CreateFilters(ctx, logger, config, true)
if err != nil {
t.Fatalf("error starting filters: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion fuzz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func FuzzFiltering(f *testing.F) {
// test that a config that passes validation won't cause a
// error/panic when starting filters
ctx, cancel := context.WithCancel(context.Background())
f, err := CreateFilters(ctx, logger, config)
f, err := CreateFilters(ctx, logger, config, false)
if err != nil {
failAndDumpConfig(t, cb, "error starting filters: %v", err)
}
Expand Down
51 changes: 28 additions & 23 deletions log.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,31 @@ import (

// dnsFields returns a list of fields for a zap logger that describes
// a DNS packet.
func dnsFields(dns *layers.DNS) []zap.Field {
fields := []zap.Field{
zap.Uint8("opcode", uint8(dns.OpCode)),
}

var flags []string
if dns.AA {
flags = append(flags, "aa")
}
if dns.TC {
flags = append(flags, "tc")
}
if dns.RD {
flags = append(flags, "rd")
}
if dns.RA {
flags = append(flags, "ra")
}
fields = append(fields, zap.Strings("flags", flags))
func dnsFields(dns *layers.DNS, fullDNSLogging bool) []zap.Field {
var (
fields []zap.Field
flags []string
)

if fullDNSLogging {
fields = append(fields, zap.Uint8("opcode", uint8(dns.OpCode)))
if dns.AA {
flags = append(flags, "aa")
}
if dns.TC {
flags = append(flags, "tc")
}
if dns.RD {
flags = append(flags, "rd")
}
if dns.RA {
flags = append(flags, "ra")
}
fields = append(fields, zap.Strings("flags", flags))

if dns.QR {
fields = append(fields, zap.Uint8("resp-code", uint8(dns.ResponseCode)))
if dns.QR {
fields = append(fields, zap.Uint8("resp-code", uint8(dns.ResponseCode)))
}
}

if dns.QDCount > 0 {
Expand All @@ -51,8 +54,10 @@ func dnsFields(dns *layers.DNS) []zap.Field {
}

stringify(dns.Answers, "answers")
stringify(dns.Authorities, "authorities")
stringify(dns.Additionals, "additionals")
if fullDNSLogging {
stringify(dns.Authorities, "authorities")
stringify(dns.Additionals, "additionals")
}

return fields
}
Expand Down
14 changes: 8 additions & 6 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,18 @@ import (
)

var (
configPath string
debugLogs bool
logPath string
testConfig bool
printVersion bool
configPath string
debugLogs bool
logFullDNSPackets bool
logPath string
testConfig bool
printVersion bool
)

func init() {
flag.StringVar(&configPath, "c", "egress-eddie.toml", "path of the config file")
flag.BoolVar(&debugLogs, "d", false, "enable debug logging")
flag.BoolVar(&logFullDNSPackets, "f", false, "enable full DNS packet logging")
flag.StringVar(&logPath, "l", "egress-eddie.log", "path to log to")
flag.BoolVar(&testConfig, "t", false, "validate the config and exit")
flag.BoolVar(&printVersion, "version", false, "print version and build information and exit")
Expand Down Expand Up @@ -106,7 +108,7 @@ func main() {

ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)

filters, err := CreateFilters(ctx, logger, config)
filters, err := CreateFilters(ctx, logger, config, logFullDNSPackets)
if err != nil {
logger.Fatal("error starting filters", zap.NamedError("error", err))
}
Expand Down

0 comments on commit 68a9906

Please sign in to comment.