parent
2abc078e53
commit
d2c4bc55fc
6 changed files with 68 additions and 28 deletions
|
@ -82,11 +82,6 @@ linters-settings:
|
|||
- "!**/pkg/apiserver/controllers/v1/errors.go"
|
||||
yaml:
|
||||
files:
|
||||
- "!**/cmd/notification-dummy/main.go"
|
||||
- "!**/cmd/notification-email/main.go"
|
||||
- "!**/cmd/notification-http/main.go"
|
||||
- "!**/cmd/notification-slack/main.go"
|
||||
- "!**/cmd/notification-splunk/main.go"
|
||||
- "!**/pkg/acquisition/acquisition.go"
|
||||
- "!**/pkg/acquisition/acquisition_test.go"
|
||||
- "!**/pkg/acquisition/modules/appsec/appsec.go"
|
||||
|
|
|
@ -5,10 +5,11 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/protobufs"
|
||||
"github.com/hashicorp/go-hclog"
|
||||
plugin "github.com/hashicorp/go-plugin"
|
||||
"gopkg.in/yaml.v2"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/protobufs"
|
||||
)
|
||||
|
||||
type PluginConfig struct {
|
||||
|
@ -32,6 +33,7 @@ func (s *DummyPlugin) Notify(ctx context.Context, notification *protobufs.Notifi
|
|||
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 != "" {
|
||||
|
@ -42,19 +44,22 @@ func (s *DummyPlugin) Notify(ctx context.Context, notification *protobufs.Notifi
|
|||
logger.Debug(notification.Text)
|
||||
|
||||
if cfg.OutputFile != nil && *cfg.OutputFile != "" {
|
||||
f, err := os.OpenFile(*cfg.OutputFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
f, err := os.OpenFile(*cfg.OutputFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644)
|
||||
if err != nil {
|
||||
logger.Error(fmt.Sprintf("Cannot open notification file: %s", err))
|
||||
}
|
||||
|
||||
if _, err := f.WriteString(notification.Text + "\n"); err != nil {
|
||||
f.Close()
|
||||
logger.Error(fmt.Sprintf("Cannot write notification to file: %s", err))
|
||||
}
|
||||
|
||||
err = f.Close()
|
||||
if err != nil {
|
||||
logger.Error(fmt.Sprintf("Cannot close notification file: %s", err))
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println(notification.Text)
|
||||
|
||||
return &protobufs.Empty{}, nil
|
||||
|
@ -64,11 +69,12 @@ func (s *DummyPlugin) Configure(ctx context.Context, config *protobufs.Config) (
|
|||
d := PluginConfig{}
|
||||
err := yaml.Unmarshal(config.Config, &d)
|
||||
s.PluginConfigByName[d.Name] = d
|
||||
|
||||
return &protobufs.Empty{}, err
|
||||
}
|
||||
|
||||
func main() {
|
||||
var handshake = plugin.HandshakeConfig{
|
||||
handshake := plugin.HandshakeConfig{
|
||||
ProtocolVersion: 1,
|
||||
MagicCookieKey: "CROWDSEC_PLUGIN_KEY",
|
||||
MagicCookieValue: os.Getenv("CROWDSEC_PLUGIN_KEY"),
|
||||
|
|
|
@ -2,15 +2,17 @@ package main
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/protobufs"
|
||||
"github.com/hashicorp/go-hclog"
|
||||
plugin "github.com/hashicorp/go-plugin"
|
||||
mail "github.com/xhit/go-simple-mail/v2"
|
||||
"gopkg.in/yaml.v2"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/protobufs"
|
||||
)
|
||||
|
||||
var baseLogger hclog.Logger = hclog.New(&hclog.LoggerOptions{
|
||||
|
@ -72,19 +74,20 @@ func (n *EmailPlugin) Configure(ctx context.Context, config *protobufs.Config) (
|
|||
}
|
||||
|
||||
if d.Name == "" {
|
||||
return nil, fmt.Errorf("name is required")
|
||||
return nil, errors.New("name is required")
|
||||
}
|
||||
|
||||
if d.SMTPHost == "" {
|
||||
return nil, fmt.Errorf("SMTP host is not set")
|
||||
return nil, errors.New("SMTP host is not set")
|
||||
}
|
||||
|
||||
if d.ReceiverEmails == nil || len(d.ReceiverEmails) == 0 {
|
||||
return nil, fmt.Errorf("receiver emails are not set")
|
||||
return nil, errors.New("receiver emails are not set")
|
||||
}
|
||||
|
||||
n.ConfigByName[d.Name] = d
|
||||
baseLogger.Debug(fmt.Sprintf("Email plugin '%s' use SMTP host '%s:%d'", d.Name, d.SMTPHost, d.SMTPPort))
|
||||
|
||||
return &protobufs.Empty{}, nil
|
||||
}
|
||||
|
||||
|
@ -92,6 +95,7 @@ func (n *EmailPlugin) Notify(ctx context.Context, notification *protobufs.Notifi
|
|||
if _, ok := n.ConfigByName[notification.Name]; !ok {
|
||||
return nil, fmt.Errorf("invalid plugin config name %s", notification.Name)
|
||||
}
|
||||
|
||||
cfg := n.ConfigByName[notification.Name]
|
||||
|
||||
logger := baseLogger.Named(cfg.Name)
|
||||
|
@ -117,6 +121,7 @@ func (n *EmailPlugin) Notify(ctx context.Context, notification *protobufs.Notifi
|
|||
server.ConnectTimeout, err = time.ParseDuration(cfg.ConnectTimeout)
|
||||
if err != nil {
|
||||
logger.Warn(fmt.Sprintf("invalid connect timeout '%s', using default '10s'", cfg.ConnectTimeout))
|
||||
|
||||
server.ConnectTimeout = 10 * time.Second
|
||||
}
|
||||
}
|
||||
|
@ -125,15 +130,18 @@ func (n *EmailPlugin) Notify(ctx context.Context, notification *protobufs.Notifi
|
|||
server.SendTimeout, err = time.ParseDuration(cfg.SendTimeout)
|
||||
if err != nil {
|
||||
logger.Warn(fmt.Sprintf("invalid send timeout '%s', using default '10s'", cfg.SendTimeout))
|
||||
|
||||
server.SendTimeout = 10 * time.Second
|
||||
}
|
||||
}
|
||||
|
||||
logger.Debug("making smtp connection")
|
||||
|
||||
smtpClient, err := server.Connect()
|
||||
if err != nil {
|
||||
return &protobufs.Empty{}, err
|
||||
}
|
||||
|
||||
logger.Debug("smtp connection done")
|
||||
|
||||
email := mail.NewMSG()
|
||||
|
@ -146,12 +154,14 @@ func (n *EmailPlugin) Notify(ctx context.Context, notification *protobufs.Notifi
|
|||
if err != nil {
|
||||
return &protobufs.Empty{}, err
|
||||
}
|
||||
|
||||
logger.Info(fmt.Sprintf("sent email to %v", cfg.ReceiverEmails))
|
||||
|
||||
return &protobufs.Empty{}, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
var handshake = plugin.HandshakeConfig{
|
||||
handshake := plugin.HandshakeConfig{
|
||||
ProtocolVersion: 1,
|
||||
MagicCookieKey: "CROWDSEC_PLUGIN_KEY",
|
||||
MagicCookieValue: os.Getenv("CROWDSEC_PLUGIN_KEY"),
|
||||
|
|
|
@ -12,10 +12,11 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/protobufs"
|
||||
"github.com/hashicorp/go-hclog"
|
||||
plugin "github.com/hashicorp/go-plugin"
|
||||
"gopkg.in/yaml.v2"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/protobufs"
|
||||
)
|
||||
|
||||
type PluginConfig struct {
|
||||
|
@ -90,18 +91,23 @@ func getTLSClient(c *PluginConfig) error {
|
|||
|
||||
tlsConfig.Certificates = []tls.Certificate{cert}
|
||||
}
|
||||
|
||||
transport := &http.Transport{
|
||||
TLSClientConfig: tlsConfig,
|
||||
}
|
||||
|
||||
if c.UnixSocket != "" {
|
||||
logger.Info(fmt.Sprintf("Using socket '%s'", c.UnixSocket))
|
||||
|
||||
transport.DialContext = func(_ context.Context, _, _ string) (net.Conn, error) {
|
||||
return net.Dial("unix", strings.TrimSuffix(c.UnixSocket, "/"))
|
||||
}
|
||||
}
|
||||
|
||||
c.Client = &http.Client{
|
||||
Transport: transport,
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -109,6 +115,7 @@ func (s *HTTPPlugin) Notify(ctx context.Context, notification *protobufs.Notific
|
|||
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 != "" {
|
||||
|
@ -121,11 +128,14 @@ func (s *HTTPPlugin) Notify(ctx context.Context, notification *protobufs.Notific
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for headerName, headerValue := range cfg.Headers {
|
||||
logger.Debug(fmt.Sprintf("adding header %s: %s", headerName, headerValue))
|
||||
request.Header.Add(headerName, headerValue)
|
||||
}
|
||||
|
||||
logger.Debug(fmt.Sprintf("making HTTP %s call to %s with body %s", cfg.Method, cfg.URL, notification.Text))
|
||||
|
||||
resp, err := cfg.Client.Do(request.WithContext(ctx))
|
||||
if err != nil {
|
||||
logger.Error(fmt.Sprintf("Failed to make HTTP request : %s", err))
|
||||
|
@ -135,7 +145,7 @@ func (s *HTTPPlugin) Notify(ctx context.Context, notification *protobufs.Notific
|
|||
|
||||
respData, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read response body got error %s", err)
|
||||
return nil, fmt.Errorf("failed to read response body got error %w", err)
|
||||
}
|
||||
|
||||
logger.Debug(fmt.Sprintf("got response %s", string(respData)))
|
||||
|
@ -143,6 +153,7 @@ func (s *HTTPPlugin) Notify(ctx context.Context, notification *protobufs.Notific
|
|||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||
logger.Warn(fmt.Sprintf("HTTP server returned non 200 status code: %d", resp.StatusCode))
|
||||
logger.Debug(fmt.Sprintf("HTTP server returned body: %s", string(respData)))
|
||||
|
||||
return &protobufs.Empty{}, nil
|
||||
}
|
||||
|
||||
|
@ -151,21 +162,25 @@ func (s *HTTPPlugin) Notify(ctx context.Context, notification *protobufs.Notific
|
|||
|
||||
func (s *HTTPPlugin) Configure(ctx context.Context, config *protobufs.Config) (*protobufs.Empty, error) {
|
||||
d := PluginConfig{}
|
||||
|
||||
err := yaml.Unmarshal(config.Config, &d)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = getTLSClient(&d)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.PluginConfigByName[d.Name] = d
|
||||
logger.Debug(fmt.Sprintf("HTTP plugin '%s' use URL '%s'", d.Name, d.URL))
|
||||
|
||||
return &protobufs.Empty{}, err
|
||||
}
|
||||
|
||||
func main() {
|
||||
var handshake = plugin.HandshakeConfig{
|
||||
handshake := plugin.HandshakeConfig{
|
||||
ProtocolVersion: 1,
|
||||
MagicCookieKey: "CROWDSEC_PLUGIN_KEY",
|
||||
MagicCookieValue: os.Getenv("CROWDSEC_PLUGIN_KEY"),
|
||||
|
|
|
@ -5,12 +5,12 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/protobufs"
|
||||
"github.com/hashicorp/go-hclog"
|
||||
plugin "github.com/hashicorp/go-plugin"
|
||||
|
||||
"github.com/slack-go/slack"
|
||||
"gopkg.in/yaml.v2"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/protobufs"
|
||||
)
|
||||
|
||||
type PluginConfig struct {
|
||||
|
@ -33,13 +33,16 @@ func (n *Notify) Notify(ctx context.Context, notification *protobufs.Notificatio
|
|||
if _, ok := n.ConfigByName[notification.Name]; !ok {
|
||||
return nil, fmt.Errorf("invalid plugin config name %s", notification.Name)
|
||||
}
|
||||
|
||||
cfg := n.ConfigByName[notification.Name]
|
||||
|
||||
if cfg.LogLevel != nil && *cfg.LogLevel != "" {
|
||||
logger.SetLevel(hclog.LevelFromString(*cfg.LogLevel))
|
||||
}
|
||||
|
||||
logger.Info(fmt.Sprintf("found notify signal for %s config", notification.Name))
|
||||
logger.Debug(fmt.Sprintf("posting to %s webhook, message %s", cfg.Webhook, notification.Text))
|
||||
|
||||
err := slack.PostWebhookContext(ctx, n.ConfigByName[notification.Name].Webhook, &slack.WebhookMessage{
|
||||
Text: notification.Text,
|
||||
})
|
||||
|
@ -52,16 +55,19 @@ func (n *Notify) Notify(ctx context.Context, notification *protobufs.Notificatio
|
|||
|
||||
func (n *Notify) Configure(ctx context.Context, config *protobufs.Config) (*protobufs.Empty, error) {
|
||||
d := PluginConfig{}
|
||||
|
||||
if err := yaml.Unmarshal(config.Config, &d); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
n.ConfigByName[d.Name] = d
|
||||
logger.Debug(fmt.Sprintf("Slack plugin '%s' use URL '%s'", d.Name, d.Webhook))
|
||||
|
||||
return &protobufs.Empty{}, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
var handshake = plugin.HandshakeConfig{
|
||||
handshake := plugin.HandshakeConfig{
|
||||
ProtocolVersion: 1,
|
||||
MagicCookieKey: "CROWDSEC_PLUGIN_KEY",
|
||||
MagicCookieValue: os.Getenv("CROWDSEC_PLUGIN_KEY"),
|
||||
|
|
|
@ -10,11 +10,11 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/protobufs"
|
||||
"github.com/hashicorp/go-hclog"
|
||||
plugin "github.com/hashicorp/go-plugin"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/protobufs"
|
||||
)
|
||||
|
||||
var logger hclog.Logger = hclog.New(&hclog.LoggerOptions{
|
||||
|
@ -44,6 +44,7 @@ func (s *Splunk) Notify(ctx context.Context, notification *protobufs.Notificatio
|
|||
if _, ok := s.PluginConfigByName[notification.Name]; !ok {
|
||||
return &protobufs.Empty{}, fmt.Errorf("splunk invalid config name %s", notification.Name)
|
||||
}
|
||||
|
||||
cfg := s.PluginConfigByName[notification.Name]
|
||||
|
||||
if cfg.LogLevel != nil && *cfg.LogLevel != "" {
|
||||
|
@ -53,6 +54,7 @@ func (s *Splunk) Notify(ctx context.Context, notification *protobufs.Notificatio
|
|||
logger.Info(fmt.Sprintf("received notify signal for %s config", notification.Name))
|
||||
|
||||
p := Payload{Event: notification.Text}
|
||||
|
||||
data, err := json.Marshal(p)
|
||||
if err != nil {
|
||||
return &protobufs.Empty{}, err
|
||||
|
@ -65,6 +67,7 @@ func (s *Splunk) Notify(ctx context.Context, notification *protobufs.Notificatio
|
|||
|
||||
req.Header.Add("Authorization", fmt.Sprintf("Splunk %s", cfg.Token))
|
||||
logger.Debug(fmt.Sprintf("posting event %s to %s", string(data), req.URL))
|
||||
|
||||
resp, err := s.Client.Do(req.WithContext(ctx))
|
||||
if err != nil {
|
||||
return &protobufs.Empty{}, err
|
||||
|
@ -73,15 +76,19 @@ func (s *Splunk) Notify(ctx context.Context, notification *protobufs.Notificatio
|
|||
if resp.StatusCode != http.StatusOK {
|
||||
content, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return &protobufs.Empty{}, fmt.Errorf("got non 200 response and failed to read error %s", err)
|
||||
return &protobufs.Empty{}, fmt.Errorf("got non 200 response and failed to read error %w", err)
|
||||
}
|
||||
|
||||
return &protobufs.Empty{}, fmt.Errorf("got non 200 response %s", string(content))
|
||||
}
|
||||
|
||||
respData, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return &protobufs.Empty{}, fmt.Errorf("failed to read response body got error %s", err)
|
||||
return &protobufs.Empty{}, fmt.Errorf("failed to read response body got error %w", err)
|
||||
}
|
||||
|
||||
logger.Debug(fmt.Sprintf("got response %s", string(respData)))
|
||||
|
||||
return &protobufs.Empty{}, nil
|
||||
}
|
||||
|
||||
|
@ -90,11 +97,12 @@ func (s *Splunk) Configure(ctx context.Context, config *protobufs.Config) (*prot
|
|||
err := yaml.Unmarshal(config.Config, &d)
|
||||
s.PluginConfigByName[d.Name] = d
|
||||
logger.Debug(fmt.Sprintf("Splunk plugin '%s' use URL '%s'", d.Name, d.URL))
|
||||
|
||||
return &protobufs.Empty{}, err
|
||||
}
|
||||
|
||||
func main() {
|
||||
var handshake = plugin.HandshakeConfig{
|
||||
handshake := plugin.HandshakeConfig{
|
||||
ProtocolVersion: 1,
|
||||
MagicCookieKey: "CROWDSEC_PLUGIN_KEY",
|
||||
MagicCookieValue: os.Getenv("CROWDSEC_PLUGIN_KEY"),
|
||||
|
|
Loading…
Reference in a new issue