Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
a423eaf
fix[frontend](settings): sending email configuration parameters on check
AlexSanchez-bit Apr 30, 2026
3c6323c
fix[frontend](integrations_guides): updated eset integration images
AlexSanchez-bit Apr 30, 2026
ddedc60
add correct status code for authentication errors
JocLRojas May 4, 2026
e9d7070
fix[frontend](alerts-view): setted echoes column as readonly (not sor…
AlexSanchez-bit May 5, 2026
823ce46
fix[frontend](alerts-view): added last echoe timestamp to alerts that…
AlexSanchez-bit May 5, 2026
7a0d15c
fix[frontend](integrations/json):updated json input guide
AlexSanchez-bit May 6, 2026
cf90521
fix[backend](collectors): avoid sending masked values to collectors
AlexSanchez-bit May 8, 2026
b5cffc4
fix[backend](csv_export): fixed csv export to include composed column…
AlexSanchez-bit May 9, 2026
d142b75
fix[frontend](tagging rules): fixed tagging rules ocnditions check
AlexSanchez-bit May 9, 2026
da364d2
fix[frontend](logexplorer): fixed sidebar selected fielrs and availab…
AlexSanchez-bit May 11, 2026
11dfdff
fix[frontend](ciscoswitch_integration): removed fixed integration nam…
AlexSanchez-bit May 13, 2026
4c0e8de
deleted: rule Office 365 Impossible Travel Login Detection removed fr…
JocLRojas May 14, 2026
6302a30
feat(filters/fortinet): add CEF format support to fortigate filter
JocLRojas May 14, 2026
608bec0
fix[ci]: build agent with CGO disabled
Kbayero May 15, 2026
791d91f
fix[installer]: generate complex password for OpenSearch
Kbayero May 15, 2026
589517f
update golang dependencies
Kbayero May 15, 2026
3911108
fix[agent](auditd): treat unavailable audit subsystem as skip, not error
Kbayero May 15, 2026
3c47450
fix[backend](collectors): enforce sending clear text passwords to col…
AlexSanchez-bit May 15, 2026
77e8440
fix[frontend](integration_guides): restored linux agent install path
AlexSanchez-bit May 15, 2026
ee3c06f
fix[backend](alerts): added last echoe field on alerts
AlexSanchez-bit May 15, 2026
b7fb0ca
fix[frontend](alerts): added last echoe timestamp to alert table
AlexSanchez-bit May 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/v11-deployment-pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ jobs:
env:
GOOS: linux
GOARCH: amd64
CGO_ENABLED: 0
run: |
cd ${{ github.workspace }}/agent
go build -o utmstack_agent_service_linux_amd64 -v -ldflags "-X 'github.com/utmstack/UTMStack/agent/config.REPLACE_KEY=${{ secrets.AGENT_SECRET_PREFIX }}'" .
Expand All @@ -145,6 +146,7 @@ jobs:
env:
GOOS: linux
GOARCH: arm64
CGO_ENABLED: 0
run: |
cd ${{ github.workspace }}/agent
go build -o utmstack_agent_service_linux_arm64 -v -ldflags "-X 'github.com/utmstack/UTMStack/agent/config.REPLACE_KEY=${{ secrets.AGENT_SECRET_PREFIX }}'" .
Expand All @@ -156,6 +158,7 @@ jobs:
env:
GOOS: windows
GOARCH: amd64
CGO_ENABLED: 0
run: |
cd ${{ github.workspace }}/agent
go build -o utmstack_agent_service_windows_amd64.exe -v -ldflags "-X 'github.com/utmstack/UTMStack/agent/config.REPLACE_KEY=${{ secrets.AGENT_SECRET_PREFIX }}'" .
Expand All @@ -167,6 +170,7 @@ jobs:
env:
GOOS: windows
GOARCH: arm64
CGO_ENABLED: 0
run: |
cd ${{ github.workspace }}/agent
go build -o utmstack_agent_service_windows_arm64.exe -v -ldflags "-X 'github.com/utmstack/UTMStack/agent/config.REPLACE_KEY=${{ secrets.AGENT_SECRET_PREFIX }}'" .
Expand Down
22 changes: 12 additions & 10 deletions agent-manager/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@ go 1.25.5

require (
github.com/AtlasInsideCorp/AtlasInsideAES v1.0.0
github.com/gin-gonic/gin v1.11.0
github.com/gin-gonic/gin v1.12.0
github.com/google/uuid v1.6.0
github.com/utmstack/config-client-go v1.2.7
google.golang.org/grpc v1.79.1
google.golang.org/grpc v1.81.1
google.golang.org/protobuf v1.36.11
gorm.io/driver/postgres v1.6.0
gorm.io/gorm v1.31.1
)

require go.mongodb.org/mongo-driver/v2 v2.5.0 // indirect

require (
github.com/bytedance/gopkg v0.1.3 // indirect
github.com/bytedance/sonic v1.15.0 // indirect
Expand Down Expand Up @@ -40,14 +42,14 @@ require (
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/quic-go/qpack v0.6.0 // indirect
github.com/quic-go/quic-go v0.59.0 // indirect
github.com/threatwinds/go-sdk v1.1.14
github.com/threatwinds/go-sdk v1.1.21
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.3.1 // indirect
golang.org/x/arch v0.23.0 // indirect
golang.org/x/crypto v0.47.0 // indirect
golang.org/x/net v0.49.0 // indirect
golang.org/x/sync v0.19.0 // indirect
golang.org/x/sys v0.40.0 // indirect
golang.org/x/text v0.33.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260203192932-546029d2fa20 // indirect
golang.org/x/arch v0.24.0 // indirect
golang.org/x/crypto v0.49.0 // indirect
golang.org/x/net v0.52.0 // indirect
golang.org/x/sync v0.20.0 // indirect
golang.org/x/sys v0.42.0 // indirect
golang.org/x/text v0.35.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 // indirect
)
66 changes: 34 additions & 32 deletions agent-manager/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ github.com/gabriel-vasile/mimetype v1.4.13 h1:46nXokslUBsAJE/wMsp5gtO500a4F3Nkz9
github.com/gabriel-vasile/mimetype v1.4.13/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk=
github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls=
github.com/gin-gonic/gin v1.12.0 h1:b3YAbrZtnf8N//yjKeU2+MQsh2mY5htkZidOM7O0wG8=
github.com/gin-gonic/gin v1.12.0/go.mod h1:VxccKfsSllpKshkBWgVgRniFFAzFb9csfngsqANjnLc=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
Expand Down Expand Up @@ -89,47 +89,49 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/threatwinds/go-sdk v1.1.14 h1:9XqqGPZvDHHuJ/XkfMsDl3fe7Adfi1fMh/PpQFkUkJU=
github.com/threatwinds/go-sdk v1.1.14/go.mod h1:Kfu26gkSZDpNNkPvuQbTAW3dWIQ66pVIrNYW1YBG3Kg=
github.com/threatwinds/go-sdk v1.1.21 h1:ZT/6Rb9szOLzXZdUgSa9eSDD4f5ljNDdzBWvR8hXTIE=
github.com/threatwinds/go-sdk v1.1.21/go.mod h1:kuU3op/tHVgoDhVeP4KHvyHXQKWSmmdEwJPUr0sGRLI=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY=
github.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
github.com/utmstack/config-client-go v1.2.7 h1:JeRdI5JjH1liNzMW3LmyevjuPd67J/yt9MAO3+oJAuM=
github.com/utmstack/config-client-go v1.2.7/go.mod h1:kM0KoUizM9ZlcQp0qKviGTWn/+anT5Rfjx3zfZk79nM=
go.mongodb.org/mongo-driver/v2 v2.5.0 h1:yXUhImUjjAInNcpTcAlPHiT7bIXhshCTL3jVBkF3xaE=
go.mongodb.org/mongo-driver/v2 v2.5.0/go.mod h1:yOI9kBsufol30iFsl1slpdq1I0eHPzybRWdyYUs8K/0=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I=
go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0=
go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM=
go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY=
go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg=
go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg=
go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw=
go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A=
go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A=
go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0=
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
golang.org/x/arch v0.23.0 h1:lKF64A2jF6Zd8L0knGltUnegD62JMFBiCPBmQpToHhg=
golang.org/x/arch v0.23.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A=
golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=
golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A=
golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=
golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/arch v0.24.0 h1:qlJ3M9upxvFfwRM51tTg3Yl+8CP9vCC1E7vlFpgv99Y=
golang.org/x/arch v0.24.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A=
golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4=
golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA=
golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0=
golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260203192932-546029d2fa20 h1:Jr5R2J6F6qWyzINc+4AM8t5pfUz6beZpHp678GNrMbE=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260203192932-546029d2fa20/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY=
google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8=
golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA=
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/grpc v1.81.1 h1:VnnIIZ88UzOOKLukQi+ImGz8O1Wdp8nAGGnvOfEIWQQ=
google.golang.org/grpc v1.81.1/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
41 changes: 27 additions & 14 deletions agent/collector/auditd/auditd_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package auditd

import (
"context"
"errors"
"os"
"sync"
"time"
Expand Down Expand Up @@ -35,9 +36,10 @@ func (a *AuditdCollector) Name() string {

// Start begins collecting audit events and sending them to the queue
func (a *AuditdCollector) Start(ctx context.Context, queue chan *plugins.Log) {
// Preflight check for audit capability
if err := checkAuditCapability(); err != nil {
utils.Logger.ErrorF("auditd: preflight check failed: %v", err)
if !errors.Is(err, ErrAuditUnavailable) {
utils.Logger.ErrorF("auditd: preflight check failed: %v", err)
}
return
}

Expand All @@ -59,9 +61,15 @@ func (a *AuditdCollector) Start(ctx context.Context, queue chan *plugins.Log) {

exitCode := a.runAuditClient(ctx, host, queue)

if exitCode == 0 {
switch exitCode {
case 0:
utils.Logger.Info("auditd client exited normally")
} else {
case auditdExitPermanent:
// Environment cannot run auditd (e.g. missing CAP_AUDIT_*, kernel
// audit disabled). Retrying will never succeed — exit silently.
utils.Logger.Info("auditd collector disabled: audit subsystem not accessible in this environment")
return
default:
utils.Logger.ErrorF("auditd client exited with code %d, restarting in %v", exitCode, restartDelay)
}

Expand All @@ -79,35 +87,40 @@ func (a *AuditdCollector) Start(ctx context.Context, queue chan *plugins.Log) {
}
}

// auditdExitPermanent signals that the collector cannot run in this
// environment and must not be retried.
const auditdExitPermanent = -2

// runAuditClient creates the audit client and runs the receive loop
func (a *AuditdCollector) runAuditClient(ctx context.Context, host string, queue chan *plugins.Log) int {
a.mu.Lock()
clientCtx, cancel := context.WithCancel(ctx)
a.cancel = cancel

// Attempt to set kernel backlog limit to prevent event loss under high load.
// This requires CAP_AUDIT_CONTROL; log warning if it fails but continue.
// Attempt to set kernel backlog limit and wait time. Both are best-effort
// tuning that require CAP_AUDIT_CONTROL — if they fail we just continue
// with kernel defaults, so log at Info level to avoid noise on restricted
// hosts (e.g. containers without audit capabilities).
if err := setKernelBacklogLimit(kernelBacklogLimit); err != nil {
utils.Logger.ErrorF("auditd: failed to set kernel backlog limit to %d: %v (continuing with default)", kernelBacklogLimit, err)
utils.Logger.Info("auditd: could not set kernel backlog limit (%v), using default", err)
} else {
utils.Logger.Info("auditd: kernel backlog limit set to %d", kernelBacklogLimit)
}

// Set backlog wait time to 0 to prevent audited processes from blocking
// when the audit backlog queue is full. The kernel will drop events instead.
// This is the "kernel" backpressure mitigation strategy from Elastic Auditbeat.
if err := setBacklogWaitTime(0); err != nil {
utils.Logger.ErrorF("auditd: failed to set backlog wait time to 0: %v (continuing)", err)
utils.Logger.Info("auditd: could not set backlog wait time (%v), using default", err)
} else {
utils.Logger.Info("auditd: backlog wait time set to 0 (non-blocking mode)")
}

// Create multicast audit client
// Create multicast audit client. Failure here (typically EPERM when the
// agent lacks CAP_AUDIT_READ) is permanent for the current process — the
// outer Start loop treats auditdExitPermanent as a no-retry condition.
client, err := newAuditClient()
if err != nil {
a.mu.Unlock()
utils.Logger.ErrorF("auditd: error creating audit client: %v", err)
return -1
utils.Logger.Info("auditd: cannot open audit netlink socket (%v); collector will not run", err)
return auditdExitPermanent
}
a.client = client

Expand Down
16 changes: 8 additions & 8 deletions agent/collector/auditd/capabilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,35 @@
package auditd

import (
"errors"
"os/exec"
"strings"

"github.com/utmstack/UTMStack/agent/utils"
)

var ErrAuditUnavailable = errors.New("audit subsystem unavailable in this environment")

// checkAuditCapability checks if the audit system is available and enabled.
// Uses auditctl -s to verify audit status since /proc/sys/kernel/auditing
// doesn't exist on all kernel versions.
func checkAuditCapability() error {
// Check if auditctl exists
auditctlPath, err := exec.LookPath("auditctl")
if err != nil {
utils.Logger.ErrorF("auditd: auditctl not found in PATH: %v", err)
return err
utils.Logger.Info("auditd: auditctl not found in PATH, collector will not start")
return ErrAuditUnavailable
}

// Run auditctl -s to check audit status
cmd := exec.Command(auditctlPath, "-s")
output, err := cmd.Output()
if err != nil {
utils.Logger.ErrorF("auditd: failed to run auditctl -s: %v", err)
return err
utils.Logger.Info("auditd: failed to run auditctl -s (%v), collector will not start", err)
return ErrAuditUnavailable
}

// Check if enabled=1 in output
if !strings.Contains(string(output), "enabled 1") && !strings.Contains(string(output), "enabled=1") {
utils.Logger.Info("auditd: kernel auditing is disabled (enabled != 1), collector will not start")
return nil
return ErrAuditUnavailable
}

utils.Logger.Info("auditd: audit system is enabled and ready")
Expand Down
23 changes: 9 additions & 14 deletions agent/dependency/auditd_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,45 +98,40 @@ func configureAuditd() error {

utils.Logger.Info("Detected distro: ID=%s, IDLike=%s, PackageManager=%s", distro.ID, distro.IDLike, distro.PackageManager)

// Install auditd if not already installed
if !isAuditdInstalled() {
utils.Logger.Info("Installing auditd package...")
if err := installAuditd(distro); err != nil {
utils.Logger.ErrorF("Failed to install auditd: %v", err)
return nil // Non-critical, don't fail the agent
utils.Logger.Info("auditd setup skipped: package install failed (%v)", err)
return nil
}
utils.Logger.Info("auditd package installed successfully")
} else {
utils.Logger.Info("auditd is already installed")
}

// Pre-flight check: can we modify audit configuration?
if canConfigure, reason := canConfigureAuditd(); !canConfigure {
utils.Logger.Info("auditd rule deployment skipped: %s", reason)
return nil // Non-critical, don't fail the agent
return nil
}

// Deploy audit rules
utils.Logger.Info("Deploying UTMStack audit rules...")
if err := deployRules(); err != nil {
utils.Logger.ErrorF("Failed to deploy audit rules: %v", err)
return nil // Non-critical, don't fail the agent
utils.Logger.Info("auditd setup skipped: rule deployment failed (%v)", err)
return nil
}
utils.Logger.Info("UTMStack audit rules deployed successfully")

// Start and enable auditd service
utils.Logger.Info("Starting auditd service...")
if err := startAuditd(); err != nil {
utils.Logger.ErrorF("Failed to start auditd service: %v", err)
return nil // Non-critical, don't fail the agent
utils.Logger.Info("auditd setup skipped: service start failed (%v)", err)
return nil
}
utils.Logger.Info("auditd service started and enabled")

// Reload rules
utils.Logger.Info("Reloading audit rules...")
if err := reloadRules(); err != nil {
utils.Logger.ErrorF("Failed to reload audit rules: %v", err)
return nil // Non-critical, don't fail the agent
utils.Logger.Info("auditd setup skipped: rule reload failed (%v)", err)
return nil
}
utils.Logger.Info("Audit rules reloaded successfully")

Expand Down
20 changes: 10 additions & 10 deletions agent/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ require (
github.com/AtlasInsideCorp/AtlasInsideAES v1.0.0
github.com/elastic/go-libaudit/v2 v2.6.2
github.com/elastic/go-sysinfo v1.15.4
github.com/fsnotify/fsnotify v1.9.0
github.com/fsnotify/fsnotify v1.10.1
github.com/glebarez/sqlite v1.11.0
github.com/google/uuid v1.6.0
github.com/kardianos/service v1.2.4
github.com/netsampler/goflow2 v1.3.7
github.com/spf13/cobra v1.10.2
github.com/tehmaze/netflow v0.0.0-20240303214733-8c13bb004068
github.com/threatwinds/go-sdk v1.1.14
github.com/threatwinds/go-sdk v1.1.21
github.com/threatwinds/logger v1.2.3
github.com/utmstack/UTMStack/shared v0.0.0
golang.org/x/sys v0.41.0
google.golang.org/grpc v1.79.1
golang.org/x/sys v0.44.0
google.golang.org/grpc v1.81.1
google.golang.org/protobuf v1.36.11
gorm.io/gorm v1.31.1
)
Expand Down Expand Up @@ -68,13 +68,13 @@ require (
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.3.1 // indirect
go.yaml.in/yaml/v2 v2.4.3 // indirect
golang.org/x/arch v0.23.0 // indirect
golang.org/x/crypto v0.47.0 // indirect
golang.org/x/arch v0.24.0 // indirect
golang.org/x/crypto v0.49.0 // indirect
golang.org/x/exp v0.0.0-20260112195511-716be5621a96 // indirect
golang.org/x/net v0.49.0 // indirect
golang.org/x/text v0.33.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260203192932-546029d2fa20 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260203192932-546029d2fa20 // indirect
golang.org/x/net v0.52.0 // indirect
golang.org/x/text v0.35.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
howett.net/plist v1.0.1 // indirect
Expand Down
Loading
Loading