notification-email: configurable timeouts (#2465)
* configurable timeouts * parse email timeouts as duration string * add helo_host to email.yaml * move html and body tags outside of the loops * added quotes to href=.., and formatting test
This commit is contained in:
parent
b8e6bd8c9a
commit
3cb9dbdb21
7 changed files with 102 additions and 6 deletions
|
@ -15,12 +15,14 @@ timeout: 20s # Time to wait for response from the plugin before conside
|
|||
# The following template receives a list of models.Alert objects
|
||||
# The output goes in the email message body
|
||||
format: |
|
||||
<html><body>
|
||||
{{range . -}}
|
||||
{{$alert := . -}}
|
||||
{{range .Decisions -}}
|
||||
<html><body><p><a href=https://www.whois.com/whois/{{.Value}}>{{.Value}}</a> will get <b>{{.Type}}</b> for next <b>{{.Duration}}</b> for triggering <b>{{.Scenario}}</b> on machine <b>{{$alert.MachineID}}</b>.</p> <p><a href=https://app.crowdsec.net/cti/{{.Value}}>CrowdSec CTI</a></p></body></html>
|
||||
<p><a href="https://www.whois.com/whois/{{.Value}}">{{.Value}}</a> will get <b>{{.Type}}</b> for next <b>{{.Duration}}</b> for triggering <b>{{.Scenario}}</b> on machine <b>{{$alert.MachineID}}</b>.</p> <p><a href="https://app.crowdsec.net/cti/{{.Value}}">CrowdSec CTI</a></p>
|
||||
{{end -}}
|
||||
{{end -}}
|
||||
</body></html>
|
||||
|
||||
smtp_host: # example: smtp.gmail.com
|
||||
smtp_username: # Replace with your actual username
|
||||
|
@ -35,7 +37,15 @@ receiver_emails:
|
|||
# - email2@gmail.com
|
||||
|
||||
# One of "ssltls", "starttls", "none"
|
||||
encryption_type: ssltls
|
||||
encryption_type: "ssltls"
|
||||
|
||||
# If you need to set the HELO hostname:
|
||||
# helo_host: "localhost"
|
||||
|
||||
# If the email server is hitting the default timeouts (10 seconds), you can increase them here
|
||||
#
|
||||
# connect_timeout: 10s
|
||||
# send_timeout: 10s
|
||||
|
||||
---
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/protobufs"
|
||||
"github.com/hashicorp/go-hclog"
|
||||
|
@ -47,6 +48,8 @@ type PluginConfig struct {
|
|||
EncryptionType string `yaml:"encryption_type"`
|
||||
AuthType string `yaml:"auth_type"`
|
||||
HeloHost string `yaml:"helo_host"`
|
||||
ConnectTimeout string `yaml:"connect_timeout"`
|
||||
SendTimeout string `yaml:"send_timeout"`
|
||||
}
|
||||
|
||||
type EmailPlugin struct {
|
||||
|
@ -77,7 +80,7 @@ func (n *EmailPlugin) Configure(ctx context.Context, config *protobufs.Config) (
|
|||
}
|
||||
|
||||
if d.ReceiverEmails == nil || len(d.ReceiverEmails) == 0 {
|
||||
return nil, fmt.Errorf("Receiver emails are not set")
|
||||
return nil, fmt.Errorf("receiver emails are not set")
|
||||
}
|
||||
|
||||
n.ConfigByName[d.Name] = d
|
||||
|
@ -108,6 +111,24 @@ func (n *EmailPlugin) Notify(ctx context.Context, notification *protobufs.Notifi
|
|||
server.Authentication = AuthStringToType[cfg.AuthType]
|
||||
server.Helo = cfg.HeloHost
|
||||
|
||||
var err error
|
||||
|
||||
if cfg.ConnectTimeout != "" {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
if cfg.SendTimeout != "" {
|
||||
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 {
|
||||
|
|
2
go.mod
2
go.mod
|
@ -73,7 +73,7 @@ require (
|
|||
github.com/stretchr/testify v1.8.4
|
||||
github.com/umahmood/haversine v0.0.0-20151105152445-808ab04add26
|
||||
github.com/wasilibs/go-re2 v1.3.0
|
||||
github.com/xhit/go-simple-mail/v2 v2.15.0
|
||||
github.com/xhit/go-simple-mail/v2 v2.16.0
|
||||
golang.org/x/crypto v0.9.0
|
||||
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1
|
||||
golang.org/x/mod v0.11.0
|
||||
|
|
4
go.sum
4
go.sum
|
@ -790,8 +790,8 @@ github.com/xdg/scram v1.0.5/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49
|
|||
github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
||||
github.com/xdg/stringprep v1.0.3 h1:cmL5Enob4W83ti/ZHuZLuKD/xqJfus4fVPwE+/BDm+4=
|
||||
github.com/xdg/stringprep v1.0.3/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
||||
github.com/xhit/go-simple-mail/v2 v2.15.0 h1:qMXeqcZErUW/Dw6EXxmPuxHzVI8MdxWnEnu2xcisohU=
|
||||
github.com/xhit/go-simple-mail/v2 v2.15.0/go.mod h1:b7P5ygho6SYE+VIqpxA6QkYfv4teeyG4MKqB3utRu98=
|
||||
github.com/xhit/go-simple-mail/v2 v2.16.0 h1:ouGy/Ww4kuaqu2E2UrDw7SvLaziWTB60ICLkIkNVccA=
|
||||
github.com/xhit/go-simple-mail/v2 v2.16.0/go.mod h1:b7P5ygho6SYE+VIqpxA6QkYfv4teeyG4MKqB3utRu98=
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
|
|
65
test/bats/73_plugin_formatting.bats
Normal file
65
test/bats/73_plugin_formatting.bats
Normal file
|
@ -0,0 +1,65 @@
|
|||
#!/usr/bin/env bats
|
||||
# vim: ft=bats:list:ts=8:sts=4:sw=4:et:ai:si:
|
||||
|
||||
set -u
|
||||
|
||||
setup_file() {
|
||||
load "../lib/setup_file.sh"
|
||||
is_package_testing && return
|
||||
|
||||
./instance-data load
|
||||
|
||||
tempfile=$(TMPDIR="${BATS_FILE_TMPDIR}" mktemp)
|
||||
export tempfile
|
||||
|
||||
DUMMY_YAML="$(config_get '.config_paths.notification_dir')/dummy.yaml"
|
||||
|
||||
# we test the template that is suggested in the email notification
|
||||
# the $alert is not a shell variable
|
||||
# shellcheck disable=SC2016
|
||||
config_set "${DUMMY_YAML}" '
|
||||
.group_wait="5s" |
|
||||
.group_threshold=2 |
|
||||
.output_file=strenv(tempfile) |
|
||||
.format="<html><body> {{range . -}} {{$alert := . -}} {{range .Decisions -}} <p><a href=\"https://www.whois.com/whois/{{.Value}}\">{{.Value}}</a> will get <b>{{.Type}}</b> for next <b>{{.Duration}}</b> for triggering <b>{{.Scenario}}</b> on machine <b>{{$alert.MachineID}}</b>.</p> <p><a href=\"https://app.crowdsec.net/cti/{{.Value}}\">CrowdSec CTI</a></p> {{end -}} {{end -}} </body></html>"
|
||||
'
|
||||
|
||||
config_set "$(config_get '.api.server.profiles_path')" '
|
||||
.notifications=["dummy_default"] |
|
||||
.filters=["Alert.GetScope() == \"Ip\""]
|
||||
'
|
||||
|
||||
config_set '
|
||||
.plugin_config.user="" |
|
||||
.plugin_config.group=""
|
||||
'
|
||||
|
||||
./instance-crowdsec start
|
||||
}
|
||||
|
||||
teardown_file() {
|
||||
load "../lib/teardown_file.sh"
|
||||
}
|
||||
|
||||
setup() {
|
||||
is_package_testing && skip
|
||||
load "../lib/setup.sh"
|
||||
}
|
||||
|
||||
#----------
|
||||
|
||||
@test "add two bans" {
|
||||
rune -0 cscli decisions add --ip 1.2.3.4 --duration 30s
|
||||
assert_stderr --partial 'Decision successfully added'
|
||||
|
||||
rune -0 cscli decisions add --ip 1.2.3.5 --duration 30s
|
||||
assert_stderr --partial 'Decision successfully added'
|
||||
sleep 2
|
||||
}
|
||||
|
||||
@test "expected 1 notification" {
|
||||
rune -0 cat "${tempfile}"
|
||||
assert_output - <<-EOT
|
||||
<html><body> <p><a href="https://www.whois.com/whois/1.2.3.4">1.2.3.4</a> will get <b>ban</b> for next <b>30s</b> for triggering <b>manual 'ban' from 'githubciXXXXXXXXXXXXXXXXXXXXXXXX'</b> on machine <b>githubciXXXXXXXXXXXXXXXXXXXXXXXX</b>.</p> <p><a href="https://app.crowdsec.net/cti/1.2.3.4">CrowdSec CTI</a></p> <p><a href="https://www.whois.com/whois/1.2.3.5">1.2.3.5</a> will get <b>ban</b> for next <b>30s</b> for triggering <b>manual 'ban' from 'githubciXXXXXXXXXXXXXXXXXXXXXXXX'</b> on machine <b>githubciXXXXXXXXXXXXXXXXXXXXXXXX</b>.</p> <p><a href="https://app.crowdsec.net/cti/1.2.3.5">CrowdSec CTI</a></p> </body></html>
|
||||
EOT
|
||||
}
|
Loading…
Reference in a new issue