Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add kolide_denylisted_query_attempts table #1458

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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 pkg/agent/knapsack/knapsack.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ func (k *knapsack) ControlStore() types.KVStore {
return k.getKVStore(storage.ControlStore)
}

func (k *knapsack) DenylistedQueryAttemptsStore() types.KVStore {
return k.getKVStore(storage.DenylistedQueryAttemptsStore)
}

func (k *knapsack) InitialResultsStore() types.KVStore {
return k.getKVStore(storage.InitialResultsStore)
}
Expand Down
1 change: 1 addition & 0 deletions pkg/agent/storage/bbolt/stores_bbolt.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ func MakeStores(logger log.Logger, db *bbolt.DB) (map[storage.Store]types.KVStor
storage.AutoupdateErrorsStore,
storage.ConfigStore,
storage.ControlStore,
storage.DenylistedQueryAttemptsStore,
storage.InitialResultsStore,
storage.ResultLogsStore,
storage.OsqueryHistoryInstanceStore,
Expand Down
1 change: 1 addition & 0 deletions pkg/agent/storage/ci/stores_ci.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func MakeStores(t *testing.T, logger log.Logger, db *bbolt.DB) (map[storage.Stor
storage.AutoupdateErrorsStore,
storage.ConfigStore,
storage.ControlStore,
storage.DenylistedQueryAttemptsStore,
storage.InitialResultsStore,
storage.ResultLogsStore,
storage.OsqueryHistoryInstanceStore,
Expand Down
25 changes: 13 additions & 12 deletions pkg/agent/storage/stores.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,19 @@ package storage
type Store string

const (
AgentFlagsStore Store = "agent_flags" // The store used for agent control flags.
AutoupdateErrorsStore Store = "tuf_autoupdate_errors" // The store used for tracking new autoupdater errors.
ConfigStore Store = "config" // The store used for launcher configuration.
ControlStore Store = "control_service_data" // The store used for control service caching data.
InitialResultsStore Store = "initial_results" // The store used for initial runner queries.
ResultLogsStore Store = "result_logs" // The store used for buffered result logs.
OsqueryHistoryInstanceStore Store = "osquery_instance_history" // The store used for the history of osquery instances.
SentNotificationsStore Store = "sent_notifications" // The store used for sent notifications.
StatusLogsStore Store = "status_logs" // The store used for buffered status logs.
ServerProvidedDataStore Store = "server_provided_data" // The store used for pushing values from server-backed tables.
TokenStore Store = "token_store" // The store used for holding bearer auth tokens, e.g. the ones used to authenticate with the observability ingest server.
ControlServerActionsStore Store = "action_store" // The store used for storing actions sent by control server.
AgentFlagsStore Store = "agent_flags" // The store used for agent control flags.
AutoupdateErrorsStore Store = "tuf_autoupdate_errors" // The store used for tracking new autoupdater errors.
ConfigStore Store = "config" // The store used for launcher configuration.
ControlStore Store = "control_service_data" // The store used for control service caching data.
DenylistedQueryAttemptsStore Store = "denylisted_query_attempts" // The store used to store attempts at running denylisted queries.
InitialResultsStore Store = "initial_results" // The store used for initial runner queries.
ResultLogsStore Store = "result_logs" // The store used for buffered result logs.
OsqueryHistoryInstanceStore Store = "osquery_instance_history" // The store used for the history of osquery instances.
SentNotificationsStore Store = "sent_notifications" // The store used for sent notifications.
StatusLogsStore Store = "status_logs" // The store used for buffered status logs.
ServerProvidedDataStore Store = "server_provided_data" // The store used for pushing values from server-backed tables.
TokenStore Store = "token_store" // The store used for holding bearer auth tokens, e.g. the ones used to authenticate with the observability ingest server.
ControlServerActionsStore Store = "action_store" // The store used for storing actions sent by control server.
)

func (storeType Store) String() string {
Expand Down
27 changes: 22 additions & 5 deletions pkg/agent/types/mocks/knapsack.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pkg/agent/types/stores.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ type Stores interface {
AutoupdateErrorsStore() KVStore
ConfigStore() KVStore
ControlStore() KVStore
DenylistedQueryAttemptsStore() KVStore
InitialResultsStore() KVStore
ResultLogsStore() KVStore
OsqueryHistoryInstanceStore() KVStore
Expand Down
1 change: 1 addition & 0 deletions pkg/osquery/table/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func LauncherTables(k types.Knapsack) []osquery.OsqueryPlugin {
tufinfo.TufReleaseVersionTable(k),
launcher_db.TablePlugin("kolide_tuf_autoupdater_errors", k.AutoupdateErrorsStore()),
desktopprocs.TablePlugin(),
launcher_db.TablePlugin("kolide_denylisted_query_attempts", k.DenylistedQueryAttemptsStore()),
}
}

Expand Down
5 changes: 5 additions & 0 deletions pkg/service/check_health.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,8 @@ func (mw uuidmw) CheckHealth(ctx context.Context) (status int32, err error) {
ctx = uuid.NewContext(ctx, uuid.NewForRequest())
return mw.next.CheckHealth(ctx)
}

func (mw extractingmw) CheckHealth(ctx context.Context) (status int32, err error) {
// Nothing to extract here
return mw.next.CheckHealth(ctx)
}
1 change: 1 addition & 0 deletions pkg/service/client_grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ func NewGRPCClient(k types.Knapsack, conn *grpc.ClientConn) KolideService {
// Wrap with UUID middleware after logger so that UUID is available in
// the logger context.
client = uuidMiddleware(client)
client = extractingMiddleware(k, client)

return client
}
Expand Down
1 change: 1 addition & 0 deletions pkg/service/client_jsonrpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ func NewJSONRPCClient(
// Wrap with UUID middleware after logger so that UUID is available in
// the logger context.
client = uuidMiddleware(client)
client = extractingMiddleware(k, client)

return client
}
32 changes: 32 additions & 0 deletions pkg/service/middleware.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package service

import (
"context"
"log/slog"
"strconv"
"time"

"github.com/kolide/launcher/pkg/agent/types"
"github.com/osquery/osquery-go/plugin/distributed"
)

type Middleware func(KolideService) KolideService
Expand All @@ -27,6 +31,34 @@ type uuidmw struct {
next KolideService
}

type extractingmw struct {
knapsack types.Knapsack
next KolideService
}

func extractingMiddleware(k types.Knapsack, next KolideService) KolideService {
return extractingmw{k, next}
}

func (mw extractingmw) extractDenylisted(ctx context.Context, results []distributed.Result) {
for _, r := range results {
// We expect that any denylisted queries will have the message "distributed query is denylisted", per
// https://osquery.readthedocs.io/en/latest/deployment/debugging/#distributed-query-denylisting
if r.Message != "distributed query is denylisted" {
continue
}

timestamp := strconv.Itoa(int(time.Now().Unix()))

if err := mw.knapsack.DenylistedQueryAttemptsStore().Set([]byte(timestamp), []byte(r.QueryName)); err != nil {
mw.knapsack.Slogger().Log(ctx, slog.LevelWarn, "could not store attempt at running denylisted query",
"err", err,
"query_name", r.QueryName,
)
}
}
}

// levelForError returns slog.LevelError if err != nil, else slog.LevelDebug
func levelForError(err error) slog.Level {
if err != nil {
Expand Down
5 changes: 5 additions & 0 deletions pkg/service/publish_logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,3 +199,8 @@ func (mw uuidmw) PublishLogs(ctx context.Context, nodeKey string, logType logger
ctx = uuid.NewContext(ctx, uuid.NewForRequest())
return mw.next.PublishLogs(ctx, nodeKey, logType, logs)
}

func (mw extractingmw) PublishLogs(ctx context.Context, nodeKey string, logType logger.LogType, logs []string) (message, errcode string, reauth bool, err error) {
// Nothing to extract here
return mw.next.PublishLogs(ctx, nodeKey, logType, logs)
}
5 changes: 5 additions & 0 deletions pkg/service/publish_results.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,3 +210,8 @@ func (mw uuidmw) PublishResults(ctx context.Context, nodeKey string, results []d
ctx = uuid.NewContext(ctx, uuid.NewForRequest())
return mw.next.PublishResults(ctx, nodeKey, results)
}

func (mw extractingmw) PublishResults(ctx context.Context, nodeKey string, results []distributed.Result) (message, errcode string, reauth bool, err error) {
go mw.extractDenylisted(ctx, results)
return mw.next.PublishResults(ctx, nodeKey, results)
}
5 changes: 5 additions & 0 deletions pkg/service/request_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,8 @@ func (mw uuidmw) RequestConfig(ctx context.Context, nodeKey string) (errcode str
ctx = uuid.NewContext(ctx, uuid.NewForRequest())
return mw.next.RequestConfig(ctx, nodeKey)
}

func (mw extractingmw) RequestConfig(ctx context.Context, nodeKey string) (errcode string, reauth bool, err error) {
// Nothing to extract here
return mw.next.RequestConfig(ctx, nodeKey)
}
5 changes: 5 additions & 0 deletions pkg/service/request_enrollment.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,3 +224,8 @@ func (mw uuidmw) RequestEnrollment(ctx context.Context, enrollSecret, hostIdenti
ctx = uuid.NewContext(ctx, uuid.NewForRequest())
return mw.next.RequestEnrollment(ctx, enrollSecret, hostIdentifier, details)
}

func (mw extractingmw) RequestEnrollment(ctx context.Context, enrollSecret, hostIdentifier string, details EnrollmentDetails) (errcode string, reauth bool, err error) {
// Nothing to extract here
return mw.next.RequestEnrollment(ctx, enrollSecret, hostIdentifier, details)
}
5 changes: 5 additions & 0 deletions pkg/service/request_queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,3 +174,8 @@ func (mw uuidmw) RequestQueries(ctx context.Context, nodeKey string) (res *distr
ctx = uuid.NewContext(ctx, uuid.NewForRequest())
return mw.next.RequestQueries(ctx, nodeKey)
}

func (mw extractingmw) RequestQueries(ctx context.Context, nodeKey string) (res *distributed.GetQueriesResult, reauth bool, err error) {
// Nothing to extract here
return mw.next.RequestQueries(ctx, nodeKey)
}
Loading