Skip to content

Commit

Permalink
auditbeat/module/auditd: add ignore_errors config option
Browse files Browse the repository at this point in the history
Setting ignore_errors to true allows incompletely valid rule sets to be
used in a configuration. This is equivalent to the -i flag of auditctl.
  • Loading branch information
efd6 committed Oct 15, 2023
1 parent 347752f commit 1a096a9
Show file tree
Hide file tree
Showing 4 changed files with 218 additions and 170 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ is collected by it.

*Auditbeat*

- Add `ignore_errors` option to audit module. {issue}15768[15768] {pull}36851[36851]

*Filebeat*

Expand Down
3 changes: 3 additions & 0 deletions auditbeat/module/auditd/_meta/docs.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,9 @@ loaded after the rules declared in `audit_rules` are loaded. Wildcards are
supported and will expand in lexicographical order. The format is the same as
that of the `audit_rules` field.

*`ignore_errors`*:: This setting allows errors during rule loading and parsing
to be ignored, but logged as warnings.

*`backpressure_strategy`*:: Specifies the strategy that {beatname_uc} uses to
prevent backpressure from propagating to the kernel and impacting audited
processes.
Expand Down
35 changes: 28 additions & 7 deletions auditbeat/module/auditd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (

"github.com/joeshaw/multierror"

"github.com/elastic/elastic-agent-libs/logp"
"github.com/elastic/go-libaudit/v2/rule"
"github.com/elastic/go-libaudit/v2/rule/flags"
)
Expand All @@ -46,6 +47,7 @@ type Config struct {
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.
IgnoreErrors bool `config:"ignore_errors"` // Ignore errors when reading and parsing rules, equivalent to auditctl -i.

// Tuning options (advanced, use with care)
ReassemblerMaxInFlight uint32 `config:"reassembler.max_in_flight"`
Expand Down Expand Up @@ -120,11 +122,19 @@ func (c Config) rules() []auditRule {
}

func (c *Config) loadRules() error {
var log *logp.Logger
if c.IgnoreErrors {
log = logp.NewLogger(moduleName)
}

var paths []string
for _, pattern := range c.RuleFiles {
absPattern, err := filepath.Abs(pattern)
if err != nil {
return fmt.Errorf("unable to get the absolute path for %s: %w", pattern, err)
if log == nil {
return fmt.Errorf("unable to get the absolute path for %s: %w", pattern, err)
}
log.Warnf("unable to get the absolute path for %s: %v", pattern, err)
}
files, err := filepath.Glob(absPattern)
if err != nil {
Expand All @@ -136,7 +146,7 @@ func (c *Config) loadRules() error {

knownRules := ruleSet{}

rules, err := readRules(bytes.NewBufferString(c.RulesBlob), "(audit_rules at auditbeat.yml)", knownRules)
rules, err := readRules(bytes.NewBufferString(c.RulesBlob), "(audit_rules at auditbeat.yml)", knownRules, log)
if err != nil {
return err
}
Expand All @@ -145,9 +155,13 @@ 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': %w", filename, err)
if log == nil {
return fmt.Errorf("unable to open rule file '%s': %w", filename, err)
}
log.Warnf("unable to open rule file '%s': %v", filename, err)
continue
}
rules, err = readRules(fHandle, filename, knownRules)
rules, err = readRules(fHandle, filename, knownRules, log)
if err != nil {
return err
}
Expand All @@ -170,7 +184,11 @@ func (c Config) failureMode() (uint32, error) {
}
}

func readRules(reader io.Reader, source string, knownRules ruleSet) (rules []auditRule, err error) {
// readRules reads the audit rules from reader, adding them to knownRules. If
// log is nil, errors will result in an empty rules set being returned. Otherwise
// errors will be logged as warnings and any successfully parsed rules will be
// returned.
func readRules(reader io.Reader, source string, knownRules ruleSet, log *logp.Logger) (rules []auditRule, err error) {
var errs multierror.Errors

s := bufio.NewScanner(reader)
Expand Down Expand Up @@ -207,8 +225,11 @@ func readRules(reader io.Reader, source string, knownRules ruleSet) (rules []aud
rules = append(rules, rule)
}

if len(errs) > 0 {
return nil, fmt.Errorf("failed loading rules: %w", errs.Err())
if len(errs) != 0 {
if log == nil {
return nil, fmt.Errorf("failed loading rules: %w", errs.Err())
}
log.Warnf("errors loading rules: %v", errs.Err())
}
return rules, nil
}
Loading

0 comments on commit 1a096a9

Please sign in to comment.