add sentinel notification plugin (#2268)
This commit is contained in:
parent
4bc225f26b
commit
77d58652a3
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -46,6 +46,7 @@ plugins/notifications/slack/notification-slack
|
||||||
plugins/notifications/splunk/notification-splunk
|
plugins/notifications/splunk/notification-splunk
|
||||||
plugins/notifications/email/notification-email
|
plugins/notifications/email/notification-email
|
||||||
plugins/notifications/dummy/notification-dummy
|
plugins/notifications/dummy/notification-dummy
|
||||||
|
plugins/notifications/sentinel/notification-sentinel
|
||||||
|
|
||||||
# Test cache (downloaded files)
|
# Test cache (downloaded files)
|
||||||
.cache
|
.cache
|
||||||
|
|
|
@ -56,6 +56,7 @@ COPY --from=build /go/src/crowdsec/plugins/notifications/email/email.yaml /stagi
|
||||||
COPY --from=build /go/src/crowdsec/plugins/notifications/http/http.yaml /staging/etc/crowdsec/notifications/http.yaml
|
COPY --from=build /go/src/crowdsec/plugins/notifications/http/http.yaml /staging/etc/crowdsec/notifications/http.yaml
|
||||||
COPY --from=build /go/src/crowdsec/plugins/notifications/slack/slack.yaml /staging/etc/crowdsec/notifications/slack.yaml
|
COPY --from=build /go/src/crowdsec/plugins/notifications/slack/slack.yaml /staging/etc/crowdsec/notifications/slack.yaml
|
||||||
COPY --from=build /go/src/crowdsec/plugins/notifications/splunk/splunk.yaml /staging/etc/crowdsec/notifications/splunk.yaml
|
COPY --from=build /go/src/crowdsec/plugins/notifications/splunk/splunk.yaml /staging/etc/crowdsec/notifications/splunk.yaml
|
||||||
|
COPY --from=build /go/src/crowdsec/plugins/notifications/sentinel/sentinel.yaml /staging/etc/crowdsec/notifications/sentinel.yaml
|
||||||
COPY --from=build /usr/local/lib/crowdsec/plugins /usr/local/lib/crowdsec/plugins
|
COPY --from=build /usr/local/lib/crowdsec/plugins /usr/local/lib/crowdsec/plugins
|
||||||
|
|
||||||
FROM slim as geoip
|
FROM slim as geoip
|
||||||
|
|
|
@ -72,6 +72,7 @@ COPY --from=build /go/src/crowdsec/plugins/notifications/email/email.yaml /stagi
|
||||||
COPY --from=build /go/src/crowdsec/plugins/notifications/http/http.yaml /staging/etc/crowdsec/notifications/http.yaml
|
COPY --from=build /go/src/crowdsec/plugins/notifications/http/http.yaml /staging/etc/crowdsec/notifications/http.yaml
|
||||||
COPY --from=build /go/src/crowdsec/plugins/notifications/slack/slack.yaml /staging/etc/crowdsec/notifications/slack.yaml
|
COPY --from=build /go/src/crowdsec/plugins/notifications/slack/slack.yaml /staging/etc/crowdsec/notifications/slack.yaml
|
||||||
COPY --from=build /go/src/crowdsec/plugins/notifications/splunk/splunk.yaml /staging/etc/crowdsec/notifications/splunk.yaml
|
COPY --from=build /go/src/crowdsec/plugins/notifications/splunk/splunk.yaml /staging/etc/crowdsec/notifications/splunk.yaml
|
||||||
|
COPY --from=build /go/src/crowdsec/plugins/notifications/sentinel/sentinel.yaml /staging/etc/crowdsec/notifications/sentinel.yaml
|
||||||
COPY --from=build /usr/local/lib/crowdsec/plugins /usr/local/lib/crowdsec/plugins
|
COPY --from=build /usr/local/lib/crowdsec/plugins /usr/local/lib/crowdsec/plugins
|
||||||
|
|
||||||
FROM slim as geoip
|
FROM slim as geoip
|
||||||
|
|
1
debian/install
vendored
1
debian/install
vendored
|
@ -10,3 +10,4 @@ plugins/notifications/slack/slack.yaml etc/crowdsec/notifications/
|
||||||
plugins/notifications/http/http.yaml etc/crowdsec/notifications/
|
plugins/notifications/http/http.yaml etc/crowdsec/notifications/
|
||||||
plugins/notifications/splunk/splunk.yaml etc/crowdsec/notifications/
|
plugins/notifications/splunk/splunk.yaml etc/crowdsec/notifications/
|
||||||
plugins/notifications/email/email.yaml etc/crowdsec/notifications/
|
plugins/notifications/email/email.yaml etc/crowdsec/notifications/
|
||||||
|
plugins/notifications/sentinel/sentinel.yaml etc/crowdsec/notifications/
|
||||||
|
|
1
debian/rules
vendored
1
debian/rules
vendored
|
@ -29,6 +29,7 @@ override_dh_auto_install:
|
||||||
install -m 551 plugins/notifications/http/notification-http debian/crowdsec/usr/lib/crowdsec/plugins/
|
install -m 551 plugins/notifications/http/notification-http debian/crowdsec/usr/lib/crowdsec/plugins/
|
||||||
install -m 551 plugins/notifications/splunk/notification-splunk debian/crowdsec/usr/lib/crowdsec/plugins/
|
install -m 551 plugins/notifications/splunk/notification-splunk debian/crowdsec/usr/lib/crowdsec/plugins/
|
||||||
install -m 551 plugins/notifications/email/notification-email debian/crowdsec/usr/lib/crowdsec/plugins/
|
install -m 551 plugins/notifications/email/notification-email debian/crowdsec/usr/lib/crowdsec/plugins/
|
||||||
|
install -m 551 plugins/notifications/sentinel/notification-sentinel debian/crowdsec/usr/lib/crowdsec/plugins/
|
||||||
|
|
||||||
cp cmd/crowdsec/crowdsec debian/crowdsec/usr/bin
|
cp cmd/crowdsec/crowdsec debian/crowdsec/usr/bin
|
||||||
cp cmd/crowdsec-cli/cscli debian/crowdsec/usr/bin
|
cp cmd/crowdsec-cli/cscli debian/crowdsec/usr/bin
|
||||||
|
|
|
@ -50,9 +50,11 @@ def test_flavor_content(crowdsec, flavor):
|
||||||
assert 'notification-http' not in stdout
|
assert 'notification-http' not in stdout
|
||||||
assert 'notification-slack' not in stdout
|
assert 'notification-slack' not in stdout
|
||||||
assert 'notification-splunk' not in stdout
|
assert 'notification-splunk' not in stdout
|
||||||
|
assert 'notification-sentinel' not in stdout
|
||||||
else:
|
else:
|
||||||
assert x.exit_code == 0
|
assert x.exit_code == 0
|
||||||
assert 'notification-email' in stdout
|
assert 'notification-email' in stdout
|
||||||
assert 'notification-http' in stdout
|
assert 'notification-http' in stdout
|
||||||
assert 'notification-slack' in stdout
|
assert 'notification-slack' in stdout
|
||||||
assert 'notification-splunk' in stdout
|
assert 'notification-splunk' in stdout
|
||||||
|
assert 'notification-sentinel' in stdout
|
||||||
|
|
17
plugins/notifications/sentinel/Makefile
Normal file
17
plugins/notifications/sentinel/Makefile
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
ifeq ($(OS), Windows_NT)
|
||||||
|
SHELL := pwsh.exe
|
||||||
|
.SHELLFLAGS := -NoProfile -Command
|
||||||
|
EXT = .exe
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Go parameters
|
||||||
|
GOCMD = go
|
||||||
|
GOBUILD = $(GOCMD) build
|
||||||
|
|
||||||
|
BINARY_NAME = notification-sentinel$(EXT)
|
||||||
|
|
||||||
|
build: clean
|
||||||
|
$(GOBUILD) $(LD_OPTS) $(BUILD_VENDOR_FLAGS) -o $(BINARY_NAME)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@$(RM) $(BINARY_NAME) $(WIN_IGNORE_ERR)
|
28
plugins/notifications/sentinel/go.mod
Normal file
28
plugins/notifications/sentinel/go.mod
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
module github.com/crowdsecurity/sentinel-plugin
|
||||||
|
|
||||||
|
go 1.20
|
||||||
|
|
||||||
|
replace github.com/crowdsecurity/crowdsec => ../../../
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/crowdsecurity/crowdsec v1.5.0
|
||||||
|
github.com/hashicorp/go-hclog v1.5.0
|
||||||
|
github.com/hashicorp/go-plugin v1.4.10
|
||||||
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/fatih/color v1.15.0 // indirect
|
||||||
|
github.com/golang/protobuf v1.5.3 // indirect
|
||||||
|
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb // indirect
|
||||||
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||||
|
github.com/mitchellh/go-testing-interface v1.0.0 // indirect
|
||||||
|
github.com/oklog/run v1.0.0 // indirect
|
||||||
|
golang.org/x/net v0.9.0 // indirect
|
||||||
|
golang.org/x/sys v0.9.0 // indirect
|
||||||
|
golang.org/x/text v0.9.0 // indirect
|
||||||
|
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
|
||||||
|
google.golang.org/grpc v1.56.1 // indirect
|
||||||
|
google.golang.org/protobuf v1.30.0 // indirect
|
||||||
|
)
|
61
plugins/notifications/sentinel/go.sum
Normal file
61
plugins/notifications/sentinel/go.sum
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||||
|
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
|
||||||
|
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
|
||||||
|
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||||
|
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||||
|
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||||
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
|
github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c=
|
||||||
|
github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||||
|
github.com/hashicorp/go-plugin v1.4.10 h1:xUbmA4jC6Dq163/fWcp8P3JuHilrHHMLNRxzGQJ9hNk=
|
||||||
|
github.com/hashicorp/go-plugin v1.4.10/go.mod h1:6/1TEzT0eQznvI/gV2CM29DLSkAK/e58mUWKVsPaph0=
|
||||||
|
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M=
|
||||||
|
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
||||||
|
github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE=
|
||||||
|
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||||
|
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||||
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||||
|
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||||
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
|
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
|
||||||
|
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
|
github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0=
|
||||||
|
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||||
|
github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
|
||||||
|
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||||
|
github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
|
||||||
|
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
|
||||||
|
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||||
|
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
|
||||||
|
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||||
|
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A=
|
||||||
|
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
|
||||||
|
google.golang.org/grpc v1.56.1 h1:z0dNfjIl0VpaZ9iSVjA6daGatAYwPGstTjt5vkRMFkQ=
|
||||||
|
google.golang.org/grpc v1.56.1/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
|
||||||
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
|
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
|
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||||
|
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
133
plugins/notifications/sentinel/main.go
Normal file
133
plugins/notifications/sentinel/main.go
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/hmac"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/base64"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/crowdsecurity/crowdsec/pkg/protobufs"
|
||||||
|
"github.com/hashicorp/go-hclog"
|
||||||
|
"github.com/hashicorp/go-plugin"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PluginConfig struct {
|
||||||
|
Name string `yaml:"name"`
|
||||||
|
CustomerID string `yaml:"customer_id"`
|
||||||
|
SharedKey string `yaml:"shared_key"`
|
||||||
|
LogType string `yaml:"log_type"`
|
||||||
|
LogLevel *string `yaml:"log_level"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SentinelPlugin struct {
|
||||||
|
PluginConfigByName map[string]PluginConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
var logger hclog.Logger = hclog.New(&hclog.LoggerOptions{
|
||||||
|
Name: "sentinel-plugin",
|
||||||
|
Level: hclog.LevelFromString("INFO"),
|
||||||
|
Output: os.Stderr,
|
||||||
|
JSONFormat: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
func (s *SentinelPlugin) getAuthorizationHeader(now string, length int, pluginName string) (string, error) {
|
||||||
|
xHeaders := "x-ms-date:" + now
|
||||||
|
|
||||||
|
stringToHash := fmt.Sprintf("POST\n%d\napplication/json\n%s\n/api/logs", length, xHeaders)
|
||||||
|
decodedKey, _ := base64.StdEncoding.DecodeString(s.PluginConfigByName[pluginName].SharedKey)
|
||||||
|
|
||||||
|
h := hmac.New(sha256.New, decodedKey)
|
||||||
|
h.Write([]byte(stringToHash))
|
||||||
|
|
||||||
|
encodedHash := base64.StdEncoding.EncodeToString(h.Sum(nil))
|
||||||
|
authorization := "SharedKey " + s.PluginConfigByName[pluginName].CustomerID + ":" + encodedHash
|
||||||
|
|
||||||
|
logger.Trace("authorization header", "header", authorization)
|
||||||
|
|
||||||
|
return authorization, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SentinelPlugin) Notify(ctx context.Context, notification *protobufs.Notification) (*protobufs.Empty, error) {
|
||||||
|
|
||||||
|
if _, ok := s.PluginConfigByName[notification.Name]; !ok {
|
||||||
|
return nil, fmt.Errorf("invalid plugin config name %s", notification.Name)
|
||||||
|
}
|
||||||
|
cfg := s.PluginConfigByName[notification.Name]
|
||||||
|
|
||||||
|
if cfg.LogLevel != nil && *cfg.LogLevel != "" {
|
||||||
|
logger.SetLevel(hclog.LevelFromString(*cfg.LogLevel))
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Info("received notification for sentinel config", "name", notification.Name)
|
||||||
|
|
||||||
|
url := fmt.Sprintf("https://%s.ods.opinsights.azure.com/api/logs?api-version=2016-04-01", s.PluginConfigByName[notification.Name].CustomerID)
|
||||||
|
body := strings.NewReader(notification.Text)
|
||||||
|
|
||||||
|
//Cannot use time.RFC1123 as azure wants GMT, not UTC
|
||||||
|
now := time.Now().UTC().Format("Mon, 02 Jan 2006 15:04:05 GMT")
|
||||||
|
|
||||||
|
authorization, err := s.getAuthorizationHeader(now, len(notification.Text), notification.Name)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return &protobufs.Empty{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", url, body)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("failed to create request", "error", err)
|
||||||
|
return &protobufs.Empty{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
req.Header.Set("Log-Type", s.PluginConfigByName[notification.Name].LogType)
|
||||||
|
req.Header.Set("Authorization", authorization)
|
||||||
|
req.Header.Set("x-ms-date", now)
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("failed to send request", "error", err)
|
||||||
|
return &protobufs.Empty{}, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
logger.Debug("sent notification to sentinel", "status", resp.Status)
|
||||||
|
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
return &protobufs.Empty{}, fmt.Errorf("failed to send notification to sentinel: %s", resp.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &protobufs.Empty{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SentinelPlugin) Configure(ctx context.Context, config *protobufs.Config) (*protobufs.Empty, error) {
|
||||||
|
d := PluginConfig{}
|
||||||
|
err := yaml.Unmarshal(config.Config, &d)
|
||||||
|
s.PluginConfigByName[d.Name] = d
|
||||||
|
return &protobufs.Empty{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var handshake = plugin.HandshakeConfig{
|
||||||
|
ProtocolVersion: 1,
|
||||||
|
MagicCookieKey: "CROWDSEC_PLUGIN_KEY",
|
||||||
|
MagicCookieValue: os.Getenv("CROWDSEC_PLUGIN_KEY"),
|
||||||
|
}
|
||||||
|
|
||||||
|
sp := &SentinelPlugin{PluginConfigByName: make(map[string]PluginConfig)}
|
||||||
|
plugin.Serve(&plugin.ServeConfig{
|
||||||
|
HandshakeConfig: handshake,
|
||||||
|
Plugins: map[string]plugin.Plugin{
|
||||||
|
"sentinel": &protobufs.NotifierPlugin{
|
||||||
|
Impl: sp,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
GRPCServer: plugin.DefaultGRPCServer,
|
||||||
|
Logger: logger,
|
||||||
|
})
|
||||||
|
}
|
21
plugins/notifications/sentinel/sentinel.yaml
Normal file
21
plugins/notifications/sentinel/sentinel.yaml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
type: sentinel # Don't change
|
||||||
|
name: sentinel_default # Must match the registered plugin in the profile
|
||||||
|
|
||||||
|
# One of "trace", "debug", "info", "warn", "error", "off"
|
||||||
|
log_level: info
|
||||||
|
# group_wait: # Time to wait collecting alerts before relaying a message to this plugin, eg "30s"
|
||||||
|
# group_threshold: # Amount of alerts that triggers a message before <group_wait> has expired, eg "10"
|
||||||
|
# max_retry: # Number of attempts to relay messages to plugins in case of error
|
||||||
|
# timeout: # Time to wait for response from the plugin before considering the attempt a failure, eg "10s"
|
||||||
|
|
||||||
|
#-------------------------
|
||||||
|
# plugin-specific options
|
||||||
|
|
||||||
|
# The following template receives a list of models.Alert objects
|
||||||
|
# The output goes in the http request body
|
||||||
|
format: |
|
||||||
|
{{.|toJson}}
|
||||||
|
|
||||||
|
customer_id: XXX-XXX
|
||||||
|
shared_key: XXXXXXX
|
||||||
|
log_type: crowdsec
|
|
@ -67,11 +67,14 @@ install -m 551 plugins/notifications/slack/notification-slack %{buildroot}%{_lib
|
||||||
install -m 551 plugins/notifications/http/notification-http %{buildroot}%{_libdir}/%{name}/plugins/
|
install -m 551 plugins/notifications/http/notification-http %{buildroot}%{_libdir}/%{name}/plugins/
|
||||||
install -m 551 plugins/notifications/splunk/notification-splunk %{buildroot}%{_libdir}/%{name}/plugins/
|
install -m 551 plugins/notifications/splunk/notification-splunk %{buildroot}%{_libdir}/%{name}/plugins/
|
||||||
install -m 551 plugins/notifications/email/notification-email %{buildroot}%{_libdir}/%{name}/plugins/
|
install -m 551 plugins/notifications/email/notification-email %{buildroot}%{_libdir}/%{name}/plugins/
|
||||||
|
install -m 551 plugins/notifications/sentinel/notification-sentinel %{buildroot}%{_libdir}/%{name}/plugins/
|
||||||
|
|
||||||
install -m 600 plugins/notifications/slack/slack.yaml %{buildroot}%{_sysconfdir}/crowdsec/notifications/
|
install -m 600 plugins/notifications/slack/slack.yaml %{buildroot}%{_sysconfdir}/crowdsec/notifications/
|
||||||
install -m 600 plugins/notifications/http/http.yaml %{buildroot}%{_sysconfdir}/crowdsec/notifications/
|
install -m 600 plugins/notifications/http/http.yaml %{buildroot}%{_sysconfdir}/crowdsec/notifications/
|
||||||
install -m 600 plugins/notifications/splunk/splunk.yaml %{buildroot}%{_sysconfdir}/crowdsec/notifications/
|
install -m 600 plugins/notifications/splunk/splunk.yaml %{buildroot}%{_sysconfdir}/crowdsec/notifications/
|
||||||
install -m 600 plugins/notifications/email/email.yaml %{buildroot}%{_sysconfdir}/crowdsec/notifications/
|
install -m 600 plugins/notifications/email/email.yaml %{buildroot}%{_sysconfdir}/crowdsec/notifications/
|
||||||
|
install -m 600 plugins/notifications/sentinel/sentinel.yaml %{buildroot}%{_sysconfdir}/crowdsec/notifications/
|
||||||
|
|
||||||
|
|
||||||
%clean
|
%clean
|
||||||
rm -rf %{buildroot}
|
rm -rf %{buildroot}
|
||||||
|
@ -85,6 +88,7 @@ rm -rf %{buildroot}
|
||||||
%{_libdir}/%{name}/plugins/notification-http
|
%{_libdir}/%{name}/plugins/notification-http
|
||||||
%{_libdir}/%{name}/plugins/notification-splunk
|
%{_libdir}/%{name}/plugins/notification-splunk
|
||||||
%{_libdir}/%{name}/plugins/notification-email
|
%{_libdir}/%{name}/plugins/notification-email
|
||||||
|
%{_libdir}/%{name}/plugins/notification-sentinel
|
||||||
%{_sysconfdir}/%{name}/patterns/linux-syslog
|
%{_sysconfdir}/%{name}/patterns/linux-syslog
|
||||||
%{_sysconfdir}/%{name}/patterns/ruby
|
%{_sysconfdir}/%{name}/patterns/ruby
|
||||||
%{_sysconfdir}/%{name}/patterns/nginx
|
%{_sysconfdir}/%{name}/patterns/nginx
|
||||||
|
|
|
@ -71,7 +71,7 @@ $parser_s02="$parser_dir\s02-enrich"
|
||||||
$scenarios_dir="$config_dir\scenarios"
|
$scenarios_dir="$config_dir\scenarios"
|
||||||
$postoverflows_dir="$config_dir\postoverflows"
|
$postoverflows_dir="$config_dir\postoverflows"
|
||||||
$hub_dir="$config_dir\hub"
|
$hub_dir="$config_dir\hub"
|
||||||
$plugins=@("http", "slack", "splunk")
|
$plugins=@("http", "slack", "splunk", "email", "sentinel")
|
||||||
$plugins_dir="plugins"
|
$plugins_dir="plugins"
|
||||||
$notif_dir="notifications"
|
$notif_dir="notifications"
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ PARSER_S02="$PARSER_DIR/s02-enrich"
|
||||||
SCENARIOS_DIR="$CONFIG_DIR/scenarios"
|
SCENARIOS_DIR="$CONFIG_DIR/scenarios"
|
||||||
POSTOVERFLOWS_DIR="$CONFIG_DIR/postoverflows"
|
POSTOVERFLOWS_DIR="$CONFIG_DIR/postoverflows"
|
||||||
HUB_DIR="$CONFIG_DIR/hub"
|
HUB_DIR="$CONFIG_DIR/hub"
|
||||||
PLUGINS="http slack splunk email"
|
PLUGINS="http slack splunk email sentinel"
|
||||||
PLUGINS_DIR="plugins"
|
PLUGINS_DIR="plugins"
|
||||||
NOTIF_DIR="notifications"
|
NOTIF_DIR="notifications"
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ config_generate() {
|
||||||
type: syslog
|
type: syslog
|
||||||
EOT
|
EOT
|
||||||
|
|
||||||
cp ../plugins/notifications/*/{http,email,slack,splunk,dummy}.yaml \
|
cp ../plugins/notifications/*/{http,email,slack,splunk,dummy,sentinel}.yaml \
|
||||||
"${CONFIG_DIR}/notifications/"
|
"${CONFIG_DIR}/notifications/"
|
||||||
|
|
||||||
yq e '
|
yq e '
|
||||||
|
|
|
@ -99,6 +99,9 @@
|
||||||
<File Id="splunk.yaml" Source="plugins\notifications\splunk\splunk.yaml" Name="splunk.yaml">
|
<File Id="splunk.yaml" Source="plugins\notifications\splunk\splunk.yaml" Name="splunk.yaml">
|
||||||
<PermissionEx Sddl="D:PAI(A;;FA;;;SY)(A;;FA;;;BA)"/>
|
<PermissionEx Sddl="D:PAI(A;;FA;;;SY)(A;;FA;;;BA)"/>
|
||||||
</File>
|
</File>
|
||||||
|
<File Id="sentinel.yaml" Source="plugins\notifications\sentinel\sentinel.yaml" Name="sentinel.yaml">
|
||||||
|
<PermissionEx Sddl="D:PAI(A;;FA;;;SY)(A;;FA;;;BA)"/>
|
||||||
|
</File>
|
||||||
</Component>
|
</Component>
|
||||||
</Directory>
|
</Directory>
|
||||||
<Directory Id="PatternsDir" Name="patterns" />
|
<Directory Id="PatternsDir" Name="patterns" />
|
||||||
|
@ -124,6 +127,7 @@
|
||||||
<File Id="notification_email.exe" Source="plugins\notifications\email\notification-email.exe" />
|
<File Id="notification_email.exe" Source="plugins\notifications\email\notification-email.exe" />
|
||||||
<File Id="notification_http.exe" Source="plugins\notifications\http\notification-http.exe" />
|
<File Id="notification_http.exe" Source="plugins\notifications\http\notification-http.exe" />
|
||||||
<File Id="notification_splunk.exe" Source="plugins\notifications\splunk\notification-splunk.exe" />
|
<File Id="notification_splunk.exe" Source="plugins\notifications\splunk\notification-splunk.exe" />
|
||||||
|
<File Id="notification_sentinel.exe" Source="plugins\notifications\sentinel\notification-sentinel.exe" />
|
||||||
</Component>
|
</Component>
|
||||||
</Directory>
|
</Directory>
|
||||||
</Directory>
|
</Directory>
|
||||||
|
|
|
@ -81,11 +81,14 @@ HTTP_PLUGIN_BINARY="./plugins/notifications/http/notification-http"
|
||||||
SLACK_PLUGIN_BINARY="./plugins/notifications/slack/notification-slack"
|
SLACK_PLUGIN_BINARY="./plugins/notifications/slack/notification-slack"
|
||||||
SPLUNK_PLUGIN_BINARY="./plugins/notifications/splunk/notification-splunk"
|
SPLUNK_PLUGIN_BINARY="./plugins/notifications/splunk/notification-splunk"
|
||||||
EMAIL_PLUGIN_BINARY="./plugins/notifications/email/notification-email"
|
EMAIL_PLUGIN_BINARY="./plugins/notifications/email/notification-email"
|
||||||
|
SENTINEL_PLUGIN_BINARY="./plugins/notifications/sentinel/notification-sentinel"
|
||||||
|
|
||||||
HTTP_PLUGIN_CONFIG="./plugins/notifications/http/http.yaml"
|
HTTP_PLUGIN_CONFIG="./plugins/notifications/http/http.yaml"
|
||||||
SLACK_PLUGIN_CONFIG="./plugins/notifications/slack/slack.yaml"
|
SLACK_PLUGIN_CONFIG="./plugins/notifications/slack/slack.yaml"
|
||||||
SPLUNK_PLUGIN_CONFIG="./plugins/notifications/splunk/splunk.yaml"
|
SPLUNK_PLUGIN_CONFIG="./plugins/notifications/splunk/splunk.yaml"
|
||||||
EMAIL_PLUGIN_CONFIG="./plugins/notifications/email/email.yaml"
|
EMAIL_PLUGIN_CONFIG="./plugins/notifications/email/email.yaml"
|
||||||
|
SENTINEL_PLUGIN_CONFIG="./plugins/notifications/sentinel/sentinel.yaml"
|
||||||
|
|
||||||
|
|
||||||
BACKUP_DIR=$(mktemp -d)
|
BACKUP_DIR=$(mktemp -d)
|
||||||
rm -rf -- "$BACKUP_DIR"
|
rm -rf -- "$BACKUP_DIR"
|
||||||
|
@ -518,12 +521,14 @@ install_plugins(){
|
||||||
cp ${SPLUNK_PLUGIN_BINARY} ${CROWDSEC_PLUGIN_DIR}
|
cp ${SPLUNK_PLUGIN_BINARY} ${CROWDSEC_PLUGIN_DIR}
|
||||||
cp ${HTTP_PLUGIN_BINARY} ${CROWDSEC_PLUGIN_DIR}
|
cp ${HTTP_PLUGIN_BINARY} ${CROWDSEC_PLUGIN_DIR}
|
||||||
cp ${EMAIL_PLUGIN_BINARY} ${CROWDSEC_PLUGIN_DIR}
|
cp ${EMAIL_PLUGIN_BINARY} ${CROWDSEC_PLUGIN_DIR}
|
||||||
|
cp ${SENTINEL_PLUGIN_BINARY} ${CROWDSEC_PLUGIN_DIR}
|
||||||
|
|
||||||
if [[ ${DOCKER_MODE} == "false" ]]; then
|
if [[ ${DOCKER_MODE} == "false" ]]; then
|
||||||
cp -n ${SLACK_PLUGIN_CONFIG} /etc/crowdsec/notifications/
|
cp -n ${SLACK_PLUGIN_CONFIG} /etc/crowdsec/notifications/
|
||||||
cp -n ${SPLUNK_PLUGIN_CONFIG} /etc/crowdsec/notifications/
|
cp -n ${SPLUNK_PLUGIN_CONFIG} /etc/crowdsec/notifications/
|
||||||
cp -n ${HTTP_PLUGIN_CONFIG} /etc/crowdsec/notifications/
|
cp -n ${HTTP_PLUGIN_CONFIG} /etc/crowdsec/notifications/
|
||||||
cp -n ${EMAIL_PLUGIN_CONFIG} /etc/crowdsec/notifications/
|
cp -n ${EMAIL_PLUGIN_CONFIG} /etc/crowdsec/notifications/
|
||||||
|
cp -n ${SENTINEL_PLUGIN_CONFIG} /etc/crowdsec/notifications/
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue