From b6bb4bc4cfd97b7561cb0e121db6eed15a0b2076 Mon Sep 17 00:00:00 2001 From: Marc Guasch Date: Tue, 19 Jul 2022 09:07:39 +0200 Subject: [PATCH] [auditbeat] Add the immutable option to auditd module (#32381) * Make the config immutable after all rules are set * Add option to the auditd module * Add pr number * Add unit tests * Fix linting issues * Improve doc explanation --- CHANGELOG.next.asciidoc | 2 + auditbeat/docs/modules/auditd.asciidoc | 9 ++ auditbeat/module/auditd/_meta/docs.asciidoc | 9 ++ auditbeat/module/auditd/audit_linux.go | 137 ++++++++++--------- auditbeat/module/auditd/audit_linux_test.go | 46 ++++++- auditbeat/module/auditd/config_linux.go | 12 +- auditbeat/module/auditd/config_linux_test.go | 40 ++++++ auditbeat/module/auditd/golden_files_test.go | 17 ++- auditbeat/module/auditd/mock_linux_test.go | 1 + 9 files changed, 191 insertions(+), 82 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 32b0c9e73f5e..e628ee3c6f8c 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -88,6 +88,8 @@ https://github.com/elastic/beats/compare/v8.2.0\...main[Check the HEAD diff] *Auditbeat* +- Add `immutable` option to the auditd module. {issue}8352[8352] {pull}32381[32381] + *Filebeat* diff --git a/auditbeat/docs/modules/auditd.asciidoc b/auditbeat/docs/modules/auditd.asciidoc index e913160d9cbb..8fed93ede613 100644 --- a/auditbeat/docs/modules/auditd.asciidoc +++ b/auditbeat/docs/modules/auditd.asciidoc @@ -135,6 +135,7 @@ following example shows all configuration options with their default values. include_raw_message: false include_warnings: false backpressure_strategy: auto + immutable: false ---- This module also supports the @@ -159,6 +160,14 @@ than 3.16 {beatname_uc} will automatically revert to `unicast`. By default {beatname_uc} will use `multicast` if the kernel version is 3.16 or newer and no rules have been defined. Otherwise `unicast` will be used. +*`immutable`*:: This boolean setting sets the audit config as immutable (`-e 2`). +This option can only be used with the `socket_type: unicast` since {beatname_uc} +needs to manage the rules to be able to set it. ++ +It is important to note that with this setting set, {beatname_uc} should never +be stopped, as it won't be able to resume processing `auditd` events until the +system is restarted. + *`resolve_ids`*:: This boolean setting enables the resolution of UIDs and GIDs to their associated names. The default value is true. diff --git a/auditbeat/module/auditd/_meta/docs.asciidoc b/auditbeat/module/auditd/_meta/docs.asciidoc index 4585b7179ff9..c751d20042bd 100644 --- a/auditbeat/module/auditd/_meta/docs.asciidoc +++ b/auditbeat/module/auditd/_meta/docs.asciidoc @@ -128,6 +128,7 @@ following example shows all configuration options with their default values. include_raw_message: false include_warnings: false backpressure_strategy: auto + immutable: false ---- This module also supports the @@ -152,6 +153,14 @@ than 3.16 {beatname_uc} will automatically revert to `unicast`. By default {beatname_uc} will use `multicast` if the kernel version is 3.16 or newer and no rules have been defined. Otherwise `unicast` will be used. +*`immutable`*:: This boolean setting sets the audit config as immutable (`-e 2`). +This option can only be used with the `socket_type: unicast` since {beatname_uc} +needs to manage the rules to be able to set it. ++ +It is important to note that with this setting set, {beatname_uc} should never +be stopped, as it won't be able to resume processing `auditd` events until the +system is restarted. + *`resolve_ids`*:: This boolean setting enables the resolution of UIDs and GIDs to their associated names. The default value is true. diff --git a/auditbeat/module/auditd/audit_linux.go b/auditbeat/module/auditd/audit_linux.go index ce346f563106..d695bee2e214 100644 --- a/auditbeat/module/auditd/audit_linux.go +++ b/auditbeat/module/auditd/audit_linux.go @@ -139,7 +139,7 @@ func newAuditClient(c *Config, log *logp.Logger) (*libaudit.AuditClient, error) return libaudit.NewAuditClient(nil) } -func closeAuditClient(client *libaudit.AuditClient) error { +func closeAuditClient(client *libaudit.AuditClient, log *logp.Logger) { discard := func(bytes []byte) ([]syscall.NetlinkMessage, error) { return nil, nil } @@ -149,22 +149,24 @@ func closeAuditClient(client *libaudit.AuditClient) error { go func() { for { _, err := client.Netlink.Receive(true, discard) - switch err { - case nil, syscall.EINTR: - case syscall.EAGAIN: + switch { + case err == nil, errors.Is(err, syscall.EINTR): + case errors.Is(err, syscall.EAGAIN): time.Sleep(50 * time.Millisecond) default: return } } }() - return client.Close() + if err := client.Close(); err != nil { + log.Errorw("Error closing audit monitoring client", "error", err) + } } // Run initializes the audit client and receives audit messages from the // kernel until the reporter's done channel is closed. func (ms *MetricSet) Run(reporter mb.PushReporterV2) { - defer closeAuditClient(ms.client) + defer closeAuditClient(ms.client, ms.log) if err := ms.addRules(reporter); err != nil { reporter.Error(err) @@ -179,6 +181,14 @@ func (ms *MetricSet) Run(reporter mb.PushReporterV2) { return } + if ms.config.Immutable { + if err := ms.client.SetImmutable(libaudit.WaitForReply); err != nil { + reporter.Error(err) + ms.log.Errorw("Failure setting audit config as immutable", "error", err) + return + } + } + if ms.kernelLost.enabled { client, err := libaudit.NewAuditClient(nil) if err != nil { @@ -188,7 +198,7 @@ func (ms *MetricSet) Run(reporter mb.PushReporterV2) { go func() { defer func() { // Close the most recently allocated "client" instance. if client != nil { - closeAuditClient(client) + closeAuditClient(client, ms.log) } }() timer := time.NewTicker(lostEventsUpdateInterval) @@ -202,9 +212,7 @@ func (ms *MetricSet) Run(reporter mb.PushReporterV2) { ms.updateKernelLostMetric(status.Lost) } else { ms.log.Error("get status request failed:", err) - if err = closeAuditClient(client); err != nil { - ms.log.Errorw("Error closing audit monitoring client", "error", err) - } + closeAuditClient(client, ms.log) client, err = libaudit.NewAuditClient(nil) if err != nil { ms.log.Errorw("Failure creating audit monitoring client", "error", err) @@ -257,7 +265,7 @@ func (ms *MetricSet) addRules(reporter mb.PushReporterV2) error { if err != nil { return fmt.Errorf("failed to create audit client for adding rules: %w", err) } - defer closeAuditClient(client) + defer closeAuditClient(client, ms.log) // Don't attempt to change configuration if audit rules are locked (enabled == 2). // Will result in EPERM. @@ -383,7 +391,8 @@ func (ms *MetricSet) initClient() error { } if err := ms.setPID(setPIDMaxRetries); err != nil { - if errno, ok := err.(syscall.Errno); ok && errno == syscall.EEXIST && status.PID != 0 { + var errno syscall.Errno + if ok := errors.As(err, &errno); ok && errno == syscall.EEXIST && status.PID != 0 { return fmt.Errorf("failed to set audit PID. An audit process is already running (PID %d)", status.PID) } return fmt.Errorf("failed to set audit PID (current audit PID %d): %w", status.PID, err) @@ -397,7 +406,7 @@ func (ms *MetricSet) setPID(retries int) (err error) { } // At this point the netlink channel is congested (ENOBUFS). // Drain and close the client, then retry with a new client. - closeAuditClient(ms.client) + closeAuditClient(ms.client, ms.log) if ms.client, err = newAuditClient(&ms.config, ms.log); err != nil { return fmt.Errorf("failed to recover from ENOBUFS: %w", err) } @@ -545,7 +554,7 @@ func buildMetricbeatEvent(msgs []*auparse.AuditMessage, config Config) mb.Event }, } if auditEvent.Session != uidUnset { - out.ModuleFields.Put("session", auditEvent.Session) + _, _ = out.ModuleFields.Put("session", auditEvent.Session) } // Add root level fields. @@ -556,14 +565,14 @@ func buildMetricbeatEvent(msgs []*auparse.AuditMessage, config Config) mb.Event addAddress(auditEvent.Dest, "destination", out.RootFields) addNetwork(auditEvent.Net, out.RootFields) if len(auditEvent.Tags) > 0 { - out.RootFields.Put("tags", auditEvent.Tags) + _, _ = out.RootFields.Put("tags", auditEvent.Tags) } if config.Warnings && len(auditEvent.Warnings) > 0 { warnings := make([]string, 0, len(auditEvent.Warnings)) for _, err := range auditEvent.Warnings { warnings = append(warnings, err.Error()) } - out.RootFields.Put("error.message", warnings) + _, _ = out.RootFields.Put("error.message", warnings) addEventOriginal(msgs, out.RootFields) } if config.RawMessage { @@ -573,25 +582,25 @@ func buildMetricbeatEvent(msgs []*auparse.AuditMessage, config Config) mb.Event // Add module fields. m := out.ModuleFields if auditEvent.Summary.Actor.Primary != "" { - m.Put("summary.actor.primary", auditEvent.Summary.Actor.Primary) + _, _ = m.Put("summary.actor.primary", auditEvent.Summary.Actor.Primary) } if auditEvent.Summary.Actor.Secondary != "" { - m.Put("summary.actor.secondary", auditEvent.Summary.Actor.Secondary) + _, _ = m.Put("summary.actor.secondary", auditEvent.Summary.Actor.Secondary) } if auditEvent.Summary.Object.Primary != "" { - m.Put("summary.object.primary", auditEvent.Summary.Object.Primary) + _, _ = m.Put("summary.object.primary", auditEvent.Summary.Object.Primary) } if auditEvent.Summary.Object.Secondary != "" { - m.Put("summary.object.secondary", auditEvent.Summary.Object.Secondary) + _, _ = m.Put("summary.object.secondary", auditEvent.Summary.Object.Secondary) } if auditEvent.Summary.Object.Type != "" { - m.Put("summary.object.type", auditEvent.Summary.Object.Type) + _, _ = m.Put("summary.object.type", auditEvent.Summary.Object.Type) } if auditEvent.Summary.How != "" { - m.Put("summary.how", auditEvent.Summary.How) + _, _ = m.Put("summary.how", auditEvent.Summary.How) } if len(auditEvent.Paths) > 0 { - m.Put("paths", auditEvent.Paths) + _, _ = m.Put("paths", auditEvent.Paths) } normalizeEventFields(auditEvent, out.RootFields) @@ -613,17 +622,17 @@ func buildMetricbeatEvent(msgs []*auparse.AuditMessage, config Config) mb.Event nameField := key + ".name" idField := key + ".id" if ent.ID != "" { - root.Put(idField, ent.ID) + _, _ = root.Put(idField, ent.ID) } else { - root.Delete(idField) + _ = root.Delete(idField) } if ent.Name != "" { - root.Put(nameField, ent.Name) + _, _ = root.Put(nameField, ent.Name) if set != nil { set.Add(ent.Name) } } else { - root.Delete(nameField) + _ = root.Delete(nameField) } } @@ -635,7 +644,7 @@ func buildMetricbeatEvent(msgs []*auparse.AuditMessage, config Config) mb.Event if userSet != nil { if userSet.Count() != 0 { - out.RootFields.Put("related.user", userSet.ToSlice()) + _, _ = out.RootFields.Put("related.user", userSet.ToSlice()) } } getStringField := func(key string, m mapstr.M) (str string) { @@ -649,7 +658,7 @@ func buildMetricbeatEvent(msgs []*auparse.AuditMessage, config Config) mb.Event removeRedundantEntity := func(target, original string, m mapstr.M) bool { for _, suffix := range []string{".id", ".name"} { if value := getStringField(original+suffix, m); value != "" && getStringField(target+suffix, m) == value { - m.Delete(target) + _ = m.Delete(target) return true } } @@ -660,21 +669,21 @@ func buildMetricbeatEvent(msgs []*auparse.AuditMessage, config Config) mb.Event } func normalizeEventFields(event *aucoalesce.Event, m mapstr.M) { - m.Put("event.kind", "event") + _, _ = m.Put("event.kind", "event") if len(event.ECS.Event.Category) > 0 { - m.Put("event.category", event.ECS.Event.Category) + _, _ = m.Put("event.category", event.ECS.Event.Category) } if len(event.ECS.Event.Type) > 0 { - m.Put("event.type", event.ECS.Event.Type) + _, _ = m.Put("event.type", event.ECS.Event.Type) } if event.ECS.Event.Outcome != "" { - m.Put("event.outcome", event.ECS.Event.Outcome) + _, _ = m.Put("event.outcome", event.ECS.Event.Outcome) } } func addUser(u aucoalesce.User, m mapstr.M) { user := mapstr.M{} - m.Put("user", user) + _, _ = m.Put("user", user) for id, value := range u.IDs { if value == uidUnset { @@ -684,23 +693,23 @@ func addUser(u aucoalesce.User, m mapstr.M) { case "uid": user["id"] = value case "gid": - user.Put("group.id", value) + _, _ = user.Put("group.id", value) case "euid": - user.Put("effective.id", value) + _, _ = user.Put("effective.id", value) case "egid": - user.Put("effective.group.id", value) + _, _ = user.Put("effective.group.id", value) case "suid": - user.Put("saved.id", value) + _, _ = user.Put("saved.id", value) case "sgid": - user.Put("saved.group.id", value) + _, _ = user.Put("saved.group.id", value) case "fsuid": - user.Put("filesystem.id", value) + _, _ = user.Put("filesystem.id", value) case "fsgid": - user.Put("filesystem.group.id", value) + _, _ = user.Put("filesystem.group.id", value) case "auid": - user.Put("audit.id", value) + _, _ = user.Put("audit.id", value) default: - user.Put(id+".id", value) + _, _ = user.Put(id+".id", value) } if len(u.SELinux) > 0 { @@ -713,23 +722,23 @@ func addUser(u aucoalesce.User, m mapstr.M) { case "uid": user["name"] = value case "gid": - user.Put("group.name", value) + _, _ = user.Put("group.name", value) case "euid": - user.Put("effective.name", value) + _, _ = user.Put("effective.name", value) case "egid": - user.Put("effective.group.name", value) + _, _ = user.Put("effective.group.name", value) case "suid": - user.Put("saved.name", value) + _, _ = user.Put("saved.name", value) case "sgid": - user.Put("saved.group.name", value) + _, _ = user.Put("saved.group.name", value) case "fsuid": - user.Put("filesystem.name", value) + _, _ = user.Put("filesystem.name", value) case "fsgid": - user.Put("filesystem.group.name", value) + _, _ = user.Put("filesystem.group.name", value) case "auid": - user.Put("audit.name", value) + _, _ = user.Put("audit.name", value) default: - user.Put(id+".name", value) + _, _ = user.Put(id+".name", value) } } } @@ -740,7 +749,7 @@ func addProcess(p aucoalesce.Process, m mapstr.M) { } process := mapstr.M{} - m.Put("process", process) + _, _ = m.Put("process", process) if p.PID != "" { if pid, err := strconv.Atoi(p.PID); err == nil { process["pid"] = pid @@ -776,7 +785,7 @@ func addFile(f *aucoalesce.File, m mapstr.M) { } file := mapstr.M{} - m.Put("file", file) + _, _ = m.Put("file", file) if f.Path != "" { file["path"] = f.Path } @@ -812,7 +821,7 @@ func addAddress(addr *aucoalesce.Address, key string, m mapstr.M) { } address := mapstr.M{} - m.Put(key, address) + _, _ = m.Put(key, address) if addr.Hostname != "" { address["domain"] = addr.Hostname } @@ -835,7 +844,7 @@ func addNetwork(net *aucoalesce.Network, m mapstr.M) { network := mapstr.M{ "direction": net.Direction, } - m.Put("network", network) + _, _ = m.Put("network", network) } func addEventOriginal(msgs []*auparse.AuditMessage, m mapstr.M) { @@ -851,18 +860,18 @@ func addEventOriginal(msgs []*auparse.AuditMessage, m mapstr.M) { for _, msg := range msgs { rawMsgs = append(rawMsgs, "type="+msg.RecordType.String()+" msg="+msg.RawData) } - m.Put(key, rawMsgs) + _, _ = m.Put(key, rawMsgs) } func createAuditdData(data map[string]string) mapstr.M { out := make(mapstr.M, len(data)) for key, v := range data { if strings.HasPrefix(key, "socket_") { - out.Put("socket."+key[7:], v) + _, _ = out.Put("socket."+key[7:], v) continue } - out.Put(key, v) + _, _ = out.Put(key, v) } return out } @@ -1038,6 +1047,11 @@ func determineSocketType(c *Config, log *logp.Logger) (string, error) { func getBackpressureStrategy(value string, logger *logp.Logger) backpressureStrategy { switch value { + default: + logger.Warn("Unknown value for the 'backpressure_strategy' option. Using default.") + fallthrough + case "", "default": + return bsAuto case "kernel": return bsKernel case "userspace", "user-space": @@ -1048,11 +1062,6 @@ func getBackpressureStrategy(value string, logger *logp.Logger) backpressureStra return bsKernel | bsUserSpace case "none": return 0 - default: - logger.Warn("Unknown value for the 'backpressure_strategy' option. Using default.") - fallthrough - case "", "default": - return bsAuto } } diff --git a/auditbeat/module/auditd/audit_linux_test.go b/auditbeat/module/auditd/audit_linux_test.go index 3c66bb0aa59e..dcbb0f18ffeb 100644 --- a/auditbeat/module/auditd/audit_linux_test.go +++ b/auditbeat/module/auditd/audit_linux_test.go @@ -72,8 +72,42 @@ var ( } ) +func TestImmutable(t *testing.T) { + _ = logp.TestingSetup() + + // Create a mock netlink client that provides the expected responses. + mock := NewMock(). + // Get Status response for initClient + returnACK().returnStatus(). + // Send expected ACKs for initialization + // With one extra for SetImmutable + returnACK().returnACK().returnACK().returnACK().returnACK().returnACK(). + // Send one auditd message. + returnMessage(userLoginFailMsg) + + // Replace the default AuditClient with a mock. + config := getConfig() + config["immutable"] = true + + ms := mbtest.NewPushMetricSetV2(t, config) + auditMetricSet := ms.(*MetricSet) + auditMetricSet.client.Close() + auditMetricSet.client = &libaudit.AuditClient{Netlink: mock} + + events := mbtest.RunPushMetricSetV2(10*time.Second, 1, ms) + if len(events) != 1 { + t.Fatalf("expected 1 events, but received %d", len(events)) + } + assertNoErrors(t, events) + + assertFieldsAreDocumented(t, events) + + beatEvent := mbtest.StandardizeEvent(ms, events[0], core.AddDatasetToEvent) + mbtest.WriteEventToDataJSON(t, beatEvent, "") +} + func TestData(t *testing.T) { - logp.TestingSetup() + _ = logp.TestingSetup() // Create a mock netlink client that provides the expected responses. mock := NewMock(). @@ -105,7 +139,7 @@ func TestData(t *testing.T) { } func TestLoginType(t *testing.T) { - logp.TestingSetup() + _ = logp.TestingSetup() // Create a mock netlink client that provides the expected responses. mock := NewMock(). @@ -223,7 +257,7 @@ func TestUnicastClient(t *testing.T) { t.Skip("-audit was not specified") } - logp.TestingSetup() + _ = logp.TestingSetup() FailIfAuditdIsRunning(t) c := map[string]interface{}{ @@ -236,7 +270,7 @@ func TestUnicastClient(t *testing.T) { // Any commands executed by this process will generate events due to the // PPID filter we applied to the rule. - time.AfterFunc(time.Second, func() { exec.Command("cat", "/proc/self/status").Output() }) + time.AfterFunc(time.Second, func() { _, _ = exec.Command("cat", "/proc/self/status").Output() }) ms := mbtest.NewPushMetricSetV2(t, c) events := mbtest.RunPushMetricSetV2(5*time.Second, 0, ms) @@ -253,7 +287,7 @@ func TestMulticastClient(t *testing.T) { t.Skip("no multicast support") } - logp.TestingSetup() + _ = logp.TestingSetup() FailIfAuditdIsRunning(t) c := map[string]interface{}{ @@ -266,7 +300,7 @@ func TestMulticastClient(t *testing.T) { // Any commands executed by this process will generate events due to the // PPID filter we applied to the rule. - time.AfterFunc(time.Second, func() { exec.Command("cat", "/proc/self/status").Output() }) + time.AfterFunc(time.Second, func() { _, _ = exec.Command("cat", "/proc/self/status").Output() }) ms := mbtest.NewPushMetricSetV2(t, c) events := mbtest.RunPushMetricSetV2(5*time.Second, 0, ms) diff --git a/auditbeat/module/auditd/config_linux.go b/auditbeat/module/auditd/config_linux.go index ffcf9a463f65..4a03584c3b7b 100644 --- a/auditbeat/module/auditd/config_linux.go +++ b/auditbeat/module/auditd/config_linux.go @@ -45,6 +45,7 @@ type Config struct { RulesBlob string `config:"audit_rules"` // Audit rules. One rule per line. RuleFiles []string `config:"audit_rule_files"` // List of rule files. SocketType string `config:"socket_type"` // Socket type to use with the kernel (unicast or multicast). + Immutable bool `config:"immutable"` // Sets kernel audit config immutable. // Tuning options (advanced, use with care) ReassemblerMaxInFlight uint32 `config:"reassembler.max_in_flight"` @@ -78,6 +79,7 @@ var defaultConfig = Config{ BacklogLimit: 8192, RateLimit: 0, RawMessage: false, + Immutable: false, Warnings: false, ReassemblerMaxInFlight: 50, ReassemblerTimeout: 2 * time.Second, @@ -99,7 +101,11 @@ func (c *Config) Validate() error { c.SocketType = strings.ToLower(c.SocketType) switch c.SocketType { - case "", "unicast", "multicast": + case "multicast": + if c.Immutable { + errs = append(errs, fmt.Errorf("immutable can't be used with socket_type: multicast")) + } + case "", "unicast": default: errs = append(errs, fmt.Errorf("invalid socket_type "+ "'%v' (use unicast, multicast, or don't set a value)", c.SocketType)) @@ -118,7 +124,7 @@ func (c *Config) loadRules() error { for _, pattern := range c.RuleFiles { absPattern, err := filepath.Abs(pattern) if err != nil { - return fmt.Errorf("unable to get the absolute path for %s: %v", pattern, err) + return fmt.Errorf("unable to get the absolute path for %s: %w", pattern, err) } files, err := filepath.Glob(absPattern) if err != nil { @@ -139,7 +145,7 @@ func (c *Config) loadRules() error { for _, filename := range paths { fHandle, err := os.Open(filename) if err != nil { - return fmt.Errorf("unable to open rule file '%s': %v", filename, err) + return fmt.Errorf("unable to open rule file '%s': %w", filename, err) } rules, err = readRules(fHandle, filename, knownRules) if err != nil { diff --git a/auditbeat/module/auditd/config_linux_test.go b/auditbeat/module/auditd/config_linux_test.go index 711c0c761bab..d48eea8c6c8d 100644 --- a/auditbeat/module/auditd/config_linux_test.go +++ b/auditbeat/module/auditd/config_linux_test.go @@ -93,6 +93,46 @@ func TestConfigValidateConnectionType(t *testing.T) { t.Log(err) } +func TestConfigValidateImmutable(t *testing.T) { + tcs := []struct { + name string + socketType string + mustFail bool + }{ + { + name: "Must pass for default", + socketType: "", + mustFail: false, + }, + { + name: "Must pass for unicast", + socketType: "unicast", + mustFail: false, + }, + { + name: "Must fail for multicast", + socketType: "multicast", + mustFail: true, + }, + } + + for _, tc := range tcs { + tc := tc + t.Run(tc.name, func(t *testing.T) { + config := defaultConfig + config.SocketType = tc.socketType + config.Immutable = true + err := config.Validate() + if tc.mustFail { + assert.Error(t, err) + t.Log(err) + } else { + assert.NoError(t, err) + } + }) + } +} + func TestConfigRuleOrdering(t *testing.T) { const fileMode = 0o644 config := defaultConfig diff --git a/auditbeat/module/auditd/golden_files_test.go b/auditbeat/module/auditd/golden_files_test.go index 17625c0b5587..252c2b0ec8f7 100644 --- a/auditbeat/module/auditd/golden_files_test.go +++ b/auditbeat/module/auditd/golden_files_test.go @@ -44,13 +44,12 @@ import ( ) const ( - testDir = "testdata" - testExt = ".log" - testPattern = "*" + testExt - goldenSuffix = "-expected.json" - goldenPattern = testPattern + goldenSuffix - fileTimeout = 3 * time.Minute - terminator = "type=TEST msg=audit(0.0:585): msg=\"terminate\"" + testDir = "testdata" + testExt = ".log" + testPattern = "*" + testExt + goldenSuffix = "-expected.json" + fileTimeout = 3 * time.Minute + terminator = "type=TEST msg=audit(0.0:585): msg=\"terminate\"" ) var ( @@ -96,7 +95,7 @@ func readGoldenFile(t testing.TB, path string) (events []mapstr.M) { if err = json.Unmarshal(data, &events); err != nil { t.Fatalf("error decoding JSON from golden file '%s': %v", path, err) } - return + return events } func normalize(t testing.TB, events []mb.Event) (norm []mapstr.M) { @@ -106,7 +105,7 @@ func normalize(t testing.TB, events []mb.Event) (norm []mapstr.M) { if err != nil { t.Fatal(err) } - json.Unmarshal(data, &output) + _ = json.Unmarshal(data, &output) norm = append(norm, output) } return norm diff --git a/auditbeat/module/auditd/mock_linux_test.go b/auditbeat/module/auditd/mock_linux_test.go index 13239eb94558..d7639ae0517f 100644 --- a/auditbeat/module/auditd/mock_linux_test.go +++ b/auditbeat/module/auditd/mock_linux_test.go @@ -47,6 +47,7 @@ func (n *MockNetlinkSendReceiver) returnACK() *MockNetlinkSendReceiver { return n } +//nolint:unused // it still might be useful for tests in the future func (n *MockNetlinkSendReceiver) returnDone() *MockNetlinkSendReceiver { n.messages = append(n.messages, syscall.NetlinkMessage{ Header: syscall.NlMsghdr{