feat(aa-log): improve logs cleaning and varible resolution.

This commit is contained in:
Alexandre Pujol 2024-09-26 22:25:24 +01:00
parent 83bc7d3ade
commit 00d6a664eb
No known key found for this signature in database
GPG key ID: C5469996F0DF68EC
5 changed files with 44 additions and 35 deletions

View file

@ -30,7 +30,7 @@ func TestGetJournalctlLogs(t *testing.T) {
"apparmor": "ALLOWED",
"label": "gsd-xsettings",
"operation": "dbus_method_call",
"name": ":*",
"name": "@{busname}",
"mask": "receive",
"bus": "session",
"path": "/org/gtk/Settings",
@ -50,8 +50,8 @@ func TestGetJournalctlLogs(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
reader, _ := GetJournalctlLogs(tt.path, tt.useFile)
if got := NewApparmorLogs(reader, tt.name); !reflect.DeepEqual(got, tt.want) {
t.Errorf("NewApparmorLogs() = %v, want %v", got, tt.want)
if got := New(reader, tt.name); !reflect.DeepEqual(got, tt.want) {
t.Errorf("New() = %v, want %v", got, tt.want)
}
})
}

View file

@ -28,11 +28,14 @@ const (
boldYellow = "\033[1;33m"
)
const (
h = `[0-9a-fA-F]`
d = `[0-9]`
)
var (
quoted bool
isAppArmorLogTemplate = regexp.MustCompile(`apparmor=("DENIED"|"ALLOWED"|"AUDIT")`)
_hex = `[0-9a-fA-F]`
_int = `[0-9]`
regCleanLogs = util.ToRegexRepl([]string{
// Clean apparmor log file
`.*apparmor="`, `apparmor="`,
@ -61,40 +64,45 @@ var (
`/home/[^/]+/`, `@{HOME}/`,
// Resolve system variables
`/usr/(lib|lib32|lib64|libexec)`, `@{lib}`,
`/usr/lib(32|64|exec)`, `@{lib}`,
`/usr/lib`, `@{lib}`,
`/usr/(bin|sbin)`, `@{bin}`,
`x86_64-pc-linux-gnu[^/]?`, `@{multiarch}`,
`(x86_64|amd64|i386|i686)`, `@{arch}`,
`@{arch}-*linux-gnu[^/]?`, `@{multiarch}`,
`/usr/etc/`, `@{etc_ro}/`,
`/var/run/`, `@{run}/`,
`/run/`, `@{run}/`,
`user/[0-9]*/`, `user/@{uid}/`,
`/tmp/user/@{uid}/`, `@{tmp}/`,
`/proc/`, `@{PROC}/`,
`@{PROC}/1/`, `@{PROC}/one/`, // Go does not support lookahead assertions like (?!1\b)d+, so we have to use a workaround
`@{PROC}/[0-9]*/`, `@{PROC}/@{pid}/`,
`@{PROC}/one/`, `@{PROC}/1/`,
`@{PROC}/@{pid}/task/[0-9]*/`, `@{PROC}/@{pid}/task/@{tid}/`,
`/sys/`, `@{sys}/`,
`@{PROC}@{sys}/`, `@{PROC}/sys/`,
`pci` + strings.Repeat(_hex, 4) + `:` + strings.Repeat(_hex, 2), `@{pci_bus}`,
`pci` + strings.Repeat(h, 4) + `:` + strings.Repeat(h, 2), `@{pci_bus}`,
`@{pci_bus}/[0-9a-f:*./]*`, `@{pci}/`,
`1000`, `@{uid}`,
// Some system glob
`:1.[0-9]*`, `:*`, // dbus peer name
`:not.active.yet`, `@{busname}`, // dbus unique bus name
`:1.[0-9]*`, `@{busname}`, // dbus unique bus name
`@{bin}/(|ba|da)sh`, `@{sh_path}`, // collect all shell
`@{lib}/modules/[^/]+\/`, `@{lib}/modules/*/`, // strip kernel version numbers from kernel module accesses
// int, hex, uuid
strings.Repeat(_hex, 8) + `[-_]` + strings.Repeat(_hex, 4) + `[-_]` + strings.Repeat(_hex, 4) + `[-_]` + strings.Repeat(_hex, 4) + `[-_]` + strings.Repeat(_hex, 12), `@{uuid}`,
strings.Repeat(_int, 64), `@{int64}`,
strings.Repeat(_hex, 64), `@{hex64}`,
strings.Repeat(_hex, 38), `@{hex38}`,
strings.Repeat(_int, 32), `@{int32}`,
strings.Repeat(_hex, 32), `@{hex32}`,
strings.Repeat(_int, 16), `@{int16}`,
strings.Repeat(_hex, 16), `@{hex16}`,
strings.Repeat(_int, 10), `@{int10}`,
strings.Repeat(_int, 8), `@{int8}`,
strings.Repeat(_int, 6), `@{int6}`,
strings.Repeat(h, 8) + `[-_]` + strings.Repeat(h, 4) + `[-_]` + strings.Repeat(h, 4) + `[-_]` + strings.Repeat(h, 4) + `[-_]` + strings.Repeat(h, 12), `@{uuid}`,
strings.Repeat(d, 64), `@{int64}`,
strings.Repeat(h, 64), `@{hex64}`,
strings.Repeat(h, 38), `@{hex38}`,
strings.Repeat(d, 32), `@{int32}`,
strings.Repeat(h, 32), `@{hex32}`,
strings.Repeat(d, 16), `@{int16}`,
strings.Repeat(h, 16), `@{hex16}`,
strings.Repeat(d, 10), `@{int10}`,
strings.Repeat(d, 8), `@{int8}`,
strings.Repeat(d, 6), `@{int6}`,
})
)
@ -117,8 +125,8 @@ func toQuote(str string) string {
return str
}
// NewApparmorLogs return a new ApparmorLogs list of map from a log file
func NewApparmorLogs(file io.Reader, profile string) AppArmorLogs {
// New returns a new ApparmorLogs list of map from a log file
func New(file io.Reader, profile string) AppArmorLogs {
logs := GetApparmorLogs(file, profile)
// Parse log into ApparmorLog struct

View file

@ -174,14 +174,14 @@ func TestAppArmorEvents(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
file := strings.NewReader(tt.event)
if got := NewApparmorLogs(file, ""); !reflect.DeepEqual(got, tt.want) {
t.Errorf("NewApparmorLogs() = %v, want %v", got, tt.want)
if got := New(file, ""); !reflect.DeepEqual(got, tt.want) {
t.Errorf("New() = %v, want %v", got, tt.want)
}
})
}
}
func TestNewApparmorLogs(t *testing.T) {
func TestNew(t *testing.T) {
tests := []struct {
name string
path string
@ -208,7 +208,7 @@ func TestNewApparmorLogs(t *testing.T) {
"apparmor": "DENIED",
"profile": "dnsmasq",
"operation": "open",
"name": "@{PROC}/@{pid}/environ",
"name": "@{PROC}/1/environ",
"comm": "dnsmasq",
"requested_mask": "r",
"denied_mask": "r",
@ -251,8 +251,8 @@ func TestNewApparmorLogs(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
file, _ := os.Open(tt.path)
if got := NewApparmorLogs(file, tt.name); !reflect.DeepEqual(got, tt.want) {
t.Errorf("NewApparmorLogs() = %v, want %v", got, tt.want)
if got := New(file, tt.name); !reflect.DeepEqual(got, tt.want) {
t.Errorf("New() = %v, want %v", got, tt.want)
}
})
}