diff --git a/.github/workflows/ci_functests-install.yml b/.github/workflows/ci_functests-install.yml index bc3c097c1..bba9812a1 100644 --- a/.github/workflows/ci_functests-install.yml +++ b/.github/workflows/ci_functests-install.yml @@ -60,6 +60,10 @@ jobs: run: | cd scripts/func_tests/ ./tests_post-install_4cold-logs.sh + - name: "Test simulation" + run: | + cd scripts/func_tests/ + ./tests_post-install_5simulation.sh - name: "Uninstall" run: sudo ./wizard.sh --uninstall - name: "Test post remove" diff --git a/pkg/apiserver/apic.go b/pkg/apiserver/apic.go index e2cac2d45..82397a07e 100644 --- a/pkg/apiserver/apic.go +++ b/pkg/apiserver/apic.go @@ -172,6 +172,11 @@ func (a *apic) Push() error { if alert.ScenarioVersion == nil || *alert.ScenarioVersion == "" || *alert.ScenarioVersion == "?" { continue } + /*we also ignore alerts in simulated mode*/ + if *alert.Simulated { + log.Debugf("simulation enabled for alert (id:%d), will not be sent to CAPI", alert.ID) + continue + } signals = append(signals, AlertToSignal(alert)) } a.mu.Lock() diff --git a/pkg/csconfig/crowdsec_service.go b/pkg/csconfig/crowdsec_service.go index c1ef7e994..582e15c39 100644 --- a/pkg/csconfig/crowdsec_service.go +++ b/pkg/csconfig/crowdsec_service.go @@ -64,6 +64,9 @@ func (c *Config) LoadCrowdsec() error { if c.Crowdsec.AcquisitionDirPath == "" && c.Crowdsec.AcquisitionFilePath == "" { return fmt.Errorf("no acquisition_path nor acquisition_dir") } + if err := c.LoadSimulation(); err != nil { + return errors.Wrap(err, "load error (simulation)") + } c.Crowdsec.ConfigDir = c.ConfigPaths.ConfigDir c.Crowdsec.DataDir = c.ConfigPaths.DataDir diff --git a/pkg/csconfig/crowdsec_service_test.go b/pkg/csconfig/crowdsec_service_test.go index 38ceeffbe..fbb92dcff 100644 --- a/pkg/csconfig/crowdsec_service_test.go +++ b/pkg/csconfig/crowdsec_service_test.go @@ -10,6 +10,7 @@ import ( ) func TestLoadCrowdsec(t *testing.T) { + falseBoolPtr := false acquisFullPath, err := filepath.Abs("./tests/acquis.yaml") if err != nil { t.Fatalf(err.Error()) @@ -66,6 +67,7 @@ func TestLoadCrowdsec(t *testing.T) { }, Crowdsec: &CrowdsecServiceCfg{ AcquisitionFilePath: "./tests/acquis.yaml", + SimulationFilePath: "./tests/simulation.yaml", }, }, expectedResult: &CrowdsecServiceCfg{ @@ -79,6 +81,10 @@ func TestLoadCrowdsec(t *testing.T) { ParserRoutinesCount: 1, OutputRoutinesCount: 1, AcquisitionFiles: []string{acquisFullPath}, + SimulationFilePath: "./tests/simulation.yaml", + SimulationConfig: &SimulationConfig{ + Simulation: &falseBoolPtr, + }, }, }, { @@ -97,6 +103,7 @@ func TestLoadCrowdsec(t *testing.T) { Crowdsec: &CrowdsecServiceCfg{ AcquisitionFilePath: "./tests/acquis.yaml", AcquisitionDirPath: "./tests/acquis/", + SimulationFilePath: "./tests/simulation.yaml", }, }, expectedResult: &CrowdsecServiceCfg{ @@ -110,6 +117,10 @@ func TestLoadCrowdsec(t *testing.T) { ParserRoutinesCount: 1, OutputRoutinesCount: 1, AcquisitionFiles: []string{acquisFullPath, acquisInDirFullPath}, + SimulationFilePath: "./tests/simulation.yaml", + SimulationConfig: &SimulationConfig{ + Simulation: &falseBoolPtr, + }, }, }, { diff --git a/scripts/func_tests/tests_post-install_5simulation.sh b/scripts/func_tests/tests_post-install_5simulation.sh new file mode 100755 index 000000000..01d81a3c3 --- /dev/null +++ b/scripts/func_tests/tests_post-install_5simulation.sh @@ -0,0 +1,47 @@ +#! /usr/bin/env bash +# -*- coding: utf-8 -*- + +source tests_base.sh + +COLLECTION=crowdsecurity/sshd +SCENARIO=crowdsecurity/ssh-bf + +# install sshd collection + +${CSCLI} collections install $COLLECTION +${CSCLI} decisions delete --all +${SYSTEMCTL} reload crowdsec + + +# generate a fake bf log -> cold logs processing +rm -f ssh-bf.log + +for i in `seq 1 10` ; do + echo `date '+%b %d %H:%M:%S '`'sd-126005 sshd[12422]: Invalid user netflix from 1.1.1.174 port 35424' >> ssh-bf.log +done; + +${CROWDSEC} -file ./ssh-bf.log -type syslog -no-api + +${CSCLI} decisions list -o=json | ${JQ} '. | length == 1' || fail "expected exactly one decision" +${CSCLI} decisions list -o=json | ${JQ} '.[].decisions[0].value == "1.1.1.174"' || fail "(exact) expected ban on 1.1.1.174" +${CSCLI} decisions list -o=json | ${JQ} '.[].decisions[0].simulated == false' || fail "(exact) expected simulated on false" + + +# enable simulation on specific scenario and try with same logs + +${CSCLI} decisions delete --all +${CSCLI} simulation enable $SCENARIO + +${CROWDSEC} -file ./ssh-bf.log -type syslog -no-api + +${CSCLI} decisions list --no-simu -o=json | ${JQ} '. == null' || fail "expected no decision (listing only non-simulated decisions)" + +# enable global simulation and try with same logs + +${CSCLI} decisions delete --all +${CSCLI} simulation disable $SCENARIO +${CSCLI} simulation enable --global + +${CROWDSEC} -file ./ssh-bf.log -type syslog -no-api + +${CSCLI} decisions list --no-simu -o=json | ${JQ} '. == null' || fail "expected no decision (listing only non-simulated decisions)" \ No newline at end of file