Skip to content

Commit

Permalink
Add redis output
Browse files Browse the repository at this point in the history
Signed-off-by: pandyamarut <[email protected]>

extra space remove

Signed-off-by: pandyamarut <[email protected]>

fixes lint issues

Signed-off-by: pandyamarut <[email protected]>

fix output file lint issue

Signed-off-by: pandyamarut <[email protected]>

add another storage type and fix err tests

Signed-off-by: pandyamarut <[email protected]>

rebase with master

Signed-off-by: Marut Pandya <[email protected]>

adds configurable key value

Signed-off-by: pandyamarut <[email protected]>

edit config_example.yaml

Signed-off-by: pandyamarut <[email protected]>

Add redis output

Signed-off-by: pandyamarut <[email protected]>

add another storage type and fix err tests

Signed-off-by: pandyamarut <[email protected]>

adds configurable key value

Signed-off-by: pandyamarut <[email protected]>

edit config_example.yaml

Signed-off-by: pandyamarut <[email protected]>
  • Loading branch information
pandyamarut committed Mar 1, 2023
1 parent 20e41e7 commit 3427272
Show file tree
Hide file tree
Showing 11 changed files with 146 additions and 3 deletions.
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,13 @@ timescaledb:
# database: "" # TimescaleDB database used
# hypertablename: "falco_events" # Hypertable to store data events (default: falco_events) See TimescaleDB setup for more info
# minimumpriority: "" # minimum priority of event for using this output, order is emergency|alert|critical|error|warning|notice|informational|debug or "" (default)
redis:
# address: "" # Redis address, if not empty, Redis output is enabled
# password: "" # Password to authenticate with Redis (default: "")
# database: "" # Redis database number (default: 0)
# storagetype: "" # Redis storage type: hashmap or list (default: list)
# key: "" # Redis storage key name for hashmap, list(default: "falco")
# minimumpriority: "" # minimum priority of event for using this output, order is emergency|alert|critical|error|warning|notice|informational|debug or "" (default)
```

Usage :
Expand Down Expand Up @@ -1033,6 +1040,12 @@ order is
- **TIMESCALEDB_DATABASE**: TimescaleDB database used
- **TIMESCALEDB_HYPERTABLENAME**: Hypertable to store data events (default: falco_events) See TimescaleDB setup for more info
- **TIMESCALEDB_MINIMUMPRIORITY**: minimum priority of event for using this output, order is emergency|alert|critical|error|warning|notice|informational|debug or "" (default)
- **REDIS_ADDRESS**: Redis host, if not empty, Redis output is enabled (example: localhost:6379)
- **REDIS_PASSWORD**: Password to authenticate with Redis (default: "")
- **REDIS_DATABASE**: Redis database number (default: 0)
- **REDIS_STORAGE**: Redis storage type: hashmap or list (default: "list")
- **REDIS_Key**: Redis storage key name for hashmap, list(default: "falco")
- **REDIS_MINIMUMPRIORITY**: minimum priority of event for using this output, order is emergency|alert|critical|error|warning|notice|informational|debug or "" (default)

#### Slack/Rocketchat/Mattermost/Googlechat Message Formatting

Expand Down Expand Up @@ -1348,4 +1361,4 @@ make test-coverage
## Author
Thomas Labarussias (https://github.com/Issif)
Thomas Labarussias (https://github.com/Issif)
10 changes: 10 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,15 @@ func getConfig() *types.Configuration {
v.SetDefault("TimescaleDB.Hypertable", "falcosidekick_events")
v.SetDefault("TimescaleDB.MinimumPriority", "")

v.SetDefault("Redis.Address", "")
v.SetDefault("Redis.Password", "")
v.SetDefault("Redis.Database", 0)
v.SetDefault("Redis.StorageType", "list")
v.SetDefault("Redis.Key", "falco")
v.SetDefault("Redis.MinimumPriority", "")
v.SetDefault("Redis.MutualTls", false)
v.SetDefault("Redis.CheckCert", true)

v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
v.AutomaticEnv()
if *configFile != "" {
Expand Down Expand Up @@ -586,6 +595,7 @@ func getConfig() *types.Configuration {
c.NodeRed.MinimumPriority = checkPriority(c.NodeRed.MinimumPriority)
c.Gotify.MinimumPriority = checkPriority(c.Gotify.MinimumPriority)
c.TimescaleDB.MinimumPriority = checkPriority(c.TimescaleDB.MinimumPriority)
c.Redis.MinimumPriority = checkPriority(c.Redis.MinimumPriority)

c.Slack.MessageFormatTemplate = getMessageFormatTemplate("Slack", c.Slack.MessageFormat)
c.Rocketchat.MessageFormatTemplate = getMessageFormatTemplate("Rocketchat", c.Rocketchat.MessageFormat)
Expand Down
8 changes: 8 additions & 0 deletions config_example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -399,3 +399,11 @@ timescaledb:
# database: "" # TimescaleDB database used
# hypertablename: "falco_events" # Hypertable to store data events (default: falco_events) See TimescaleDB setup for more info
# minimumpriority: "" # minimum priority of event for using this output, order is emergency|alert|critical|error|warning|notice|informational|debug or "" (default)

redis:
# address: "" # Redis address, if not empty, Redis output is enabled
# password: "" # Password to authenticate with Redis (default: "")
# database: "" # Redis database number (default: 0)
# storagetype: "" # Redis storage type: hashmap or list (default: "list")
# key: "" # Redis storage key name for hashmap, list(default: "falco")
# minimumpriority: "" # minimum priority of event for using this output, order is emergency|alert|critical|error|warning|notice|informational|debug or "" (default)
6 changes: 4 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ require (
github.com/segmentio/kafka-go v0.4.38
github.com/spf13/viper v1.12.0
github.com/streadway/amqp v1.0.0
github.com/stretchr/testify v1.8.0
github.com/stretchr/testify v1.8.1
github.com/wavefronthq/wavefront-sdk-go v0.10.3
github.com/xitongsys/parquet-go v1.6.2
github.com/xitongsys/parquet-go-source v0.0.0-20220723234337-052319f3f36b
Expand Down Expand Up @@ -62,9 +62,10 @@ require (
github.com/benbjohnson/clock v1.3.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/caio/go-tdigest v3.1.0+incompatible // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/devigned/tab v0.1.1 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/emicklei/go-restful/v3 v3.9.0 // indirect
github.com/fsnotify/fsnotify v1.5.4 // indirect
github.com/go-logr/logr v1.2.3 // indirect
Expand Down Expand Up @@ -111,6 +112,7 @@ require (
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect
github.com/redis/go-redis/v9 v9.0.2 // indirect
github.com/spf13/afero v1.9.2 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
Expand Down
10 changes: 10 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,8 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
Expand Down Expand Up @@ -252,6 +254,8 @@ github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zA
github.com/devigned/tab v0.1.1 h1:3mD6Kb1mUOYeLpJvTVSDwSg5ZsfSxfvxGRTxRsJsITA=
github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/dimchansky/utfbom v1.1.0 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TRo4=
github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
Expand Down Expand Up @@ -782,6 +786,8 @@ github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/redis/go-redis/v9 v9.0.2 h1:BA426Zqe/7r56kCcvxYLWe1mkaz71LKF77GwgFzSxfE=
github.com/redis/go-redis/v9 v9.0.2/go.mod h1:/xDTe9EF1LM61hek62Poq2nzQSGj0xSrEtEHbBQevps=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
Expand Down Expand Up @@ -832,6 +838,8 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
Expand All @@ -843,6 +851,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs=
github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
Expand Down
4 changes: 4 additions & 0 deletions handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,4 +362,8 @@ func forwardEvent(falcopayload types.FalcoPayload) {
if config.TimescaleDB.Host != "" && (falcopayload.Priority >= types.Priority(config.TimescaleDB.MinimumPriority) || falcopayload.Rule == testRule) {
go timescaleDBClient.TimescaleDBPost(falcopayload)
}

if config.Redis.Address != "" && (falcopayload.Priority >= types.Priority(config.Redis.MinimumPriority) || falcopayload.Rule == testRule) {
go redisClient.RedisPost(falcopayload)
}
}
11 changes: 11 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ var (
gotifyClient *outputs.Client
spyderbatClient *outputs.Client
timescaleDBClient *outputs.Client
redisClient *outputs.Client

statsdClient, dogstatsdClient *statsd.Client
config *types.Configuration
Expand Down Expand Up @@ -651,6 +652,16 @@ func init() {
}
}

if config.Redis.Address != "" {
var err error
redisClient, err = outputs.NewRedisClient(config, stats, promStats, statsdClient, dogstatsdClient)
if err != nil {
config.Redis.Address = ""
} else {
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "Redis")
}
}

log.Printf("[INFO] : Falco Sidekick version: %s\n", GetVersionInfo().GitVersion)
log.Printf("[INFO] : Enabled Outputs : %s\n", outputs.EnabledOutputs)

Expand Down
2 changes: 2 additions & 0 deletions outputs/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (

mqtt "github.com/eclipse/paho.mqtt.golang"
timescaledb "github.com/jackc/pgx/v5/pgxpool"
redis "github.com/redis/go-redis/v9"

"github.com/falcosecurity/falcosidekick/types"
)
Expand Down Expand Up @@ -117,6 +118,7 @@ type Client struct {
Crdclient *crdClient.Clientset
MQTTClient mqtt.Client
TimescaleDBClient *timescaledb.Pool
RedisClient *redis.Client
}

// NewClient returns a new output.Client for accessing the different API.
Expand Down
67 changes: 67 additions & 0 deletions outputs/redis.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package outputs

import (
"context"
"encoding/json"
"log"
"strings"

"github.com/DataDog/datadog-go/statsd"
"github.com/falcosecurity/falcosidekick/types"
"github.com/redis/go-redis/v9"
)

func (c *Client) ReportError(err error) {
go c.CountMetric(Outputs, 1, []string{"output:redis", "status:error"})
c.Stats.Redis.Add(Error, 1)
c.PromStats.Outputs.With(map[string]string{"destination": "redis", "status": Error}).Inc()
log.Printf("[ERROR] : Redis - %v\n", err)
return
}

func NewRedisClient(config *types.Configuration, stats *types.Statistics, promStats *types.PromStatistics,
statsdClient, dogstatsdClient *statsd.Client) (*Client, error) {

rClient := redis.NewClient(&redis.Options{
Addr: config.Redis.Address,
Password: config.Redis.Password,
DB: config.Redis.Database,
})
// Ping the Redis server to check if it's running
pong, err := rClient.Ping(context.Background()).Result()
if err != nil {
log.Printf("[ERROR] : Redis - Misconfiguration, cannot connect to the server %v\n", err)
}
log.Printf("[INFO] : Redis - Connected to redis server: %v\n", pong)

return &Client{
OutputType: "Redis",
Config: config,
RedisClient: rClient,
Stats: stats,
PromStats: promStats,
StatsdClient: statsdClient,
DogstatsdClient: dogstatsdClient,
}, nil
}

func (c *Client) RedisPost(falcopayload types.FalcoPayload) {
c.Stats.Redis.Add(Total, 1)
redisPayload, _ := json.Marshal(falcopayload)
if strings.ToLower(c.Config.Redis.StorageType) == "hashmap" {
_, err := c.RedisClient.HSet(context.Background(), c.Config.Redis.Key, falcopayload.UUID, redisPayload).Result()
if err != nil {
c.ReportError(err)
}
} else {
_, err := c.RedisClient.RPush(context.Background(), c.Config.Redis.Key, redisPayload).Result()
if err != nil {
c.ReportError(err)
}
}

// Setting the success status
go c.CountMetric(Outputs, 1, []string{"output:redis", "status:ok"})
c.Stats.Redis.Add(OK, 1)
c.PromStats.Outputs.With(map[string]string{"destination": "redis", "status": OK}).Inc()
}
1 change: 1 addition & 0 deletions stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ func getInitStats() *types.Statistics {
Zincsearch: getOutputNewMap("zincsearch"),
Gotify: getOutputNewMap("gotify"),
TimescaleDB: getOutputNewMap("timescaledb"),
Redis: getOutputNewMap("redis"),
}
stats.Falco.Add(outputs.Emergency, 0)
stats.Falco.Add(outputs.Alert, 0)
Expand Down
15 changes: 15 additions & 0 deletions types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ type Configuration struct {
Gotify gotifyOutputConfig
Spyderbat SpyderbatConfig
TimescaleDB TimescaleDBConfig
Redis RedisConfig
}

// SlackOutputConfig represents parameters for Slack
Expand Down Expand Up @@ -621,6 +622,19 @@ type TimescaleDBConfig struct {
MinimumPriority string
}

// RedisConfig represents config parameters for Redis
type RedisConfig struct {
Address string
Password string
Database int
StorageType string
Key string
Version int
MinimumPriority string
CheckCert bool
MutualTLS bool
}

// Statistics is a struct to store stastics
type Statistics struct {
Requests *expvar.Map
Expand Down Expand Up @@ -680,6 +694,7 @@ type Statistics struct {
Gotify *expvar.Map
Spyderbat *expvar.Map
TimescaleDB *expvar.Map
Redis *expvar.Map
}

// PromStatistics is a struct to store prometheus metrics
Expand Down

0 comments on commit 3427272

Please sign in to comment.