Skip to content

Commit

Permalink
add n8n output
Browse files Browse the repository at this point in the history
Signed-off-by: Thomas Labarussias <[email protected]>
  • Loading branch information
Issif committed Apr 24, 2023
1 parent be2db27 commit d24a4e9
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 0 deletions.
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ It works as a single endpoint for as many as you want `Falco` instances :

- [**AWS Security Lake**](https://aws.amazon.com/security-lake/)

### Workflow

- [**n8n**](https://n8n.io/)

### Other
- [**Policy Report**](https://github.com/kubernetes-sigs/wg-policy-prototypes/tree/master/policy-report/falco-adapter)

Expand Down Expand Up @@ -585,6 +589,15 @@ telegram:
# chatid: "" # telegram Identifier of the shared chat
# checkcert: true # check if ssl certificate of the output is valid (default: true)
# minimumpriority: "" # minimum priority of event for using this output, order is emergency|alert|critical|error|warning|notice|informational|debug or "" (default)

n8n:
# address: "" # N8N address, if not empty, N8N output is enabled
# user: "" # Username to authenticate with N8N in basic auth
# password: "" # Password to authenticate with N8N in basic auth
# headerauthname: "" # Header Auth Key to authenticate with N8N
# headerauthvalue: "" # Header Auth Value to authenticate with N8N
# checkcert: true # check if ssl certificate of the output is valid (default: true)
# 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 @@ -1076,6 +1089,11 @@ order is
- **TELEGRAM_CHATID**: telegram Identifier of the shared chat
- **TELEGRAM_CHECKCERT**: check if ssl certificate of the output is valid (default: true)
- **TELEGRAM_MINIMUMPRIORITY**: minimum priority of event for using this output, order is emergency|alert|critical|error|warning|notice|informational|debug or "" (default)
- **N8N_ADDRESS**: N8N address, if not empty, N8N output is enabled
- **N8N_USER**: Password to authenticate with N8N in basic auth
- **N8N_PASSWORD**: Header Auth Value to authenticate with N8N
- **N8N_CHECKCERT**: check if ssl certificate of the output is valid (default: true)
- **N8N_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
8 changes: 8 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,14 @@ func getConfig() *types.Configuration {
v.SetDefault("Redis.MutualTls", false)
v.SetDefault("Redis.CheckCert", true)

v.SetDefault("N8n.Address", "")
v.SetDefault("N8n.User", "")
v.SetDefault("N8n.Password", "")
v.SetDefault("N8n.HeaderAuthName", "")
v.SetDefault("N8n.HeaderAuthValue", "")
v.SetDefault("N8n.MinimumPriority", "")
v.SetDefault("N8n.CheckCert", true)

v.SetDefault("Slack.Token", "")
v.SetDefault("Slack.ChatID", "")
v.SetDefault("Slack.MinimumPriority", "")
Expand Down
9 changes: 9 additions & 0 deletions config_example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -422,3 +422,12 @@ telegram:
# chatid: "" # telegram Identifier of the shared chat
# checkcert: true # check if ssl certificate of the output is valid (default: true)
# minimumpriority: "" # minimum priority of event for using this output, order is emergency|alert|critical|error|warning|notice|informational|debug or "" (default)

n8n:
# address: "" # N8N address, if not empty, N8N output is enabled
# user: "" # Username to authenticate with N8N in basic auth
# password: "" # Password to authenticate with N8N in basic auth
# headerauthname: "" # Header Auth Key to authenticate with N8N
# headerauthvalue: "" # Header Auth Value to authenticate with N8N
# checkcert: true # check if ssl certificate of the output is valid (default: true)
# minimumpriority: "" # minimum priority of event for using this output, order is emergency|alert|critical|error|warning|notice|informational|debug or "" (default)
4 changes: 4 additions & 0 deletions handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -386,4 +386,8 @@ func forwardEvent(falcopayload types.FalcoPayload) {
if config.Telegram.ChatID != "" && config.Telegram.Token != "" && (falcopayload.Priority >= types.Priority(config.Telegram.MinimumPriority) || falcopayload.Rule == testRule) {
go telegramClient.TelegramPost(falcopayload)
}

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

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

if config.N8N.Address != "" {
var err error
n8nClient, err = outputs.NewClient("n8n", config.N8N.Address, false, config.N8N.CheckCert, config, stats, promStats, statsdClient, dogstatsdClient)
if err != nil {
config.N8N.Address = ""
} else {
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "n8n")
}
}

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

Expand Down
38 changes: 38 additions & 0 deletions outputs/n8n.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package outputs

import (
"log"

"github.com/falcosecurity/falcosidekick/types"
)

// N8NPost posts event to an URL
func (c *Client) N8NPost(falcopayload types.FalcoPayload) {
c.Stats.N8N.Add(Total, 1)

if c.Config.N8N.User != "" && c.Config.N8N.Password != "" {
c.httpClientLock.Lock()
defer c.httpClientLock.Unlock()
c.BasicAuth(c.Config.N8N.User, c.Config.N8N.Password)
}

if c.Config.N8N.HeaderAuthName != "" && c.Config.N8N.HeaderAuthValue != "" {
c.httpClientLock.Lock()
defer c.httpClientLock.Unlock()
c.AddHeader(c.Config.N8N.HeaderAuthName, c.Config.N8N.HeaderAuthValue)
}

err := c.Post(falcopayload)
if err != nil {
go c.CountMetric(Outputs, 1, []string{"output:n8n", "status:error"})
c.Stats.N8N.Add(Error, 1)
c.PromStats.Outputs.With(map[string]string{"destination": "n8n", "status": Error}).Inc()
log.Printf("[ERROR] : N8N - %v\n", err.Error())
return
}

// Setting the success status
go c.CountMetric(Outputs, 1, []string{"output:n8n", "status:ok"})
c.Stats.N8N.Add(OK, 1)
c.PromStats.Outputs.With(map[string]string{"destination": "n8n", "status": OK}).Inc()
}
1 change: 1 addition & 0 deletions stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ func getInitStats() *types.Statistics {
TimescaleDB: getOutputNewMap("timescaledb"),
Redis: getOutputNewMap("redis"),
Telegram: getOutputNewMap("telegram"),
N8N: getOutputNewMap("n8n"),
}
stats.Falco.Add(outputs.Emergency, 0)
stats.Falco.Add(outputs.Alert, 0)
Expand Down
13 changes: 13 additions & 0 deletions types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ type Configuration struct {
TimescaleDB TimescaleDBConfig
Redis RedisConfig
Telegram TelegramConfig
N8N N8NConfig
}

// SlackOutputConfig represents parameters for Slack
Expand Down Expand Up @@ -649,6 +650,17 @@ type TelegramConfig struct {
CheckCert bool
}

// N8NConfig represents config parameters for N8N
type N8NConfig struct {
Address string
User string
Password string
HeaderAuthName string
HeaderAuthValue string
MinimumPriority string
CheckCert bool
}

// Statistics is a struct to store stastics
type Statistics struct {
Requests *expvar.Map
Expand Down Expand Up @@ -710,6 +722,7 @@ type Statistics struct {
TimescaleDB *expvar.Map
Redis *expvar.Map
Telegram *expvar.Map
N8N *expvar.Map
}

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

0 comments on commit d24a4e9

Please sign in to comment.