Merge branch 'master' into coraza_poc_acquis

This commit is contained in:
Thibault "bui" Koechlin 2023-06-06 18:23:59 +02:00 committed by GitHub
commit ee8b31348b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
217 changed files with 3347 additions and 3447 deletions
.dockerignore
.github
.gitignoreDockerfileDockerfile.debianMakefileazure-pipelines.yml
cmd
config
debian
docker
go.modgo.sum
mk
pkg

View file

@ -3,3 +3,4 @@
#.git
/tests
/crowdsec-v*

10
.github/codecov.yml vendored Normal file
View file

@ -0,0 +1,10 @@
# we measure coverage but don't enforce it
# https://docs.codecov.com/docs/codecov-yaml
coverage:
status:
patch:
default:
target: 0%
project:
default:
target: 0%

View file

@ -15,7 +15,7 @@ jobs:
build:
strategy:
matrix:
go-version: ["1.20.3"]
go-version: ["1.20.4"]
name: "Build + tests"
runs-on: ubuntu-latest

View file

@ -14,7 +14,7 @@ jobs:
build:
strategy:
matrix:
go-version: ["1.20.3"]
go-version: ["1.20.4"]
name: "Build + tests"
runs-on: ubuntu-latest

View file

@ -10,7 +10,7 @@ jobs:
build:
strategy:
matrix:
go-version: ["1.20.3"]
go-version: ["1.20.4"]
name: "Build + tests"
runs-on: ubuntu-latest
@ -86,24 +86,6 @@ jobs:
PGPASSWORD: "secret"
PGUSER: postgres
# - name: "Build crowdsec and fixture (DB_BACKEND: postgres)"
# run: make clean bats-build bats-fixture
# env:
# DB_BACKEND: postgres
# PGHOST: 127.0.0.1
# PGPORT: 5432
# PGPASSWORD: "secret"
# PGUSER: postgres
#
# - name: "Run tests (DB_BACKEND: postgres)"
# run: make bats-test
# env:
# DB_BACKEND: postgres
# PGHOST: 127.0.0.1
# PGPORT: 5432
# PGPASSWORD: "secret"
# PGUSER: postgres
- name: "Show stack traces"
run: for file in $(find /tmp/crowdsec-crash.*.txt); do echo ">>>>> $file"; cat $file; echo; done
if: ${{ always() }}

View file

@ -11,7 +11,7 @@ jobs:
build:
strategy:
matrix:
go-version: ["1.20.3"]
go-version: ["1.20.4"]
name: "Build + tests"
runs-on: ubuntu-latest
@ -72,7 +72,6 @@ jobs:
-e '/plugins/notifications' \
-e '/pkg/protobufs' \
-e '/pkg/cwversions' \
-e '/pkg/cstest' \
-e '/pkg/models' \
< coverage-bats-raw.out \
> coverage-bats.out

View file

@ -23,7 +23,7 @@ jobs:
build:
strategy:
matrix:
go-version: ["1.20.3"]
go-version: ["1.20.4"]
name: Build
runs-on: windows-2019

View file

@ -22,7 +22,7 @@ jobs:
build:
strategy:
matrix:
go-version: ["1.20.3"]
go-version: ["1.20.4"]
name: "Build + tests"
runs-on: windows-2022

View file

@ -34,7 +34,7 @@ jobs:
build:
strategy:
matrix:
go-version: ["1.20.3"]
go-version: ["1.20.4"]
name: "Build + tests"
runs-on: ubuntu-latest

View file

@ -0,0 +1,70 @@
name: Publish Debian Docker image on Push to Master
on:
push:
branches: [ master ]
paths:
- 'pkg/**'
- 'cmd/**'
- 'plugins/**'
- 'docker/docker_start.sh'
- 'docker/config.yaml'
- '.github/workflows/publish_docker-image_on_master-debian.yml'
- 'Dockerfile.debian'
- 'go.mod'
- 'go.sum'
- 'Makefile'
jobs:
push_to_registry:
name: Push Debian Docker image to Docker Hub
runs-on: ubuntu-latest
steps:
- name: Check out the repo
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Prepare
id: prep
run: |
DOCKER_IMAGE=crowdsecurity/crowdsec
GHCR_IMAGE=ghcr.io/${{ github.repository_owner }}/crowdsec
VERSION=dev-debian
TAGS="${DOCKER_IMAGE}:${VERSION},${GHCR_IMAGE}:${VERSION}"
echo "tags=${TAGS}" >> $GITHUB_OUTPUT
echo "created=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
config: .github/buildkit.toml
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push full image
uses: docker/build-push-action@v4
with:
context: .
file: ./Dockerfile.debian
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.prep.outputs.tags }}
platforms: linux/amd64
labels: |
org.opencontainers.image.source=${{ github.event.repository.html_url }}
org.opencontainers.image.created=${{ steps.prep.outputs.created }}
org.opencontainers.image.revision=${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=min

View file

@ -6,11 +6,15 @@ on:
types:
- prereleased
permissions:
# Use write for: hub release edit
contents: write
jobs:
build:
strategy:
matrix:
go-version: ["1.20.3"]
go-version: ["1.20.4"]
name: Build and upload binary package
runs-on: ubuntu-latest
@ -43,8 +47,8 @@ jobs:
run: make release
- name: Upload to release
uses: JasonEtco/upload-to-release@master
with:
args: crowdsec-release.tgz application/x-gzip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
tag_name="${GITHUB_REF##*/}"
hub release edit -a crowdsec-release.tgz -m "" "$tag_name"

View file

@ -29,7 +29,7 @@ jobs:
VERSION=pr-${{ github.event.number }}
fi
TAGS="${DOCKER_IMAGE}:${VERSION}-debian"
if [[ ${{ github.event.action }} == released ]]; then
if [[ "${{ github.event.action }}" == "released" ]]; then
TAGS=$TAGS,${DOCKER_IMAGE}:latest-debian
fi
echo "version=${VERSION}" >> $GITHUB_OUTPUT
@ -54,7 +54,7 @@ jobs:
file: ./Dockerfile.debian
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.prep.outputs.tags }}
platforms: linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6,linux/386
platforms: linux/amd64,linux/arm64,linux/386
labels: |
org.opencontainers.image.source=${{ github.event.repository.html_url }}
org.opencontainers.image.created=${{ steps.prep.outputs.created }}

7
.gitignore vendored
View file

@ -8,10 +8,17 @@
.pc
.vscode
# If vendor is included, allow prebuilt (wasm?) libraries.
!vendor/**/*.so
# Test binaries, built with `go test -c`
*.test
*.cover
# VMs used for dev/test
.vagrant
# Test binaries, built from *_test.go
pkg/csplugin/tests/cs_plugin_test*

View file

@ -1,5 +1,5 @@
# vim: set ft=dockerfile:
ARG GOVERSION=1.20.3
ARG GOVERSION=1.20.4
FROM golang:${GOVERSION}-alpine AS build
@ -7,9 +7,19 @@ WORKDIR /go/src/crowdsec
COPY . .
# Alpine does not ship a static version of re2, we can build it ourselves
# Later versions require 'abseil', which is likewise not available in its static form
ENV RE2_VERSION=2023-03-01
# wizard.sh requires GNU coreutils
RUN apk add --no-cache git gcc libc-dev make bash gettext binutils-gold coreutils && \
RUN apk add --no-cache git g++ gcc libc-dev make bash gettext binutils-gold coreutils icu-static re2-dev pkgconfig && \
wget https://github.com/google/re2/archive/refs/tags/${RE2_VERSION}.tar.gz && \
tar -xzf ${RE2_VERSION}.tar.gz && \
cd re2-${RE2_VERSION} && \
make && \
make install && \
echo "githubciXXXXXXXXXXXXXXXXXXXXXXXX" > /etc/machine-id && \
cd - && \
make clean release DOCKER_BUILD=1 && \
cd crowdsec-v* && \
./wizard.sh --docker-mode && \

View file

@ -1,5 +1,5 @@
# vim: set ft=dockerfile:
ARG GOVERSION=1.20.3
ARG GOVERSION=1.20.4
FROM golang:${GOVERSION}-bullseye AS build
@ -12,7 +12,7 @@ ENV DEBCONF_NOWARNINGS="yes"
# wizard.sh requires GNU coreutils
RUN apt-get update && \
apt-get install -y -q git gcc libc-dev make bash gettext binutils-gold coreutils tzdata && \
apt-get install -y -q git gcc libc-dev make bash gettext binutils-gold coreutils tzdata libre2-dev && \
echo "githubciXXXXXXXXXXXXXXXXXXXXXXXX" > /etc/machine-id && \
make clean release DOCKER_BUILD=1 && \
cd crowdsec-v* && \
@ -44,6 +44,9 @@ RUN apt-get update && \
mkdir -p /staging/var/lib/crowdsec && \
mkdir -p /var/lib/crowdsec/data
RUN echo "deb http://deb.debian.org/debian bullseye-backports main" >> /etc/apt/sources.list \
&& apt-get update && apt-get install -t bullseye-backports -y libsystemd0
COPY --from=build /go/bin/yq /usr/local/bin/yq
COPY --from=build /etc/crowdsec /staging/etc/crowdsec
COPY --from=build /usr/local/bin/crowdsec /usr/local/bin/crowdsec

147
Makefile
View file

@ -1,36 +1,42 @@
include mk/platform.mk
BUILD_REQUIRE_GO_MAJOR ?= 1
BUILD_REQUIRE_GO_MINOR ?= 20
GOCMD = go
GOTEST = $(GOCMD) test
BUILD_CODENAME ?= alphaga
CROWDSEC_FOLDER = ./cmd/crowdsec
CSCLI_FOLDER = ./cmd/crowdsec-cli/
HTTP_PLUGIN_FOLDER = ./plugins/notifications/http
SLACK_PLUGIN_FOLDER = ./plugins/notifications/slack
SPLUNK_PLUGIN_FOLDER = ./plugins/notifications/splunk
EMAIL_PLUGIN_FOLDER = ./plugins/notifications/email
DUMMY_PLUGIN_FOLDER = ./plugins/notifications/dummy
HTTP_PLUGIN_BIN = notification-http$(EXT)
SLACK_PLUGIN_BIN = notification-slack$(EXT)
SPLUNK_PLUGIN_BIN = notification-splunk$(EXT)
EMAIL_PLUGIN_BIN = notification-email$(EXT)
DUMMY_PLUGIN_BIN= notification-dummy$(EXT)
HTTP_PLUGIN_CONFIG = http.yaml
SLACK_PLUGIN_CONFIG = slack.yaml
SPLUNK_PLUGIN_CONFIG = splunk.yaml
EMAIL_PLUGIN_CONFIG = email.yaml
PLUGINS ?= $(patsubst ./plugins/notifications/%,%,$(wildcard ./plugins/notifications/*))
PLUGINS_DIR = ./plugins/notifications
CROWDSEC_BIN = crowdsec$(EXT)
CSCLI_BIN = cscli$(EXT)
BUILD_CMD = build
# Directory for the release files
RELDIR = crowdsec-$(BUILD_VERSION)
GO_MODULE_NAME = github.com/crowdsecurity/crowdsec
# see if we have libre2-dev installed for C++ optimizations
RE2_CHECK := $(shell pkg-config --libs re2 2>/dev/null)
#--------------------------------------
#
# Define MAKE_FLAGS and LD_OPTS for the sub-makefiles in cmd/ and plugins/
#
MAKE_FLAGS = --no-print-directory GOARCH=$(GOARCH) GOOS=$(GOOS) RM="$(RM)" WIN_IGNORE_ERR="$(WIN_IGNORE_ERR)" CP="$(CP)" CPR="$(CPR)" MKDIR="$(MKDIR)"
LD_OPTS_VARS= \
-X '$(GO_MODULE_NAME)/pkg/cwversion.Version=$(BUILD_VERSION)' \
-X '$(GO_MODULE_NAME)/pkg/cwversion.BuildDate=$(BUILD_TIMESTAMP)' \
-X 'github.com/crowdsecurity/go-cs-lib/pkg/version.Version=$(BUILD_VERSION)' \
-X 'github.com/crowdsecurity/go-cs-lib/pkg/version.BuildDate=$(BUILD_TIMESTAMP)' \
-X 'github.com/crowdsecurity/go-cs-lib/pkg/version.Tag=$(BUILD_TAG)' \
-X '$(GO_MODULE_NAME)/pkg/cwversion.Codename=$(BUILD_CODENAME)' \
-X '$(GO_MODULE_NAME)/pkg/cwversion.Tag=$(BUILD_TAG)' \
-X '$(GO_MODULE_NAME)/pkg/csconfig.defaultConfigDir=$(DEFAULT_CONFIGDIR)' \
-X '$(GO_MODULE_NAME)/pkg/csconfig.defaultDataDir=$(DEFAULT_DATADIR)'
@ -38,66 +44,67 @@ ifneq (,$(DOCKER_BUILD))
LD_OPTS_VARS += -X '$(GO_MODULE_NAME)/pkg/cwversion.System=docker'
endif
ifdef BUILD_STATIC
$(warning WARNING: The BUILD_STATIC variable is deprecated and has no effect. Builds are static by default since v1.5.0.)
GO_TAGS := netgo,osusergo,sqlite_omit_load_extension
ifneq (,$(RE2_CHECK))
# += adds a space that we don't want
GO_TAGS := $(GO_TAGS),re2_cgo
LD_OPTS_VARS += -X '$(GO_MODULE_NAME)/pkg/cwversion.Libre2=C++'
endif
export LD_OPTS=-ldflags "-s -w -extldflags '-static' $(LD_OPTS_VARS)" \
-trimpath -tags netgo,osusergo,sqlite_omit_load_extension
-trimpath -tags $(GO_TAGS)
ifneq (,$(TEST_COVERAGE))
LD_OPTS += -cover
endif
GOCMD = go
GOTEST = $(GOCMD) test
RELDIR = crowdsec-$(BUILD_VERSION)
#--------------------------------------
.PHONY: build
build: goversion crowdsec cscli plugins
build: pre-build goversion crowdsec cscli plugins
.PHONY: pre-build
pre-build:
ifdef BUILD_STATIC
$(warning WARNING: The BUILD_STATIC variable is deprecated and has no effect. Builds are static by default since v1.5.0.)
endif
$(info Building $(BUILD_VERSION) ($(BUILD_TAG)) for $(GOOS)/$(GOARCH))
ifneq (,$(RE2_CHECK))
$(info Using C++ regexp library)
else
$(info Fallback to WebAssembly regexp library. To use the C++ version, make sure you have installed libre2-dev and pkg-config.)
endif
$(info )
.PHONY: all
all: clean test build
.PHONY: plugins
plugins: http-plugin slack-plugin splunk-plugin email-plugin dummy-plugin
plugins:
@$(foreach plugin,$(PLUGINS), \
$(MAKE) -C $(PLUGINS_DIR)/$(plugin) build $(MAKE_FLAGS); \
)
.PHONY: clean
clean: testclean
@$(MAKE) -C $(CROWDSEC_FOLDER) clean --no-print-directory RM="$(RM)" WIN_IGNORE_ERR="$(WIN_IGNORE_ERR)" CP="$(CP)" CPR="$(CPR)" MKDIR="$(MKDIR)"
@$(MAKE) -C $(CSCLI_FOLDER) clean --no-print-directory RM="$(RM)" WIN_IGNORE_ERR="$(WIN_IGNORE_ERR)" CP="$(CP)" CPR="$(CPR)" MKDIR="$(MKDIR)"
@$(MAKE) -C $(CROWDSEC_FOLDER) clean $(MAKE_FLAGS)
@$(MAKE) -C $(CSCLI_FOLDER) clean $(MAKE_FLAGS)
@$(RM) $(CROWDSEC_BIN) $(WIN_IGNORE_ERR)
@$(RM) $(CSCLI_BIN) $(WIN_IGNORE_ERR)
@$(RM) *.log $(WIN_IGNORE_ERR)
@$(RM) crowdsec-release.tgz $(WIN_IGNORE_ERR)
@$(RM) $(HTTP_PLUGIN_FOLDER)/$(HTTP_PLUGIN_BIN) $(WIN_IGNORE_ERR)
@$(RM) $(SLACK_PLUGIN_FOLDER)/$(SLACK_PLUGIN_BIN) $(WIN_IGNORE_ERR)
@$(RM) $(SPLUNK_PLUGIN_FOLDER)/$(SPLUNK_PLUGIN_BIN) $(WIN_IGNORE_ERR)
@$(RM) $(EMAIL_PLUGIN_FOLDER)/$(EMAIL_PLUGIN_BIN) $(WIN_IGNORE_ERR)
@$(RM) $(DUMMY_PLUGIN_FOLDER)/$(DUMMY_PLUGIN_BIN) $(WIN_IGNORE_ERR)
@$(foreach plugin,$(PLUGINS), \
$(MAKE) -C $(PLUGINS_DIR)/$(plugin) clean $(MAKE_FLAGS); \
)
.PHONY: cscli
cscli: goversion
@$(MAKE) -C $(CSCLI_FOLDER) build --no-print-directory GOARCH=$(GOARCH) GOOS=$(GOOS) RM="$(RM)" WIN_IGNORE_ERR="$(WIN_IGNORE_ERR)" CP="$(CP)" CPR="$(CPR)" MKDIR="$(MKDIR)"
@$(MAKE) -C $(CSCLI_FOLDER) build $(MAKE_FLAGS)
.PHONY: crowdsec
crowdsec: goversion
@$(MAKE) -C $(CROWDSEC_FOLDER) build --no-print-directory GOARCH=$(GOARCH) GOOS=$(GOOS) RM="$(RM)" WIN_IGNORE_ERR="$(WIN_IGNORE_ERR)" CP="$(CP)" CPR="$(CPR)" MKDIR="$(MKDIR)"
http-plugin: goversion
@$(MAKE) -C $(HTTP_PLUGIN_FOLDER) build --no-print-directory GOARCH=$(GOARCH) GOOS=$(GOOS) RM="$(RM)" WIN_IGNORE_ERR="$(WIN_IGNORE_ERR)" CP="$(CP)" CPR="$(CPR)" MKDIR="$(MKDIR)"
slack-plugin: goversion
@$(MAKE) -C $(SLACK_PLUGIN_FOLDER) build --no-print-directory GOARCH=$(GOARCH) GOOS=$(GOOS) RM="$(RM)" WIN_IGNORE_ERR="$(WIN_IGNORE_ERR)" CP="$(CP)" CPR="$(CPR)" MKDIR="$(MKDIR)"
splunk-plugin: goversion
@$(MAKE) -C $(SPLUNK_PLUGIN_FOLDER) build --no-print-directory GOARCH=$(GOARCH) GOOS=$(GOOS) RM="$(RM)" WIN_IGNORE_ERR="$(WIN_IGNORE_ERR)" WIN_IGNORE_ERR="$(WIN_IGNORE_ERR)" CP="$(CP)" CPR="$(CPR)" MKDIR="$(MKDIR)"
email-plugin: goversion
@$(MAKE) -C $(EMAIL_PLUGIN_FOLDER) build --no-print-directory GOARCH=$(GOARCH) GOOS=$(GOOS) RM="$(RM)" WIN_IGNORE_ERR="$(WIN_IGNORE_ERR)" CP="$(CP)" CPR="$(CPR)" MKDIR="$(MKDIR)"
dummy-plugin: goversion
$(MAKE) -C $(DUMMY_PLUGIN_FOLDER) build --no-print-directory GOARCH=$(GOARCH) GOOS=$(GOOS) RM="$(RM)" WIN_IGNORE_ERR="$(WIN_IGNORE_ERR)" CP="$(CP)" CPR="$(CPR)" MKDIR="$(MKDIR)"
@$(MAKE) -C $(CROWDSEC_FOLDER) build $(MAKE_FLAGS)
.PHONY: testclean
testclean: bats-clean
@ -130,35 +137,33 @@ localstack:
localstack-stop:
docker-compose -f test/localstack/docker-compose.yml down
package-common:
.PHONY: vendor
vendor:
@echo "Vendoring dependencies"
@$(GOCMD) mod vendor
@$(foreach plugin,$(PLUGINS), \
$(MAKE) -C $(PLUGINS_DIR)/$(plugin) vendor $(MAKE_FLAGS); \
)
.PHONY: package
package:
@echo "Building Release to dir $(RELDIR)"
@$(MKDIR) $(RELDIR)/cmd/crowdsec
@$(MKDIR) $(RELDIR)/cmd/crowdsec-cli
@$(MKDIR) $(RELDIR)/$(subst ./,,$(HTTP_PLUGIN_FOLDER))
@$(MKDIR) $(RELDIR)/$(subst ./,,$(SLACK_PLUGIN_FOLDER))
@$(MKDIR) $(RELDIR)/$(subst ./,,$(SPLUNK_PLUGIN_FOLDER))
@$(MKDIR) $(RELDIR)/$(subst ./,,$(EMAIL_PLUGIN_FOLDER))
@$(CP) $(CROWDSEC_FOLDER)/$(CROWDSEC_BIN) $(RELDIR)/cmd/crowdsec
@$(CP) $(CSCLI_FOLDER)/$(CSCLI_BIN) $(RELDIR)/cmd/crowdsec-cli
@$(CP) $(HTTP_PLUGIN_FOLDER)/$(HTTP_PLUGIN_BIN) $(RELDIR)/$(subst ./,,$(HTTP_PLUGIN_FOLDER))
@$(CP) $(SLACK_PLUGIN_FOLDER)/$(SLACK_PLUGIN_BIN) $(RELDIR)/$(subst ./,,$(SLACK_PLUGIN_FOLDER))
@$(CP) $(SPLUNK_PLUGIN_FOLDER)/$(SPLUNK_PLUGIN_BIN) $(RELDIR)/$(subst ./,,$(SPLUNK_PLUGIN_FOLDER))
@$(CP) $(EMAIL_PLUGIN_FOLDER)/$(EMAIL_PLUGIN_BIN) $(RELDIR)/$(subst ./,,$(EMAIL_PLUGIN_FOLDER))
@$(CP) $(HTTP_PLUGIN_FOLDER)/$(HTTP_PLUGIN_CONFIG) $(RELDIR)/$(subst ./,,$(HTTP_PLUGIN_FOLDER))
@$(CP) $(SLACK_PLUGIN_FOLDER)/$(SLACK_PLUGIN_CONFIG) $(RELDIR)/$(subst ./,,$(SLACK_PLUGIN_FOLDER))
@$(CP) $(SPLUNK_PLUGIN_FOLDER)/$(SPLUNK_PLUGIN_CONFIG) $(RELDIR)/$(subst ./,,$(SPLUNK_PLUGIN_FOLDER))
@$(CP) $(EMAIL_PLUGIN_FOLDER)/$(EMAIL_PLUGIN_CONFIG) $(RELDIR)/$(subst ./,,$(EMAIL_PLUGIN_FOLDER))
@$(foreach plugin,$(PLUGINS), \
$(MKDIR) $(RELDIR)/$(PLUGINS_DIR)/$(plugin); \
$(CP) $(PLUGINS_DIR)/$(plugin)/notification-$(plugin)$(EXT) $(RELDIR)/$(PLUGINS_DIR)/$(plugin); \
$(CP) $(PLUGINS_DIR)/$(plugin)/$(plugin).yaml $(RELDIR)/$(PLUGINS_DIR)/$(plugin)/; \
)
@$(CPR) ./config $(RELDIR)
@$(CP) wizard.sh $(RELDIR)
@$(CP) scripts/test_env.sh $(RELDIR)
@$(CP) scripts/test_env.ps1 $(RELDIR)
.PHONY: package
package: package-common
@tar cvzf crowdsec-release.tgz $(RELDIR)
.PHONY: check_release

View file

@ -27,7 +27,7 @@ stages:
- task: GoTool@0
displayName: "Install Go 1.20"
inputs:
version: '1.20.3'
version: '1.20.4'
- pwsh: |
choco install -y make

View file

@ -7,9 +7,7 @@ endif
# Go parameters
GOCMD = go
GOBUILD = $(GOCMD) build
GOCLEAN = $(GOCMD) clean
GOTEST = $(GOCMD) test
GOGET = $(GOCMD) get
BINARY_NAME = cscli$(EXT)
PREFIX ?= "/"

View file

@ -20,8 +20,9 @@ import (
"github.com/spf13/cobra"
"gopkg.in/yaml.v2"
"github.com/crowdsecurity/go-cs-lib/pkg/version"
"github.com/crowdsecurity/crowdsec/pkg/apiclient"
"github.com/crowdsecurity/crowdsec/pkg/cwversion"
"github.com/crowdsecurity/crowdsec/pkg/database"
"github.com/crowdsecurity/crowdsec/pkg/models"
"github.com/crowdsecurity/crowdsec/pkg/types"
@ -219,7 +220,7 @@ func NewAlertsCmd() *cobra.Command {
Client, err = apiclient.NewClient(&apiclient.Config{
MachineID: csConfig.API.Client.Credentials.Login,
Password: strfmt.Password(csConfig.API.Client.Credentials.Password),
UserAgent: fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
UserAgent: fmt.Sprintf("crowdsec/%s", version.String()),
URL: apiURL,
VersionPrefix: "v1",
})

View file

@ -11,6 +11,7 @@ import (
"github.com/fatih/color"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"golang.org/x/exp/slices"
middlewares "github.com/crowdsecurity/crowdsec/pkg/apiserver/middlewares/v1"
"github.com/crowdsecurity/crowdsec/pkg/database"
@ -122,7 +123,6 @@ func runBouncersAdd(cmd *cobra.Command, args []string) error {
return nil
}
func NewBouncersAddCmd() *cobra.Command {
cmdBouncersAdd := &cobra.Command{
Use: "add MyBouncerName [--length 16]",
@ -133,7 +133,7 @@ cscli bouncers add MyBouncerName -l 24
cscli bouncers add MyBouncerName -k <random-key>`,
Args: cobra.ExactArgs(1),
DisableAutoGenTag: true,
RunE: runBouncersAdd,
RunE: runBouncersAdd,
}
flags := cmdBouncersAdd.Flags()
@ -144,7 +144,6 @@ cscli bouncers add MyBouncerName -k <random-key>`,
return cmdBouncersAdd
}
func runBouncersDelete(cmd *cobra.Command, args []string) error {
for _, bouncerID := range args {
err := dbClient.DeleteBouncer(bouncerID)
@ -157,7 +156,6 @@ func runBouncersDelete(cmd *cobra.Command, args []string) error {
return nil
}
func NewBouncersDeleteCmd() *cobra.Command {
cmdBouncersDelete := &cobra.Command{
Use: "delete MyBouncerName",
@ -178,7 +176,7 @@ func NewBouncersDeleteCmd() *cobra.Command {
}
ret := make([]string, 0)
for _, bouncer := range bouncers {
if strings.Contains(bouncer.Name, toComplete) && !inSlice(bouncer.Name, args) {
if strings.Contains(bouncer.Name, toComplete) && !slices.Contains(args, bouncer.Name) {
ret = append(ret, bouncer.Name)
}
}

View file

@ -6,10 +6,11 @@ import (
"net/url"
"os"
"github.com/crowdsecurity/go-cs-lib/pkg/version"
"github.com/crowdsecurity/crowdsec/pkg/apiclient"
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
"github.com/crowdsecurity/crowdsec/pkg/cwversion"
"github.com/crowdsecurity/crowdsec/pkg/fflag"
"github.com/crowdsecurity/crowdsec/pkg/models"
"github.com/crowdsecurity/crowdsec/pkg/types"
@ -70,7 +71,7 @@ func NewCapiRegisterCmd() *cobra.Command {
_, err = apiclient.RegisterClient(&apiclient.Config{
MachineID: capiUser,
Password: password,
UserAgent: fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
UserAgent: fmt.Sprintf("crowdsec/%s", version.String()),
URL: apiurl,
VersionPrefix: CAPIURLPrefix,
}, nil)
@ -164,7 +165,7 @@ func NewCapiStatusCmd() *cobra.Command {
log.Fatalf("no scenarios installed, abort")
}
Client, err = apiclient.NewDefaultClient(apiurl, CAPIURLPrefix, fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()), nil)
Client, err = apiclient.NewDefaultClient(apiurl, CAPIURLPrefix, fmt.Sprintf("crowdsec/%s", version.String()), nil)
if err != nil {
log.Fatalf("init default client: %s", err)
}

View file

@ -13,6 +13,7 @@ func NewConfigCmd() *cobra.Command {
}
cmdConfig.AddCommand(NewConfigShowCmd())
cmdConfig.AddCommand(NewConfigShowYAMLCmd())
cmdConfig.AddCommand(NewConfigBackupCmd())
cmdConfig.AddCommand(NewConfigRestoreCmd())
cmdConfig.AddCommand(NewConfigFeatureFlagsCmd())

View file

@ -0,0 +1,24 @@
package main
import (
"fmt"
"github.com/spf13/cobra"
)
func runConfigShowYAML(cmd *cobra.Command, args []string) error {
fmt.Println(mergedConfig)
return nil
}
func NewConfigShowYAMLCmd() *cobra.Command {
cmdConfigShow := &cobra.Command{
Use: "show-yaml",
Short: "Displays merged config.yaml + config.yaml.local",
Args: cobra.ExactArgs(0),
DisableAutoGenTag: true,
RunE: runConfigShowYAML,
}
return cmdConfigShow
}

View file

@ -16,10 +16,12 @@ import (
"github.com/spf13/cobra"
"gopkg.in/yaml.v3"
"github.com/crowdsecurity/go-cs-lib/pkg/ptr"
"github.com/crowdsecurity/go-cs-lib/pkg/version"
"github.com/crowdsecurity/crowdsec/pkg/apiclient"
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
"github.com/crowdsecurity/crowdsec/pkg/cwversion"
"github.com/crowdsecurity/crowdsec/pkg/fflag"
"github.com/crowdsecurity/crowdsec/pkg/types"
)
@ -101,7 +103,7 @@ After running this command your will need to validate the enrollment in the weba
MachineID: csConfig.API.Server.OnlineClient.Credentials.Login,
Password: password,
Scenarios: scenarios,
UserAgent: fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
UserAgent: fmt.Sprintf("crowdsec/%s", version.String()),
URL: apiURL,
VersionPrefix: "v3",
})
@ -249,7 +251,7 @@ func SetConsoleOpts(args []string, wanted bool) {
}
} else {
log.Infof("%s set to %t", csconfig.CONSOLE_MANAGEMENT, wanted)
csConfig.API.Server.ConsoleConfig.ConsoleManagement = types.BoolPtr(wanted)
csConfig.API.Server.ConsoleConfig.ConsoleManagement = ptr.Of(wanted)
}
if csConfig.API.Server.OnlineClient.Credentials != nil {
changed := false
@ -283,7 +285,7 @@ func SetConsoleOpts(args []string, wanted bool) {
}
} else {
log.Infof("%s set to %t", csconfig.SEND_CUSTOM_SCENARIOS, wanted)
csConfig.API.Server.ConsoleConfig.ShareCustomScenarios = types.BoolPtr(wanted)
csConfig.API.Server.ConsoleConfig.ShareCustomScenarios = ptr.Of(wanted)
}
case csconfig.SEND_TAINTED_SCENARIOS:
/*for each flag check if it's already set before setting it*/
@ -296,7 +298,7 @@ func SetConsoleOpts(args []string, wanted bool) {
}
} else {
log.Infof("%s set to %t", csconfig.SEND_TAINTED_SCENARIOS, wanted)
csConfig.API.Server.ConsoleConfig.ShareTaintedScenarios = types.BoolPtr(wanted)
csConfig.API.Server.ConsoleConfig.ShareTaintedScenarios = ptr.Of(wanted)
}
case csconfig.SEND_MANUAL_SCENARIOS:
/*for each flag check if it's already set before setting it*/
@ -309,7 +311,7 @@ func SetConsoleOpts(args []string, wanted bool) {
}
} else {
log.Infof("%s set to %t", csconfig.SEND_MANUAL_SCENARIOS, wanted)
csConfig.API.Server.ConsoleConfig.ShareManualDecisions = types.BoolPtr(wanted)
csConfig.API.Server.ConsoleConfig.ShareManualDecisions = ptr.Of(wanted)
}
case csconfig.SEND_CONTEXT:
/*for each flag check if it's already set before setting it*/
@ -322,7 +324,7 @@ func SetConsoleOpts(args []string, wanted bool) {
}
} else {
log.Infof("%s set to %t", csconfig.SEND_CONTEXT, wanted)
csConfig.API.Server.ConsoleConfig.ShareContext = types.BoolPtr(wanted)
csConfig.API.Server.ConsoleConfig.ShareContext = ptr.Of(wanted)
}
default:
log.Fatalf("unknown flag %s", arg)

View file

@ -19,8 +19,10 @@ import (
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/crowdsecurity/go-cs-lib/pkg/ptr"
"github.com/crowdsecurity/go-cs-lib/pkg/version"
"github.com/crowdsecurity/crowdsec/pkg/apiclient"
"github.com/crowdsecurity/crowdsec/pkg/cwversion"
"github.com/crowdsecurity/crowdsec/pkg/models"
"github.com/crowdsecurity/crowdsec/pkg/types"
)
@ -120,7 +122,7 @@ func NewDecisionsCmd() *cobra.Command {
Client, err = apiclient.NewClient(&apiclient.Config{
MachineID: csConfig.API.Client.Credentials.Login,
Password: password,
UserAgent: fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
UserAgent: fmt.Sprintf("crowdsec/%s", version.String()),
URL: apiurl,
VersionPrefix: "v1",
})
@ -488,6 +490,7 @@ func NewDecisionsImportCmd() *cobra.Command {
importReason string
importType string
importFile string
batchSize int
)
var cmdDecisionImport = &cobra.Command{
@ -578,37 +581,69 @@ decisions.json :
log.Debugf("'scope' line %d, using supplied value: '%s'", line, importScope)
}
decision := models.Decision{
Value: types.StrPtr(decisionLine.Value),
Duration: types.StrPtr(decisionLine.Duration),
Origin: types.StrPtr(decisionLine.Origin),
Scenario: types.StrPtr(decisionLine.Scenario),
Type: types.StrPtr(decisionLine.Type),
Scope: types.StrPtr(decisionLine.Scope),
Value: ptr.Of(decisionLine.Value),
Duration: ptr.Of(decisionLine.Duration),
Origin: ptr.Of(decisionLine.Origin),
Scenario: ptr.Of(decisionLine.Scenario),
Type: ptr.Of(decisionLine.Type),
Scope: ptr.Of(decisionLine.Scope),
Simulated: new(bool),
}
decisionsList = append(decisionsList, &decision)
}
alerts := models.AddAlertsRequest{}
importAlert := models.Alert{
CreatedAt: time.Now().UTC().Format(time.RFC3339),
Scenario: types.StrPtr(fmt.Sprintf("import %s : %d IPs", importFile, len(decisionsList))),
Message: types.StrPtr(""),
Events: []*models.Event{},
Source: &models.Source{
Scope: types.StrPtr(""),
Value: types.StrPtr(""),
},
StartAt: types.StrPtr(time.Now().UTC().Format(time.RFC3339)),
StopAt: types.StrPtr(time.Now().UTC().Format(time.RFC3339)),
Capacity: types.Int32Ptr(0),
Simulated: types.BoolPtr(false),
EventsCount: types.Int32Ptr(int32(len(decisionsList))),
Leakspeed: types.StrPtr(""),
ScenarioHash: types.StrPtr(""),
ScenarioVersion: types.StrPtr(""),
Decisions: decisionsList,
if batchSize > 0 {
for i := 0; i < len(decisionsList); i += batchSize {
end := i + batchSize
if end > len(decisionsList) {
end = len(decisionsList)
}
decisionBatch := decisionsList[i:end]
importAlert := models.Alert{
CreatedAt: time.Now().UTC().Format(time.RFC3339),
Scenario: ptr.Of(fmt.Sprintf("import %s : %d IPs", importFile, len(decisionBatch))),
Message: ptr.Of(""),
Events: []*models.Event{},
Source: &models.Source{
Scope: ptr.Of(""),
Value: ptr.Of(""),
},
StartAt: ptr.Of(time.Now().UTC().Format(time.RFC3339)),
StopAt: ptr.Of(time.Now().UTC().Format(time.RFC3339)),
Capacity: ptr.Of(int32(0)),
Simulated: ptr.Of(false),
EventsCount: ptr.Of(int32(len(decisionBatch))),
Leakspeed: ptr.Of(""),
ScenarioHash: ptr.Of(""),
ScenarioVersion: ptr.Of(""),
Decisions: decisionBatch,
}
alerts = append(alerts, &importAlert)
}
} else {
importAlert := models.Alert{
CreatedAt: time.Now().UTC().Format(time.RFC3339),
Scenario: ptr.Of(fmt.Sprintf("import %s : %d IPs", importFile, len(decisionsList))),
Message: ptr.Of(""),
Events: []*models.Event{},
Source: &models.Source{
Scope: ptr.Of(""),
Value: ptr.Of(""),
},
StartAt: ptr.Of(time.Now().UTC().Format(time.RFC3339)),
StopAt: ptr.Of(time.Now().UTC().Format(time.RFC3339)),
Capacity: ptr.Of(int32(0)),
Simulated: ptr.Of(false),
EventsCount: ptr.Of(int32(len(decisionsList))),
Leakspeed: ptr.Of(""),
ScenarioHash: ptr.Of(""),
ScenarioVersion: ptr.Of(""),
Decisions: decisionsList,
}
alerts = append(alerts, &importAlert)
}
alerts = append(alerts, &importAlert)
if len(decisionsList) > 1000 {
log.Infof("You are about to add %d decisions, this may take a while", len(decisionsList))
@ -628,6 +663,7 @@ decisions.json :
cmdDecisionImport.Flags().StringVar(&importScope, "scope", types.Ip, "Decision scope (ie. ip,range,username)")
cmdDecisionImport.Flags().StringVarP(&importReason, "reason", "R", "", "Decision reason (ie. scenario-name)")
cmdDecisionImport.Flags().StringVarP(&importType, "type", "t", "", "Decision type (ie. ban,captcha,throttle)")
cmdDecisionImport.Flags().IntVar(&batchSize, "batch", 0, "Split import in batches of N decisions")
return cmdDecisionImport
}

View file

@ -1,6 +1,7 @@
package main
import (
"errors"
"fmt"
"github.com/fatih/color"
@ -98,7 +99,15 @@ Fetches the [.index.json](https://github.com/crowdsecurity/hub/blob/master/.inde
log.Fatal(err)
}
if err := cwhub.UpdateHubIdx(csConfig.Hub); err != nil {
log.Fatalf("Failed to get Hub index : %v", err)
if errors.Is(err, cwhub.ErrIndexNotFound) {
log.Warnf("Could not find index file for branch '%s', using 'master'", cwhub.HubBranch)
cwhub.HubBranch = "master"
if err := cwhub.UpdateHubIdx(csConfig.Hub); err != nil {
log.Fatalf("Failed to get Hub index after retry : %v", err)
}
} else {
log.Fatalf("Failed to get Hub index : %v", err)
}
}
//use LocalSync to get warnings about tainted / outdated items
_, warn := cwhub.LocalSync(csConfig.Hub)

View file

@ -12,13 +12,15 @@ import (
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"golang.org/x/exp/slices"
"gopkg.in/yaml.v2"
"github.com/crowdsecurity/go-cs-lib/pkg/version"
"github.com/crowdsecurity/crowdsec/pkg/alertcontext"
"github.com/crowdsecurity/crowdsec/pkg/apiclient"
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
"github.com/crowdsecurity/crowdsec/pkg/cwversion"
"github.com/crowdsecurity/crowdsec/pkg/exprhelpers"
"github.com/crowdsecurity/crowdsec/pkg/models"
"github.com/crowdsecurity/crowdsec/pkg/parser"
@ -51,7 +53,7 @@ func runLapiStatus(cmd *cobra.Command, args []string) error {
Client, err = apiclient.NewDefaultClient(apiurl,
LAPIURLPrefix,
fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
fmt.Sprintf("crowdsec/%s", version.String()),
nil)
if err != nil {
log.Fatalf("init default client: %s", err)
@ -122,7 +124,7 @@ func runLapiRegister(cmd *cobra.Command, args []string) error {
_, err = apiclient.RegisterClient(&apiclient.Config{
MachineID: lapiUser,
Password: password,
UserAgent: fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
UserAgent: fmt.Sprintf("crowdsec/%s", version.String()),
URL: apiurl,
VersionPrefix: LAPIURLPrefix,
}, nil)
@ -258,7 +260,7 @@ cscli lapi context add --key file_source --value evt.Line.Src
}
data := csConfig.Crowdsec.ContextToSend[keyToAdd]
for _, val := range valuesToAdd {
if !inSlice(val, data) {
if !slices.Contains(data, val) {
log.Infof("value '%s' added to key '%s'", val, keyToAdd)
data = append(data, val)
}
@ -332,7 +334,7 @@ cscli lapi context detect crowdsecurity/sshd-logs
fieldByParsers := make(map[string][]string)
for _, node := range csParsers.Nodes {
if !detectAll && !inSlice(node.Name, args) {
if !detectAll && !slices.Contains(args, node.Name) {
continue
}
if !detectAll {
@ -343,7 +345,7 @@ cscli lapi context detect crowdsecurity/sshd-logs
subNodeFields := detectSubNode(node, *csParsers.Ctx)
for _, field := range subNodeFields {
if !inSlice(field, fieldByParsers[node.Name]) {
if !slices.Contains(fieldByParsers[node.Name], field) {
fieldByParsers[node.Name] = append(fieldByParsers[node.Name], field)
}
}
@ -411,7 +413,7 @@ cscli lapi context delete --value evt.Line.Src
for _, value := range valuesToDelete {
valueFound := false
for key, context := range csConfig.Crowdsec.ContextToSend {
if inSlice(value, context) {
if slices.Contains(context, value) {
valueFound = true
csConfig.Crowdsec.ContextToSend[key] = removeFromSlice(value, context)
log.Infof("value '%s' has been removed from key '%s'", value, key)
@ -443,13 +445,13 @@ func detectStaticField(GrokStatics []types.ExtraField) []string {
for _, static := range GrokStatics {
if static.Parsed != "" {
fieldName := fmt.Sprintf("evt.Parsed.%s", static.Parsed)
if !inSlice(fieldName, ret) {
if !slices.Contains(ret, fieldName) {
ret = append(ret, fieldName)
}
}
if static.Meta != "" {
fieldName := fmt.Sprintf("evt.Meta.%s", static.Meta)
if !inSlice(fieldName, ret) {
if !slices.Contains(ret, fieldName) {
ret = append(ret, fieldName)
}
}
@ -458,7 +460,7 @@ func detectStaticField(GrokStatics []types.ExtraField) []string {
if !strings.HasPrefix(fieldName, "evt.") {
fieldName = "evt." + fieldName
}
if !inSlice(fieldName, ret) {
if !slices.Contains(ret, fieldName) {
ret = append(ret, fieldName)
}
}
@ -472,7 +474,7 @@ func detectNode(node parser.Node, parserCTX parser.UnixParserCtx) []string {
if node.Grok.RunTimeRegexp != nil {
for _, capturedField := range node.Grok.RunTimeRegexp.Names() {
fieldName := fmt.Sprintf("evt.Parsed.%s", capturedField)
if !inSlice(fieldName, ret) {
if !slices.Contains(ret, fieldName) {
ret = append(ret, fieldName)
}
}
@ -485,7 +487,7 @@ func detectNode(node parser.Node, parserCTX parser.UnixParserCtx) []string {
}
for _, capturedField := range grokCompiled.Names() {
fieldName := fmt.Sprintf("evt.Parsed.%s", capturedField)
if !inSlice(fieldName, ret) {
if !slices.Contains(ret, fieldName) {
ret = append(ret, fieldName)
}
}
@ -494,7 +496,7 @@ func detectNode(node parser.Node, parserCTX parser.UnixParserCtx) []string {
if len(node.Grok.Statics) > 0 {
staticsField := detectStaticField(node.Grok.Statics)
for _, staticField := range staticsField {
if !inSlice(staticField, ret) {
if !slices.Contains(ret, staticField) {
ret = append(ret, staticField)
}
}
@ -503,7 +505,7 @@ func detectNode(node parser.Node, parserCTX parser.UnixParserCtx) []string {
if len(node.Statics) > 0 {
staticsField := detectStaticField(node.Statics)
for _, staticField := range staticsField {
if !inSlice(staticField, ret) {
if !slices.Contains(ret, staticField) {
ret = append(ret, staticField)
}
}
@ -519,7 +521,7 @@ func detectSubNode(node parser.Node, parserCTX parser.UnixParserCtx) []string {
if subnode.Grok.RunTimeRegexp != nil {
for _, capturedField := range subnode.Grok.RunTimeRegexp.Names() {
fieldName := fmt.Sprintf("evt.Parsed.%s", capturedField)
if !inSlice(fieldName, ret) {
if !slices.Contains(ret, fieldName) {
ret = append(ret, fieldName)
}
}
@ -531,7 +533,7 @@ func detectSubNode(node parser.Node, parserCTX parser.UnixParserCtx) []string {
}
for _, capturedField := range grokCompiled.Names() {
fieldName := fmt.Sprintf("evt.Parsed.%s", capturedField)
if !inSlice(fieldName, ret) {
if !slices.Contains(ret, fieldName) {
ret = append(ret, fieldName)
}
}
@ -540,7 +542,7 @@ func detectSubNode(node parser.Node, parserCTX parser.UnixParserCtx) []string {
if len(subnode.Grok.Statics) > 0 {
staticsField := detectStaticField(subnode.Grok.Statics)
for _, staticField := range staticsField {
if !inSlice(staticField, ret) {
if !slices.Contains(ret, staticField) {
ret = append(ret, staticField)
}
}
@ -549,7 +551,7 @@ func detectSubNode(node parser.Node, parserCTX parser.UnixParserCtx) []string {
if len(subnode.Statics) > 0 {
staticsField := detectStaticField(subnode.Statics)
for _, staticField := range staticsField {
if !inSlice(staticField, ret) {
if !slices.Contains(ret, staticField) {
ret = append(ret, staticField)
}
}

View file

@ -18,6 +18,7 @@ import (
"github.com/google/uuid"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"golang.org/x/exp/slices"
"gopkg.in/yaml.v2"
"github.com/crowdsecurity/machineid"
@ -33,8 +34,8 @@ var (
)
func generatePassword(length int) string {
upper := "ABCDEFGHIJKLMNOPQRSTUVWXY"
lower := "abcdefghijklmnopqrstuvwxyz"
upper := "ABCDEFGHIJKLMNOPQRSTUVWXY"
lower := "abcdefghijklmnopqrstuvwxyz"
digits := "0123456789"
charset := upper + lower + digits
@ -344,7 +345,7 @@ func NewMachinesDeleteCmd() *cobra.Command {
}
ret := make([]string, 0)
for _, machine := range machines {
if strings.Contains(machine.MachineId, toComplete) && !inSlice(machine.MachineId, args) {
if strings.Contains(machine.MachineId, toComplete) && !slices.Contains(args, machine.MachineId) {
ret = append(ret, machine.MachineId)
}
}

View file

@ -12,6 +12,7 @@ import (
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/cobra/doc"
"golang.org/x/exp/slices"
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
@ -36,6 +37,8 @@ var all bool
var prometheusURL string
var mergedConfig string
func initConfig() {
var err error
if trace_lvl {
@ -50,8 +53,8 @@ func initConfig() {
log.SetLevel(log.ErrorLevel)
}
if !inSlice(os.Args[1], NoNeedConfig) {
csConfig, err = csconfig.NewConfig(ConfigFilePath, false, false, true)
if !slices.Contains(NoNeedConfig, os.Args[1]) {
csConfig, mergedConfig, err = csconfig.NewConfig(ConfigFilePath, false, false, true)
if err != nil {
log.Fatal(err)
}

View file

@ -5,7 +5,6 @@ import (
"fmt"
"io"
"net/http"
"os"
"strconv"
"strings"
"time"
@ -17,12 +16,13 @@ import (
"github.com/spf13/cobra"
"gopkg.in/yaml.v2"
"github.com/crowdsecurity/crowdsec/pkg/types"
"github.com/crowdsecurity/go-cs-lib/pkg/trace"
)
// FormatPrometheusMetrics is a complete rip from prom2json
func FormatPrometheusMetrics(out io.Writer, url string, formatType string) error {
mfChan := make(chan *dto.MetricFamily, 1024)
errChan := make(chan error, 1)
// Start with the DefaultTransport for sane defaults.
transport := http.DefaultTransport.(*http.Transport).Clone()
@ -32,17 +32,24 @@ func FormatPrometheusMetrics(out io.Writer, url string, formatType string) error
// Timeout early if the server doesn't even return the headers.
transport.ResponseHeaderTimeout = time.Minute
go func() {
defer types.CatchPanic("crowdsec/ShowPrometheus")
defer trace.CatchPanic("crowdsec/ShowPrometheus")
err := prom2json.FetchMetricFamilies(url, mfChan, transport)
if err != nil {
log.Fatalf("failed to fetch prometheus metrics : %v", err)
errChan <- fmt.Errorf("failed to fetch prometheus metrics: %w", err)
return
}
errChan <- nil
}()
result := []*prom2json.Family{}
for mf := range mfChan {
result = append(result, prom2json.NewFamily(mf))
}
if err := <-errChan; err != nil {
return err
}
log.Debugf("Finished reading prometheus output, %d entries", len(result))
/*walk*/
lapi_decisions_stats := map[string]struct {
@ -262,36 +269,44 @@ func FormatPrometheusMetrics(out io.Writer, url string, formatType string) error
var noUnit bool
func runMetrics(cmd *cobra.Command, args []string) error {
if err := csConfig.LoadPrometheus(); err != nil {
return fmt.Errorf("failed to load prometheus config: %w", err)
}
if csConfig.Prometheus == nil {
return fmt.Errorf("prometheus section missing, can't show metrics")
}
if !csConfig.Prometheus.Enabled {
return fmt.Errorf("prometheus is not enabled, can't show metrics")
}
if prometheusURL == "" {
prometheusURL = csConfig.Cscli.PrometheusUrl
}
if prometheusURL == "" {
return fmt.Errorf("no prometheus url, please specify in %s or via -u", *csConfig.FilePath)
}
err := FormatPrometheusMetrics(color.Output, prometheusURL+"/metrics", csConfig.Cscli.Output)
if err != nil {
return fmt.Errorf("could not fetch prometheus metrics: %w", err)
}
return nil
}
func NewMetricsCmd() *cobra.Command {
var cmdMetrics = &cobra.Command{
cmdMetrics := &cobra.Command{
Use: "metrics",
Short: "Display crowdsec prometheus metrics.",
Long: `Fetch metrics from the prometheus server and display them in a human-friendly way`,
Args: cobra.ExactArgs(0),
DisableAutoGenTag: true,
Run: func(cmd *cobra.Command, args []string) {
if err := csConfig.LoadPrometheus(); err != nil {
log.Fatal(err)
}
if !csConfig.Prometheus.Enabled {
log.Warning("Prometheus is not enabled, can't show metrics")
os.Exit(1)
}
if prometheusURL == "" {
prometheusURL = csConfig.Cscli.PrometheusUrl
}
if prometheusURL == "" {
log.Errorf("No prometheus url, please specify in %s or via -u", *csConfig.FilePath)
os.Exit(1)
}
err := FormatPrometheusMetrics(color.Output, prometheusURL+"/metrics", csConfig.Cscli.Output)
if err != nil {
log.Fatalf("could not fetch prometheus metrics: %s", err)
}
},
RunE: runMetrics,
}
cmdMetrics.PersistentFlags().StringVarP(&prometheusURL, "url", "u", "", "Prometheus url (http://<ip>:<port>/metrics)")
cmdMetrics.PersistentFlags().BoolVar(&noUnit, "no-unit", false, "Show the real number instead of formatted with units")

View file

@ -20,11 +20,12 @@ import (
"github.com/spf13/cobra"
"gopkg.in/tomb.v2"
"github.com/crowdsecurity/go-cs-lib/pkg/version"
"github.com/crowdsecurity/crowdsec/pkg/apiclient"
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
"github.com/crowdsecurity/crowdsec/pkg/csplugin"
"github.com/crowdsecurity/crowdsec/pkg/csprofiles"
"github.com/crowdsecurity/crowdsec/pkg/cwversion"
)
@ -273,7 +274,7 @@ cscli notifications reinject <alert_id> -a '{"remediation": true,"scenario":"not
client, err := apiclient.NewClient(&apiclient.Config{
MachineID: csConfig.API.Client.Credentials.Login,
Password: strfmt.Password(csConfig.API.Client.Credentials.Password),
UserAgent: fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
UserAgent: fmt.Sprintf("crowdsec/%s", version.String()),
URL: apiURL,
VersionPrefix: "v1",
})

View file

@ -1,15 +1,17 @@
package main
import (
"fmt"
"time"
"github.com/crowdsecurity/crowdsec/pkg/apiserver"
"github.com/crowdsecurity/crowdsec/pkg/database"
"github.com/crowdsecurity/crowdsec/pkg/types"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"gopkg.in/tomb.v2"
"github.com/crowdsecurity/go-cs-lib/pkg/ptr"
"github.com/crowdsecurity/crowdsec/pkg/apiserver"
"github.com/crowdsecurity/crowdsec/pkg/database"
)
func NewPapiCmd() *cobra.Command {
@ -20,7 +22,7 @@ func NewPapiCmd() *cobra.Command {
DisableAutoGenTag: true,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
if err := csConfig.LoadAPIServer(); err != nil || csConfig.DisableAPI {
return errors.Wrap(err, "Local API is disabled, please run this command on the local API machine")
return fmt.Errorf("Local API is disabled, please run this command on the local API machine: %w", err)
}
if csConfig.API.Server.OnlineClient == nil {
log.Fatalf("no configuration for Central API in '%s'", *csConfig.FilePath)
@ -71,7 +73,7 @@ func NewPapiStatusCmd() *cobra.Command {
var lastTimestampStr *string
lastTimestampStr, err = dbClient.GetConfigItem(apiserver.PapiPullKey)
if err != nil {
lastTimestampStr = types.StrPtr("never")
lastTimestampStr = ptr.Of("never")
}
log.Infof("You can successfully interact with Polling API (PAPI)")
log.Infof("Console plan: %s", perms.Plan)

View file

@ -6,6 +6,7 @@ import (
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"golang.org/x/exp/slices"
"gopkg.in/yaml.v2"
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
@ -161,7 +162,7 @@ func NewSimulationEnableCmd() *cobra.Command {
if !item.Installed {
log.Warningf("'%s' isn't enabled", scenario)
}
isExcluded := inSlice(scenario, csConfig.Cscli.SimulationConfig.Exclusions)
isExcluded := slices.Contains(csConfig.Cscli.SimulationConfig.Exclusions, scenario)
if *csConfig.Cscli.SimulationConfig.Simulation && !isExcluded {
log.Warning("global simulation is already enabled")
continue
@ -210,7 +211,7 @@ func NewSimulationDisableCmd() *cobra.Command {
Run: func(cmd *cobra.Command, args []string) {
if len(args) > 0 {
for _, scenario := range args {
isExcluded := inSlice(scenario, csConfig.Cscli.SimulationConfig.Exclusions)
isExcluded := slices.Contains(csConfig.Cscli.SimulationConfig.Exclusions, scenario)
if !*csConfig.Cscli.SimulationConfig.Simulation && !isExcluded {
log.Warningf("%s isn't in simulation mode", scenario)
continue

View file

@ -18,6 +18,8 @@ import (
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/crowdsecurity/go-cs-lib/pkg/version"
"github.com/crowdsecurity/crowdsec/pkg/apiclient"
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
"github.com/crowdsecurity/crowdsec/pkg/cwversion"
@ -182,7 +184,7 @@ func collectAPIStatus(login string, password string, endpoint string, prefix str
Client, err = apiclient.NewDefaultClient(apiurl,
prefix,
fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
fmt.Sprintf("crowdsec/%s", version.String()),
nil)
if err != nil {
return []byte(fmt.Sprintf("could not init client: %s", err))

View file

@ -19,8 +19,11 @@ import (
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/texttheater/golang-levenshtein/levenshtein"
"golang.org/x/exp/slices"
"gopkg.in/yaml.v2"
"github.com/crowdsecurity/go-cs-lib/pkg/trace"
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
"github.com/crowdsecurity/crowdsec/pkg/database"
"github.com/crowdsecurity/crowdsec/pkg/types"
@ -35,15 +38,6 @@ func printHelp(cmd *cobra.Command) {
}
}
func inSlice(s string, slice []string) bool {
for _, str := range slice {
if s == str {
return true
}
}
return false
}
func indexOf(s string, slice []string) int {
for i, elem := range slice {
if s == elem {
@ -113,7 +107,7 @@ func compAllItems(itemType string, args []string, toComplete string) ([]string,
comp := make([]string, 0)
hubItems := cwhub.GetHubStatusForItemType(itemType, "", true)
for _, item := range hubItems {
if !inSlice(item.Name, args) && strings.Contains(item.Name, toComplete) {
if !slices.Contains(args, item.Name) && strings.Contains(item.Name, toComplete) {
comp = append(comp, item.Name)
}
}
@ -515,7 +509,7 @@ func GetPrometheusMetric(url string) []*prom2json.Family {
transport.ResponseHeaderTimeout = time.Minute
go func() {
defer types.CatchPanic("crowdsec/GetPrometheusMetric")
defer trace.CatchPanic("crowdsec/GetPrometheusMetric")
err := prom2json.FetchMetricFamilies(url, mfChan, transport)
if err != nil {
log.Fatalf("failed to fetch prometheus metrics : %v", err)
@ -691,30 +685,13 @@ type unit struct {
}
var ranges = []unit{
{
value: 1e18,
symbol: "E",
},
{
value: 1e15,
symbol: "P",
},
{
value: 1e12,
symbol: "T",
},
{
value: 1e6,
symbol: "M",
},
{
value: 1e3,
symbol: "k",
},
{
value: 1,
symbol: "",
},
{value: 1e18, symbol: "E"},
{value: 1e15, symbol: "P"},
{value: 1e12, symbol: "T"},
{value: 1e9, symbol: "G"},
{value: 1e6, symbol: "M"},
{value: 1e3, symbol: "k"},
{value: 1, symbol: ""},
}
func formatNumber(num int) string {
@ -746,7 +723,6 @@ func getDBClient() (*database.Client, error) {
return ret, nil
}
func removeFromSlice(val string, slice []string) []string {
var i int
var value string

View file

@ -7,9 +7,7 @@ endif
# Go parameters
GOCMD = go
GOBUILD = $(GOCMD) build
GOCLEAN = $(GOCMD) clean
GOTEST = $(GOCMD) test
GOGET = $(GOCMD) get
CROWDSEC_BIN = crowdsec$(EXT)
# names longer than 15 chars break 'pgrep'
@ -31,7 +29,7 @@ test:
$(GOTEST) $(LD_OPTS) -v ./...
clean:
@$(RM) $(CROWDSEC_BIN) $(CROWDSEC_BIN).test $(WIN_IGNORE_ERR)
@$(RM) $(CROWDSEC_BIN) $(WIN_IGNORE_ERR)
.PHONY: install
install: install-conf install-bin
@ -59,7 +57,7 @@ install-conf:
install-bin:
install -v -m 755 -D "$(CROWDSEC_BIN)" "$(BIN_PREFIX)/$(CROWDSEC_BIN)" || exit
.PHONY: systemd"$(BIN_PREFI"$(BIN_PREFIX)/$(CROWDSEC_BIN)""$(BIN_PREFIX)/$(CROWDSEC_BIN)"X)/$(CROWDSEC_BIN)"
.PHONY: systemd
systemd: install
CFG=$(CFG_PREFIX) PID=$(PID_DIR) BIN=$(BIN_PREFIX)"/"$(CROWDSEC_BIN) envsubst < ../../config/crowdsec.service > "$(SYSTEMD_PATH_FILE)"
systemctl daemon-reload

View file

@ -7,9 +7,10 @@ import (
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
"github.com/crowdsecurity/go-cs-lib/pkg/trace"
"github.com/crowdsecurity/crowdsec/pkg/apiserver"
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
"github.com/crowdsecurity/crowdsec/pkg/types"
)
func initAPIServer(cConfig *csconfig.Config) (*apiserver.APIServer, error) {
@ -52,9 +53,9 @@ func initAPIServer(cConfig *csconfig.Config) (*apiserver.APIServer, error) {
func serveAPIServer(apiServer *apiserver.APIServer, apiReady chan bool) {
apiTomb.Go(func() error {
defer types.CatchPanic("crowdsec/serveAPIServer")
defer trace.CatchPanic("crowdsec/serveAPIServer")
go func() {
defer types.CatchPanic("crowdsec/runAPIServer")
defer trace.CatchPanic("crowdsec/runAPIServer")
log.Debugf("serving API after %s ms", time.Since(crowdsecT0))
if err := apiServer.Run(apiReady); err != nil {
log.Fatal(err)

View file

@ -8,6 +8,8 @@ import (
"path/filepath"
"github.com/crowdsecurity/go-cs-lib/pkg/trace"
"github.com/crowdsecurity/crowdsec/pkg/acquisition"
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
@ -53,7 +55,7 @@ func runCrowdsec(cConfig *csconfig.Config, parsers *parser.Parsers) error {
parserWg.Add(1)
for i := 0; i < cConfig.Crowdsec.ParserRoutinesCount; i++ {
parsersTomb.Go(func() error {
defer types.CatchPanic("crowdsec/runParse")
defer trace.CatchPanic("crowdsec/runParse")
if err := runParse(inputLineChan, inputEventChan, *parsers.Ctx, parsers.Nodes); err != nil { //this error will never happen as parser.Parse is not able to return errors
log.Fatalf("starting parse error : %s", err)
return err
@ -79,7 +81,7 @@ func runCrowdsec(cConfig *csconfig.Config, parsers *parser.Parsers) error {
for i := 0; i < cConfig.Crowdsec.BucketsRoutinesCount; i++ {
bucketsTomb.Go(func() error {
defer types.CatchPanic("crowdsec/runPour")
defer trace.CatchPanic("crowdsec/runPour")
if err := runPour(inputEventChan, holders, buckets, cConfig); err != nil {
log.Fatalf("starting pour error : %s", err)
return err
@ -97,7 +99,7 @@ func runCrowdsec(cConfig *csconfig.Config, parsers *parser.Parsers) error {
outputWg.Add(1)
for i := 0; i < cConfig.Crowdsec.OutputRoutinesCount; i++ {
outputsTomb.Go(func() error {
defer types.CatchPanic("crowdsec/runOutput")
defer trace.CatchPanic("crowdsec/runOutput")
if err := runOutput(inputEventChan, outputEventChan, buckets, *parsers.Povfwctx, parsers.Povfwnodes, *cConfig.API.Client.Credentials); err != nil {
log.Fatalf("starting outputs error : %s", err)
return err
@ -132,9 +134,9 @@ func runCrowdsec(cConfig *csconfig.Config, parsers *parser.Parsers) error {
func serveCrowdsec(parsers *parser.Parsers, cConfig *csconfig.Config, agentReady chan bool) {
crowdsecTomb.Go(func() error {
defer types.CatchPanic("crowdsec/serveCrowdsec")
defer trace.CatchPanic("crowdsec/serveCrowdsec")
go func() {
defer types.CatchPanic("crowdsec/runCrowdsec")
defer trace.CatchPanic("crowdsec/runCrowdsec")
// this logs every time, even at config reload
log.Debugf("running agent after %s ms", time.Since(crowdsecT0))
agentReady <- true

View file

@ -154,7 +154,9 @@ func (f *Flags) Parse() {
flag.BoolVar(&f.DisableAgent, "no-cs", false, "disable crowdsec agent")
flag.BoolVar(&f.DisableAPI, "no-api", false, "disable local API")
flag.BoolVar(&f.DisableCAPI, "no-capi", false, "disable communication with Central API")
flag.StringVar(&f.WinSvc, "winsvc", "", "Windows service Action : Install, Remove etc..")
if runtime.GOOS == "windows" {
flag.StringVar(&f.WinSvc, "winsvc", "", "Windows service Action: Install, Remove etc..")
}
flag.StringVar(&dumpFolder, "dump-data", "", "dump parsers/buckets raw outputs")
flag.Parse()
}
@ -192,7 +194,7 @@ func newLogLevel(curLevelPtr *log.Level, f *Flags) *log.Level {
// LoadConfig returns a configuration parsed from configuration file
func LoadConfig(configFile string, disableAgent bool, disableAPI bool, quiet bool) (*csconfig.Config, error) {
cConfig, err := csconfig.NewConfig(configFile, disableAgent, disableAPI, quiet)
cConfig, _, err := csconfig.NewConfig(configFile, disableAgent, disableAPI, quiet)
if err != nil {
return nil, err
}

View file

@ -9,15 +9,16 @@ import (
"github.com/prometheus/client_golang/prometheus/promhttp"
log "github.com/sirupsen/logrus"
"github.com/crowdsecurity/go-cs-lib/pkg/trace"
"github.com/crowdsecurity/go-cs-lib/pkg/version"
v1 "github.com/crowdsecurity/crowdsec/pkg/apiserver/controllers/v1"
"github.com/crowdsecurity/crowdsec/pkg/cache"
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
"github.com/crowdsecurity/crowdsec/pkg/cwversion"
"github.com/crowdsecurity/crowdsec/pkg/database"
"github.com/crowdsecurity/crowdsec/pkg/exprhelpers"
leaky "github.com/crowdsecurity/crowdsec/pkg/leakybucket"
"github.com/crowdsecurity/crowdsec/pkg/parser"
"github.com/crowdsecurity/crowdsec/pkg/types"
)
/*prometheus*/
@ -61,7 +62,7 @@ var globalCsInfo = prometheus.NewGauge(
prometheus.GaugeOpts{
Name: "cs_info",
Help: "Information about Crowdsec.",
ConstLabels: prometheus.Labels{"version": cwversion.VersionStr()},
ConstLabels: prometheus.Labels{"version": version.String()},
},
)
@ -187,7 +188,7 @@ func servePrometheus(config *csconfig.PrometheusCfg, dbClient *database.Client,
return
}
defer types.CatchPanic("crowdsec/servePrometheus")
defer trace.CatchPanic("crowdsec/servePrometheus")
http.Handle("/metrics", computeDynamicMetrics(promhttp.Handler(), dbClient))
<-apiReady

View file

@ -7,10 +7,11 @@ import (
"sync"
"time"
"github.com/crowdsecurity/go-cs-lib/pkg/version"
"github.com/crowdsecurity/crowdsec/pkg/apiclient"
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
"github.com/crowdsecurity/crowdsec/pkg/cwversion"
leaky "github.com/crowdsecurity/crowdsec/pkg/leakybucket"
"github.com/crowdsecurity/crowdsec/pkg/models"
"github.com/crowdsecurity/crowdsec/pkg/parser"
@ -88,7 +89,7 @@ func runOutput(input chan types.Event, overflow chan types.Event, buckets *leaky
MachineID: apiConfig.Login,
Password: password,
Scenarios: scenarios,
UserAgent: fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
UserAgent: fmt.Sprintf("crowdsec/%s", version.String()),
URL: apiURL,
PapiURL: papiURL,
VersionPrefix: "v1",

View file

@ -10,10 +10,11 @@ import (
log "github.com/sirupsen/logrus"
"github.com/sirupsen/logrus/hooks/writer"
"github.com/crowdsecurity/go-cs-lib/pkg/trace"
"github.com/crowdsecurity/go-cs-lib/pkg/version"
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
"github.com/crowdsecurity/crowdsec/pkg/cwversion"
"github.com/crowdsecurity/crowdsec/pkg/database"
"github.com/crowdsecurity/crowdsec/pkg/types"
)
func StartRunSvc() error {
@ -22,7 +23,7 @@ func StartRunSvc() error {
err error
)
defer types.CatchPanic("crowdsec/StartRunSvc")
defer trace.CatchPanic("crowdsec/StartRunSvc")
// Set a default logger with level=fatal on stderr,
// in addition to the one we configure afterwards
@ -38,7 +39,7 @@ func StartRunSvc() error {
return err
}
log.Infof("Crowdsec %s", cwversion.VersionStr())
log.Infof("Crowdsec %s", version.String())
apiReady := make(chan bool, 1)
agentReady := make(chan bool, 1)

View file

@ -7,17 +7,18 @@ import (
log "github.com/sirupsen/logrus"
"golang.org/x/sys/windows/svc"
"github.com/crowdsecurity/go-cs-lib/pkg/trace"
"github.com/crowdsecurity/go-cs-lib/pkg/version"
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
"github.com/crowdsecurity/crowdsec/pkg/cwversion"
"github.com/crowdsecurity/crowdsec/pkg/database"
"github.com/crowdsecurity/crowdsec/pkg/types"
)
func StartRunSvc() error {
const svcName = "CrowdSec"
const svcDescription = "Crowdsec IPS/IDS"
defer types.CatchPanic("crowdsec/StartRunSvc")
defer trace.CatchPanic("crowdsec/StartRunSvc")
isRunninginService, err := svc.IsWindowsService()
if err != nil {
@ -66,7 +67,7 @@ func WindowsRun() error {
return err
}
// Configure logging
log.Infof("Crowdsec %s", cwversion.VersionStr())
log.Infof("Crowdsec %s", version.String())
apiReady := make(chan bool, 1)
agentReady := make(chan bool, 1)

View file

@ -11,6 +11,8 @@ import (
log "github.com/sirupsen/logrus"
"gopkg.in/tomb.v2"
"github.com/crowdsecurity/go-cs-lib/pkg/trace"
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
"github.com/crowdsecurity/crowdsec/pkg/database"
"github.com/crowdsecurity/crowdsec/pkg/exprhelpers"
@ -226,7 +228,7 @@ func HandleSignals(cConfig *csconfig.Config) error {
exitChan := make(chan error)
go func() {
defer types.CatchPanic("crowdsec/HandleSignals")
defer trace.CatchPanic("crowdsec/HandleSignals")
Loop:
for {
s := <-signalChan

View file

@ -1,3 +1,4 @@
##RDP
source: wineventlog
event_channel: Security
event_ids:
@ -5,4 +6,26 @@ event_ids:
- 4623
event_level: information
labels:
type: eventlog
type: eventlog
---
##Firewall
filenames:
- C:\Windows\System32\LogFiles\Firewall\pfirewall.log
labels:
type: windows-firewall
---
##SQL Server
source: wineventlog
event_channel: Application
event_ids:
- 18456
event_level: information
labels:
type: eventlog
---
##IIS
use_time_machine: true
filenames:
- C:\inetpub\logs\LogFiles\*\*.log
labels:
type: iis

View file

@ -1,4 +1,3 @@
simulation: off
simulation: false
# exclusions:
# - crowdsecurity/ssh-bf

6
debian/rules vendored
View file

@ -4,12 +4,6 @@ export DEB_VERSION=$(shell dpkg-parsechangelog | egrep '^Version:' | cut -f 2 -d
export BUILD_VERSION=v${DEB_VERSION}-debian-pragmatic
export GO111MODULE=on
# LD_OPTS=-ldflags "-s -w -X github.com/crowdsecurity/crowdsec/pkg/cwversion.Version=$(BUILD_VERSION) \
# -X github.com/crowdsecurity/crowdsec/pkg/cwversion.BuildDate=$(BUILD_TIMESTAMP) \
# -X github.com/crowdsecurity/crowdsec/pkg/cwversion.Codename=$(BUILD_CODENAME) \
# -X github.com/crowdsecurity/crowdsec/pkg/cwversion.Tag=$(BUILD_TAG) \
# -X github.com/crowdsecurity/crowdsec/pkg/cwversion.GoVersion=$(BUILD_GOVERSION)"
%:
dh $@

View file

@ -280,6 +280,7 @@ config.yaml) each time the container is run.
| __LAPI__ | | (useless with DISABLE_LOCAL_API) |
| `USE_WAL` | false | Enable Write-Ahead Logging with SQLite |
| `CUSTOM_HOSTNAME` | localhost | Name for the local agent (running in the container with LAPI) |
| `CAPI_WHITELISTS_PATH` | | Path for capi_whitelists.yaml |
| | | |
| __Agent__ | | (these don't work with DISABLE_AGENT) |
| `TYPE` | | [`Labels.type`](https://docs.crowdsec.net/Crowdsec/v1/references/acquisition/) for file in time-machine: `-e TYPE="<type>"` |

View file

@ -187,7 +187,6 @@ fi
lapi_credentials_path=$(conf_get '.api.client.credentials_path')
if isfalse "$DISABLE_LOCAL_API"; then
# generate local agent credentials (even if agent is disabled, cscli needs a
# connection to the API)
@ -365,6 +364,11 @@ for BOUNCER in /run/secrets/@(bouncer_key|BOUNCER_KEY)* ; do
done
shopt -u nullglob extglob
# set all options before validating the configuration
conf_set_if "$CAPI_WHITELISTS_PATH" '.api.server.capi_whitelists_path = strenv(CAPI_WHITELISTS_PATH)'
conf_set_if "$METRICS_PORT" '.prometheus.listen_port=env(METRICS_PORT)'
ARGS=""
if [ "$CONFIG_FILE" != "" ]; then
ARGS="-c $CONFIG_FILE"
@ -402,7 +406,5 @@ if istrue "$LEVEL_INFO"; then
ARGS="$ARGS -info"
fi
conf_set_if "$METRICS_PORT" '.prometheus.listen_port=env(METRICS_PORT)'
# shellcheck disable=SC2086
exec crowdsec $ARGS

View file

@ -1,11 +1,11 @@
[packages]
pytest-dotenv = "*"
pytest-xdist = "*"
pytest-cs = {ref = "0.4.0", git = "https://github.com/crowdsecurity/pytest-cs.git"}
pytest-cs = {ref = "0.7.16", git = "https://github.com/crowdsecurity/pytest-cs.git"}
[dev-packages]
gnureadline = "*"
ipdb = "*"
[requires]
python_version = "3.10"
python_version = "*"

189
docker/test/Pipfile.lock generated
View file

@ -1,11 +1,11 @@
{
"_meta": {
"hash": {
"sha256": "da2959f993eb751a5f6d2b1c4537ba39ed414d0e9d300dc513ced5a8f0ab4261"
"sha256": "7e91f125d4ad0d1f1b5da7ef441d75baf4f28788c791803a216cb6956b131ea9"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.10"
"python_version": "*"
},
"sources": [
{
@ -16,21 +16,13 @@
]
},
"default": {
"attrs": {
"hashes": [
"sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836",
"sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99"
],
"markers": "python_version >= '3.6'",
"version": "==22.2.0"
},
"certifi": {
"hashes": [
"sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3",
"sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"
"sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7",
"sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716"
],
"markers": "python_version >= '3.6'",
"version": "==2022.12.7"
"version": "==2023.5.7"
},
"cffi": {
"hashes": [
@ -184,48 +176,36 @@
},
"cryptography": {
"hashes": [
"sha256:103e8f7155f3ce2ffa0049fe60169878d47a4364b277906386f8de21c9234aa1",
"sha256:23df8ca3f24699167daf3e23e51f7ba7334d504af63a94af468f468b975b7dd7",
"sha256:2725672bb53bb92dc7b4150d233cd4b8c59615cd8288d495eaa86db00d4e5c06",
"sha256:30b1d1bfd00f6fc80d11300a29f1d8ab2b8d9febb6ed4a38a76880ec564fae84",
"sha256:35d658536b0a4117c885728d1a7032bdc9a5974722ae298d6c533755a6ee3915",
"sha256:50cadb9b2f961757e712a9737ef33d89b8190c3ea34d0fb6675e00edbe35d074",
"sha256:5f8c682e736513db7d04349b4f6693690170f95aac449c56f97415c6980edef5",
"sha256:6236a9610c912b129610eb1a274bdc1350b5df834d124fa84729ebeaf7da42c3",
"sha256:788b3921d763ee35dfdb04248d0e3de11e3ca8eb22e2e48fef880c42e1f3c8f9",
"sha256:8bc0008ef798231fac03fe7d26e82d601d15bd16f3afaad1c6113771566570f3",
"sha256:8f35c17bd4faed2bc7797d2a66cbb4f986242ce2e30340ab832e5d99ae60e011",
"sha256:b49a88ff802e1993b7f749b1eeb31134f03c8d5c956e3c125c75558955cda536",
"sha256:bc0521cce2c1d541634b19f3ac661d7a64f9555135e9d8af3980965be717fd4a",
"sha256:bc5b871e977c8ee5a1bbc42fa8d19bcc08baf0c51cbf1586b0e87a2694dde42f",
"sha256:c43ac224aabcbf83a947eeb8b17eaf1547bce3767ee2d70093b461f31729a480",
"sha256:d15809e0dbdad486f4ad0979753518f47980020b7a34e9fc56e8be4f60702fac",
"sha256:d7d84a512a59f4412ca8549b01f94be4161c94efc598bf09d027d67826beddc0",
"sha256:e029b844c21116564b8b61216befabca4b500e6816fa9f0ba49527653cae2108",
"sha256:e8a0772016feeb106efd28d4a328e77dc2edae84dfbac06061319fdb669ff828",
"sha256:e944fe07b6f229f4c1a06a7ef906a19652bdd9fd54c761b0ff87e83ae7a30354",
"sha256:eb40fe69cfc6f5cdab9a5ebd022131ba21453cf7b8a7fd3631f45bbf52bed612",
"sha256:fa507318e427169ade4e9eccef39e9011cdc19534f55ca2f36ec3f388c1f70f3",
"sha256:ffd394c7896ed7821a6d13b24657c6a34b6e2650bd84ae063cf11ccffa4f1a97"
"sha256:05dc219433b14046c476f6f09d7636b92a1c3e5808b9a6536adf4932b3b2c440",
"sha256:0dcca15d3a19a66e63662dc8d30f8036b07be851a8680eda92d079868f106288",
"sha256:142bae539ef28a1c76794cca7f49729e7c54423f615cfd9b0b1fa90ebe53244b",
"sha256:3daf9b114213f8ba460b829a02896789751626a2a4e7a43a28ee77c04b5e4958",
"sha256:48f388d0d153350f378c7f7b41497a54ff1513c816bcbbcafe5b829e59b9ce5b",
"sha256:4df2af28d7bedc84fe45bd49bc35d710aede676e2a4cb7fc6d103a2adc8afe4d",
"sha256:4f01c9863da784558165f5d4d916093737a75203a5c5286fde60e503e4276c7a",
"sha256:7a38250f433cd41df7fcb763caa3ee9362777fdb4dc642b9a349721d2bf47404",
"sha256:8f79b5ff5ad9d3218afb1e7e20ea74da5f76943ee5edb7f76e56ec5161ec782b",
"sha256:956ba8701b4ffe91ba59665ed170a2ebbdc6fc0e40de5f6059195d9f2b33ca0e",
"sha256:a04386fb7bc85fab9cd51b6308633a3c271e3d0d3eae917eebab2fac6219b6d2",
"sha256:a95f4802d49faa6a674242e25bfeea6fc2acd915b5e5e29ac90a32b1139cae1c",
"sha256:adc0d980fd2760c9e5de537c28935cc32b9353baaf28e0814df417619c6c8c3b",
"sha256:aecbb1592b0188e030cb01f82d12556cf72e218280f621deed7d806afd2113f9",
"sha256:b12794f01d4cacfbd3177b9042198f3af1c856eedd0a98f10f141385c809a14b",
"sha256:c0764e72b36a3dc065c155e5b22f93df465da9c39af65516fe04ed3c68c92636",
"sha256:c33c0d32b8594fa647d2e01dbccc303478e16fdd7cf98652d5b3ed11aa5e5c99",
"sha256:cbaba590180cba88cb99a5f76f90808a624f18b169b90a4abb40c1fd8c19420e",
"sha256:d5a1bd0e9e2031465761dfa920c16b0065ad77321d8a8c1f5ee331021fda65e9"
],
"markers": "python_version >= '3.6'",
"version": "==39.0.2"
"version": "==40.0.2"
},
"docker": {
"hashes": [
"sha256:896c4282e5c7af5c45e8b683b0b0c33932974fe6e50fc6906a0a83616ab3da97",
"sha256:dbcb3bd2fa80dca0788ed908218bf43972772009b881ed1e20dfc29a65e49782"
"sha256:134cd828f84543cbf8e594ff81ca90c38288df3c0a559794c12f2e4b634ea19e",
"sha256:dcc088adc2ec4e7cfc594e275d8bd2c9738c56c808de97476939ef67db5af8c2"
],
"markers": "python_version >= '3.7'",
"version": "==6.0.1"
},
"exceptiongroup": {
"hashes": [
"sha256:232c37c63e4f682982c8b6459f33a8981039e5fb8756b2074364e5055c498c9e",
"sha256:d484c3090ba2889ae2928419117447a14daf3c1231d5e30d0aae34f354f01785"
],
"markers": "python_version < '3.11'",
"version": "==1.1.1"
"version": "==6.1.2"
},
"execnet": {
"hashes": [
@ -253,11 +233,11 @@
},
"packaging": {
"hashes": [
"sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2",
"sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"
"sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61",
"sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"
],
"markers": "python_version >= '3.7'",
"version": "==23.0"
"version": "==23.1"
},
"pluggy": {
"hashes": [
@ -269,23 +249,23 @@
},
"psutil": {
"hashes": [
"sha256:149555f59a69b33f056ba1c4eb22bb7bf24332ce631c44a319cec09f876aaeff",
"sha256:16653106f3b59386ffe10e0bad3bb6299e169d5327d3f187614b1cb8f24cf2e1",
"sha256:3d7f9739eb435d4b1338944abe23f49584bde5395f27487d2ee25ad9a8774a62",
"sha256:3ff89f9b835100a825b14c2808a106b6fdcc4b15483141482a12c725e7f78549",
"sha256:54c0d3d8e0078b7666984e11b12b88af2db11d11249a8ac8920dd5ef68a66e08",
"sha256:54d5b184728298f2ca8567bf83c422b706200bcbbfafdc06718264f9393cfeb7",
"sha256:6001c809253a29599bc0dfd5179d9f8a5779f9dffea1da0f13c53ee568115e1e",
"sha256:68908971daf802203f3d37e78d3f8831b6d1014864d7a85937941bb35f09aefe",
"sha256:6b92c532979bafc2df23ddc785ed116fced1f492ad90a6830cf24f4d1ea27d24",
"sha256:852dd5d9f8a47169fe62fd4a971aa07859476c2ba22c2254d4a1baa4e10b95ad",
"sha256:9120cd39dca5c5e1c54b59a41d205023d436799b1c8c4d3ff71af18535728e94",
"sha256:c1ca331af862803a42677c120aff8a814a804e09832f166f226bfd22b56feee8",
"sha256:efeae04f9516907be44904cc7ce08defb6b665128992a56957abc9b61dca94b7",
"sha256:fd8522436a6ada7b4aad6638662966de0d61d241cb821239b2ae7013d41a43d4"
"sha256:104a5cc0e31baa2bcf67900be36acde157756b9c44017b86b2c049f11957887d",
"sha256:3c6f686f4225553615612f6d9bc21f1c0e305f75d7d8454f9b46e901778e7217",
"sha256:4aef137f3345082a3d3232187aeb4ac4ef959ba3d7c10c33dd73763fbc063da4",
"sha256:5410638e4df39c54d957fc51ce03048acd8e6d60abc0f5107af51e5fb566eb3c",
"sha256:5b9b8cb93f507e8dbaf22af6a2fd0ccbe8244bf30b1baad6b3954e935157ae3f",
"sha256:7a7dd9997128a0d928ed4fb2c2d57e5102bb6089027939f3b722f3a210f9a8da",
"sha256:89518112647f1276b03ca97b65cc7f64ca587b1eb0278383017c2a0dcc26cbe4",
"sha256:8c5f7c5a052d1d567db4ddd231a9d27a74e8e4a9c3f44b1032762bd7b9fdcd42",
"sha256:ab8ed1a1d77c95453db1ae00a3f9c50227ebd955437bcf2a574ba8adbf6a74d5",
"sha256:acf2aef9391710afded549ff602b5887d7a2349831ae4c26be7c807c0a39fac4",
"sha256:b258c0c1c9d145a1d5ceffab1134441c4c5113b2417fafff7315a917a026c3c9",
"sha256:be8929ce4313f9f8146caad4272f6abb8bf99fc6cf59344a3167ecd74f4f203f",
"sha256:c607bb3b57dc779d55e1554846352b4e358c10fff3abf3514a7a6601beebdb30",
"sha256:ea8518d152174e1249c4f2a1c89e3e6065941df2fa13a1ab45327716a23c2b48"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==5.9.4"
"version": "==5.9.5"
},
"pycparser": {
"hashes": [
@ -296,15 +276,15 @@
},
"pytest": {
"hashes": [
"sha256:130328f552dcfac0b1cec75c12e3f005619dc5f874f0a06e8ff7263f0ee6225e",
"sha256:c99ab0c73aceb050f68929bc93af19ab6db0558791c6a0715723abe9d0ade9d4"
"sha256:3799fa815351fea3a5e96ac7e503a96fa51cc9942c3753cda7651b93c1cfa362",
"sha256:434afafd78b1d78ed0addf160ad2b77a30d35d4bdf8af234fe621919d9ed15e3"
],
"markers": "python_version >= '3.7'",
"version": "==7.2.2"
"version": "==7.3.1"
},
"pytest-cs": {
"git": "https://github.com/crowdsecurity/pytest-cs.git",
"ref": "8c49bd8072672c49855a7991a5900858b3ebb777"
"ref": "4a3451084215053af8a48ff37507b4f86bf75c10"
},
"pytest-datadir": {
"hashes": [
@ -324,11 +304,11 @@
},
"pytest-xdist": {
"hashes": [
"sha256:1849bd98d8b242b948e472db7478e090bf3361912a8fed87992ed94085f54727",
"sha256:37290d161638a20b672401deef1cba812d110ac27e35d213f091d15b8beb40c9"
"sha256:d5ee0520eb1b7bcca50a60a518ab7a7707992812c578198f8b44fdfac78e8c93",
"sha256:ff9daa7793569e6a68544850fd3927cd257cc03a7ef76c95e86915355e82b5f2"
],
"index": "pypi",
"version": "==3.2.1"
"version": "==3.3.1"
},
"python-dotenv": {
"hashes": [
@ -386,42 +366,35 @@
},
"requests": {
"hashes": [
"sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa",
"sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf"
"sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f",
"sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"
],
"markers": "python_version >= '3.7' and python_version < '4'",
"version": "==2.28.2"
},
"tomli": {
"hashes": [
"sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc",
"sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"
],
"markers": "python_version < '3.11'",
"version": "==2.0.1"
"markers": "python_version >= '3.7'",
"version": "==2.31.0"
},
"trustme": {
"hashes": [
"sha256:5e07b23d70ceed64f3bb36ae4b9abc52354c16c98d45ab037bee2b5fbffe586c",
"sha256:a6e53039cc43e70548ebd9a42ec1af5cba803a16d14321cd96352d2b4e010e04"
"sha256:1d4f0b0fe28091506edc29c19ad90cca387646add436c3ca66ba7bcc53807f55",
"sha256:7a9f82ad494d661cd10c9eed38e0f708154eb59a2e415da6b02af3e5dac53134"
],
"version": "==0.9.0"
"markers": "python_version >= '3.7'",
"version": "==1.0.0"
},
"urllib3": {
"hashes": [
"sha256:8a388717b9476f934a21484e8c8e61875ab60644d29b9b39e11e4b9dc1c6b305",
"sha256:aa751d169e23c7479ce47a0cb0da579e3ede798f994f5816a74e4f4500dcea42"
"sha256:61717a1095d7e155cdb737ac7bb2f4324a858a1e2e6466f6d03ff630ca68d3cc",
"sha256:d055c2f9d38dc53c808f6fdc8eab7360b6fdbbde02340ed25cfbcd817c62469e"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'",
"version": "==1.26.15"
"markers": "python_version >= '3.7'",
"version": "==2.0.2"
},
"websocket-client": {
"hashes": [
"sha256:3f09e6d8230892547132177f575a4e3e73cfdf06526e20cc02aa1c3b47184d40",
"sha256:cdf5877568b7e83aa7cf2244ab56a3213de587bbe0ce9d8b9600fc77b455d89e"
"sha256:c7d67c13b928645f259d9b847ab5b57fd2d127213ca41ebd880de1f553b7c23b",
"sha256:f8c64e28cd700e7ba1f04350d66422b6833b82a796b525a51e740b8cc8dab4b1"
],
"markers": "python_version >= '3.7'",
"version": "==1.5.1"
"version": "==1.5.2"
}
},
"develop": {
@ -444,7 +417,7 @@
"sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330",
"sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"
],
"markers": "python_version < '3.11' and python_version >= '3.7'",
"markers": "python_version >= '3.11'",
"version": "==5.1.1"
},
"executing": {
@ -497,11 +470,11 @@
},
"ipython": {
"hashes": [
"sha256:5b54478e459155a326bf5f42ee4f29df76258c0279c36f21d71ddb560f88b156",
"sha256:735cede4099dbc903ee540307b9171fbfef4aa75cfcacc5a273b2cda2f02be04"
"sha256:7dff3fad32b97f6488e02f87b970f309d082f758d7b7fc252e3b19ee0e432dbb",
"sha256:ffca270240fbd21b06b2974e14a86494d6d29290184e788275f55e0b55914926"
],
"markers": "python_version < '3.11' and python_version >= '3.7'",
"version": "==8.11.0"
"markers": "python_version >= '3.11'",
"version": "==8.13.2"
},
"jedi": {
"hashes": [
@ -566,11 +539,11 @@
},
"pygments": {
"hashes": [
"sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297",
"sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717"
"sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c",
"sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1"
],
"markers": "python_version >= '3.6'",
"version": "==2.14.0"
"markers": "python_version >= '3.7'",
"version": "==2.15.1"
},
"six": {
"hashes": [
@ -587,14 +560,6 @@
],
"version": "==0.6.2"
},
"tomli": {
"hashes": [
"sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc",
"sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"
],
"markers": "python_version < '3.11'",
"version": "==2.0.1"
},
"traitlets": {
"hashes": [
"sha256:9e6ec080259b9a5940c797d58b613b5e31441c2257b87c2e795c5228ae80d2d8",

View file

@ -0,0 +1,32 @@
#!/usr/bin/env python
from http import HTTPStatus
import yaml
import pytest
pytestmark = pytest.mark.docker
def test_capi_whitelists(crowdsec, tmp_path_factory, flavor,):
"""Test CAPI_WHITELISTS_PATH"""
env = {
"CAPI_WHITELISTS_PATH": "/path/to/whitelists.yaml"
}
whitelists = tmp_path_factory.mktemp("whitelists")
with open(whitelists / "whitelists.yaml", "w") as f:
yaml.dump({"ips": ["1.2.3.4", "2.3.4.5"], "cidrs": ["1.2.3.0/24"]}, f)
volumes = {
whitelists / "whitelists.yaml": {"bind": "/path/to/whitelists.yaml", "mode": "ro"}
}
with crowdsec(flavor=flavor, environment=env, volumes=volumes) as cs:
cs.wait_for_log("*Starting processing data*")
cs.wait_for_http(8080, '/health', want_status=HTTPStatus.OK)
res = cs.cont.exec_run(f'cscli config show-yaml')
assert res.exit_code == 0
stdout = res.output.decode()
y = yaml.safe_load(stdout)
assert y['api']['server']['capi_whitelists_path'] == '/path/to/whitelists.yaml'

12
go.mod
View file

@ -48,11 +48,11 @@ require (
github.com/prometheus/client_model v0.3.0
github.com/prometheus/prom2json v1.3.0
github.com/r3labs/diff/v2 v2.14.1
github.com/sirupsen/logrus v1.9.0
github.com/sirupsen/logrus v1.9.2
github.com/spf13/cobra v1.7.0
github.com/stretchr/testify v1.8.2
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d
golang.org/x/mod v0.8.0
github.com/stretchr/testify v1.8.3
golang.org/x/crypto v0.1.0
golang.org/x/mod v0.6.0
google.golang.org/grpc v1.47.0
google.golang.org/protobuf v1.28.1
gopkg.in/natefinch/lumberjack.v2 v2.2.1
@ -72,6 +72,7 @@ require (
github.com/cespare/xxhash/v2 v2.1.2
github.com/corazawaf/coraza/v3 v3.0.0-rc.2
github.com/coreos/go-systemd/v22 v22.5.0
github.com/crowdsecurity/go-cs-lib v0.0.0-20230531105801-4c1535c2b3bd
github.com/goccy/go-yaml v1.9.7
github.com/gofrs/uuid v4.0.0+incompatible
github.com/golang-jwt/jwt/v4 v4.2.0
@ -85,6 +86,7 @@ require (
github.com/texttheater/golang-levenshtein/levenshtein v0.0.0-20200805054039-cae8b0eaed6c
github.com/umahmood/haversine v0.0.0-20151105152445-808ab04add26
github.com/wasilibs/go-re2 v0.2.1
golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc
golang.org/x/sys v0.7.0
gopkg.in/yaml.v3 v3.0.1
k8s.io/apiserver v0.22.5
@ -103,7 +105,7 @@ require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/corazawaf/libinjection-go v0.1.2 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/docker/distribution v2.8.0+incompatible // indirect
github.com/docker/distribution v2.8.2+incompatible // indirect
github.com/docker/go-units v0.4.0 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-logr/logr v1.2.3 // indirect

19
go.sum
View file

@ -174,6 +174,8 @@ github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/crowdsecurity/dlog v0.0.0-20170105205344-4fb5f8204f26 h1:r97WNVC30Uen+7WnLs4xDScS/Ex988+id2k6mDf8psU=
github.com/crowdsecurity/dlog v0.0.0-20170105205344-4fb5f8204f26/go.mod h1:zpv7r+7KXwgVUZnUNjyP22zc/D7LKjyoY02weH2RBbk=
github.com/crowdsecurity/go-cs-lib v0.0.0-20230531105801-4c1535c2b3bd h1:Y70ceDKAKYFXTnxEjXuBDSh07umvDhbX3PCCYhdtsZ0=
github.com/crowdsecurity/go-cs-lib v0.0.0-20230531105801-4c1535c2b3bd/go.mod h1:9JJLSpGj1ZXnROV3xAcJvS/HTaUvuA8K3gGOpO4tfVc=
github.com/crowdsecurity/grokky v0.2.1 h1:t4VYnDlAd0RjDM2SlILalbwfCrQxtJSMGdQOR0zwkE4=
github.com/crowdsecurity/grokky v0.2.1/go.mod h1:33usDIYzGDsgX1kHAThCbseso6JuWNJXOzRQDGXHtWM=
github.com/crowdsecurity/machineid v1.0.2 h1:wpkpsUghJF8Khtmn/tg6GxgdhLA1Xflerh5lirI+bdc=
@ -185,8 +187,8 @@ github.com/dghubble/sling v1.3.0 h1:pZHjCJq4zJvc6qVQ5wN1jo5oNZlNE0+8T/h0XeXBUKU=
github.com/dghubble/sling v1.3.0/go.mod h1:XXShWaBWKzNLhu2OxikSNFrlsvowtz4kyRuXUG7oQKY=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/docker/distribution v2.8.0+incompatible h1:l9EaZDICImO1ngI+uTifW+ZYvvz7fKISBAKpg+MbWbY=
github.com/docker/distribution v2.8.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v20.10.24+incompatible h1:Ugvxm7a8+Gz6vqQYQQ2W7GYq5EUPaAiuPgIfVyI3dYE=
github.com/docker/docker v20.10.24+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
@ -847,8 +849,8 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/sirupsen/logrus v1.9.2 h1:oxx1eChJGI6Uks2ZC4W1zpLlVgqB8ner4EuQwV4Ik1Y=
github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
@ -887,8 +889,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tetratelabs/wazero v1.0.0-rc.2 h1:OA3UUynnoqxrjCQ94mpAtdO4/oMxFQVNL2BXDMOc66Q=
github.com/tetratelabs/wazero v1.0.0-rc.2/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ=
@ -1016,8 +1018,9 @@ golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWP
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -1028,6 +1031,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc h1:mCRnTeVUjcrhlRmO0VK8a6k6Rrf6TF9htwo2pJVSjIU=
golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=

View file

@ -1,7 +1,4 @@
BUILD_REQUIRE_GO_MAJOR ?= 1
BUILD_REQUIRE_GO_MINOR ?= 20
BUILD_GOVERSION = $(subst go,,$(shell go env GOVERSION))
go_major_minor = $(subst ., ,$(BUILD_GOVERSION))
@ -10,8 +7,19 @@ GO_MINOR_VERSION = $(word 2, $(go_major_minor))
GO_VERSION_VALIDATION_ERR_MSG = Golang version ($(BUILD_GOVERSION)) is not supported, please use at least $(BUILD_REQUIRE_GO_MAJOR).$(BUILD_REQUIRE_GO_MINOR)
.PHONY: goversion
goversion:
goversion: $(if $(findstring devel,$(shell go env GOVERSION)),goversion_devel,goversion_check)
.PHONY: goversion_devel
goversion_devel:
$(warning WARNING: You are using a development version of Golang ($(BUILD_GOVERSION)) which is not supported. For production environments, use a stable version (at least $(BUILD_REQUIRE_GO_MAJOR).$(BUILD_REQUIRE_GO_MINOR)))
$(info )
.PHONY: goversion_check
goversion_check:
ifneq ($(OS), Windows_NT)
@if [ $(GO_MAJOR_VERSION) -gt $(BUILD_REQUIRE_GO_MAJOR) ]; then \
exit 0; \

View file

@ -1,3 +1,8 @@
BUILD_CODENAME ?= alphaga
GOARCH ?= $(shell go env GOARCH)
BUILD_TAG ?= $(shell git rev-parse HEAD)
ifeq ($(OS), Windows_NT)
SHELL := pwsh.exe
.SHELLFLAGS := -NoProfile -Command

View file

@ -1,5 +1,3 @@
# FreeBSD specific
MAKE=gmake
$(info building for FreeBSD)

View file

@ -1,5 +1,3 @@
# Linux specific
MAKE=make
$(info Building for linux)

View file

@ -1,5 +1,3 @@
# OpenBSD specific
MAKE=gmake
$(info building for OpenBSD)

View file

@ -6,12 +6,9 @@ MKDIR=mkdir -p
# Go should not be required to run functional tests
GOOS ?= $(shell go env GOOS)
GOARCH ?= $(shell go env GOARCH)
#Current versioning information from env
BUILD_VERSION?=$(shell git describe --tags)
BUILD_CODENAME="alphaga"
BUILD_TIMESTAMP=$(shell date +%F"_"%T)
BUILD_TAG?=$(shell git rev-parse HEAD)
DEFAULT_CONFIGDIR?=/etc/crowdsec
DEFAULT_DATADIR?=/var/lib/crowdsec/data

View file

@ -4,16 +4,11 @@ MAKE=make
GOOS=windows
PREFIX=$(shell $$env:TEMP)
GOOS ?= $(shell go env GOOS)
GOARCH ?= $(shell go env GOARCH)
#Current versioning information from env
#BUILD_VERSION?=$(shell (Invoke-WebRequest -UseBasicParsing -Uri https://api.github.com/repos/crowdsecurity/crowdsec/releases/latest).Content | jq -r '.tag_name')
#hardcode it till i find a workaround
BUILD_VERSION?=$(shell git describe --tags $$(git rev-list --tags --max-count=1))
BUILD_CODENAME?=alphaga
BUILD_TIMESTAMP?=$(shell Get-Date -Format "yyyy-MM-dd_HH:mm:ss")
BUILD_TAG?=$(shell git rev-parse HEAD)
DEFAULT_CONFIGDIR?=C:\\ProgramData\\CrowdSec\\config
DEFAULT_DATADIR?=C:\\ProgramData\\CrowdSec\\data
@ -23,5 +18,3 @@ CP=Copy-Item
CPR=Copy-Item -Recurse
MKDIR=New-Item -ItemType directory
WIN_IGNORE_ERR=; exit 0
$(info Building for windows)

View file

@ -15,6 +15,8 @@ import (
tomb "gopkg.in/tomb.v2"
"gopkg.in/yaml.v2"
"github.com/crowdsecurity/go-cs-lib/pkg/trace"
"github.com/crowdsecurity/crowdsec/pkg/acquisition/configuration"
cloudwatchacquisition "github.com/crowdsecurity/crowdsec/pkg/acquisition/modules/cloudwatch"
dockeracquisition "github.com/crowdsecurity/crowdsec/pkg/acquisition/modules/docker"
@ -243,7 +245,7 @@ func GetMetrics(sources []DataSource, aggregated bool) error {
}
func transform(transformChan chan types.Event, output chan types.Event, AcquisTomb *tomb.Tomb, transformRuntime *vm.Program, logger *log.Entry) {
defer types.CatchPanic("crowdsec/acquis")
defer trace.CatchPanic("crowdsec/acquis")
logger.Infof("transformer started")
for {
select {
@ -298,7 +300,7 @@ func StartAcquisition(sources []DataSource, output chan types.Event, AcquisTomb
log.Debugf("starting one source %d/%d ->> %T", i, len(sources), subsrc)
AcquisTomb.Go(func() error {
defer types.CatchPanic("crowdsec/acquis")
defer trace.CatchPanic("crowdsec/acquis")
var err error
outChan := output

View file

@ -13,9 +13,10 @@ import (
tomb "gopkg.in/tomb.v2"
"gopkg.in/yaml.v2"
"github.com/crowdsecurity/go-cs-lib/pkg/cstest"
"github.com/crowdsecurity/crowdsec/pkg/acquisition/configuration"
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
"github.com/crowdsecurity/crowdsec/pkg/cstest"
"github.com/crowdsecurity/crowdsec/pkg/types"
)

View file

@ -9,9 +9,10 @@ import (
"testing"
"time"
"github.com/crowdsecurity/go-cs-lib/pkg/cstest"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/cloudwatchlogs"
"github.com/crowdsecurity/crowdsec/pkg/cstest"
"github.com/crowdsecurity/crowdsec/pkg/types"
log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/require"

View file

@ -11,7 +11,8 @@ import (
"testing"
"time"
"github.com/crowdsecurity/crowdsec/pkg/cstest"
"github.com/crowdsecurity/go-cs-lib/pkg/cstest"
"github.com/crowdsecurity/crowdsec/pkg/types"
dockerTypes "github.com/docker/docker/api/types"
dockerContainer "github.com/docker/docker/api/types/container"

View file

@ -14,6 +14,8 @@ import (
"strings"
"time"
"github.com/crowdsecurity/go-cs-lib/pkg/trace"
"github.com/fsnotify/fsnotify"
"github.com/nxadm/tail"
"github.com/pkg/errors"
@ -39,6 +41,7 @@ type FileConfiguration struct {
Filename string
ForceInotify bool `yaml:"force_inotify"`
MaxBufferSize int `yaml:"max_buffer_size"`
PollWithoutInotify bool `yaml:"poll_without_inotify"`
configuration.DataSourceCommonCfg `yaml:",inline"`
}
@ -328,14 +331,14 @@ func (f *FileSource) StreamingAcquisition(out chan types.Event, t *tomb.Tomb) er
continue
}
tail, err := tail.TailFile(file, tail.Config{ReOpen: true, Follow: true, Poll: true, Location: &tail.SeekInfo{Offset: 0, Whence: io.SeekEnd}, Logger: log.NewEntry(log.StandardLogger())})
tail, err := tail.TailFile(file, tail.Config{ReOpen: true, Follow: true, Poll: f.config.PollWithoutInotify, Location: &tail.SeekInfo{Offset: 0, Whence: io.SeekEnd}, Logger: log.NewEntry(log.StandardLogger())})
if err != nil {
f.logger.Errorf("Could not start tailing file %s : %s", file, err)
continue
}
f.tails[file] = true
t.Go(func() error {
defer types.CatchPanic("crowdsec/acquis/file/live/fsnotify")
defer trace.CatchPanic("crowdsec/acquis/file/live/fsnotify")
return f.tailFile(out, t, tail)
})
}
@ -411,14 +414,14 @@ func (f *FileSource) monitorNewFiles(out chan types.Event, t *tomb.Tomb) error {
continue
}
//Slightly different parameters for Location, as we want to read the first lines of the newly created file
tail, err := tail.TailFile(event.Name, tail.Config{ReOpen: true, Follow: true, Poll: true, Location: &tail.SeekInfo{Offset: 0, Whence: io.SeekStart}})
tail, err := tail.TailFile(event.Name, tail.Config{ReOpen: true, Follow: true, Poll: f.config.PollWithoutInotify, Location: &tail.SeekInfo{Offset: 0, Whence: io.SeekStart}})
if err != nil {
logger.Errorf("Could not start tailing file %s : %s", event.Name, err)
break
}
f.tails[event.Name] = true
t.Go(func() error {
defer types.CatchPanic("crowdsec/acquis/tailfile")
defer trace.CatchPanic("crowdsec/acquis/tailfile")
return f.tailFile(out, t, tail)
})
}

View file

@ -13,8 +13,9 @@ import (
"github.com/stretchr/testify/require"
"gopkg.in/tomb.v2"
"github.com/crowdsecurity/go-cs-lib/pkg/cstest"
fileacquisition "github.com/crowdsecurity/crowdsec/pkg/acquisition/modules/file"
"github.com/crowdsecurity/crowdsec/pkg/cstest"
"github.com/crowdsecurity/crowdsec/pkg/types"
)

View file

@ -15,6 +15,8 @@ import (
"gopkg.in/tomb.v2"
"gopkg.in/yaml.v2"
"github.com/crowdsecurity/go-cs-lib/pkg/trace"
"github.com/crowdsecurity/crowdsec/pkg/acquisition/configuration"
"github.com/crowdsecurity/crowdsec/pkg/types"
)
@ -257,7 +259,7 @@ func (j *JournalCtlSource) GetName() string {
}
func (j *JournalCtlSource) OneShotAcquisition(out chan types.Event, t *tomb.Tomb) error {
defer types.CatchPanic("crowdsec/acquis/journalctl/oneshot")
defer trace.CatchPanic("crowdsec/acquis/journalctl/oneshot")
err := j.runJournalCtl(out, t)
j.logger.Debug("Oneshot journalctl acquisition is done")
return err
@ -266,7 +268,7 @@ func (j *JournalCtlSource) OneShotAcquisition(out chan types.Event, t *tomb.Tomb
func (j *JournalCtlSource) StreamingAcquisition(out chan types.Event, t *tomb.Tomb) error {
t.Go(func() error {
defer types.CatchPanic("crowdsec/acquis/journalctl/streaming")
defer trace.CatchPanic("crowdsec/acquis/journalctl/streaming")
return j.runJournalCtl(out, t)
})
return nil

View file

@ -8,7 +8,8 @@ import (
"testing"
"time"
"github.com/crowdsecurity/crowdsec/pkg/cstest"
"github.com/crowdsecurity/go-cs-lib/pkg/cstest"
"github.com/crowdsecurity/crowdsec/pkg/types"
log "github.com/sirupsen/logrus"
"github.com/sirupsen/logrus/hooks/test"

View file

@ -17,6 +17,8 @@ import (
"gopkg.in/tomb.v2"
"gopkg.in/yaml.v2"
"github.com/crowdsecurity/go-cs-lib/pkg/trace"
"github.com/crowdsecurity/crowdsec/pkg/acquisition/configuration"
"github.com/crowdsecurity/crowdsec/pkg/types"
)
@ -190,7 +192,7 @@ func (k *KafkaSource) StreamingAcquisition(out chan types.Event, t *tomb.Tomb) e
k.logger.Infof("start reader on topic '%s'", k.Config.Topic)
t.Go(func() error {
defer types.CatchPanic("crowdsec/acquis/kafka/live")
defer trace.CatchPanic("crowdsec/acquis/kafka/live")
return k.RunReader(out, t)
})
@ -212,7 +214,13 @@ func (kc *KafkaConfiguration) NewTLSConfig() (*tls.Config, error) {
if err != nil {
return &tlsConfig, err
}
caCertPool := x509.NewCertPool()
caCertPool, err := x509.SystemCertPool()
if err != nil {
return &tlsConfig, fmt.Errorf("unable to load system CA certificates: %w", err)
}
if caCertPool == nil {
caCertPool = x509.NewCertPool()
}
caCertPool.AppendCertsFromPEM(caCert)
tlsConfig.RootCAs = caCertPool

View file

@ -8,7 +8,8 @@ import (
"testing"
"time"
"github.com/crowdsecurity/crowdsec/pkg/cstest"
"github.com/crowdsecurity/go-cs-lib/pkg/cstest"
"github.com/crowdsecurity/crowdsec/pkg/types"
"github.com/segmentio/kafka-go"
log "github.com/sirupsen/logrus"

View file

@ -19,6 +19,8 @@ import (
"gopkg.in/tomb.v2"
"gopkg.in/yaml.v2"
"github.com/crowdsecurity/go-cs-lib/pkg/trace"
"github.com/crowdsecurity/crowdsec/pkg/acquisition/configuration"
"github.com/crowdsecurity/crowdsec/pkg/types"
)
@ -490,7 +492,7 @@ func (k *KinesisSource) ReadFromStream(out chan types.Event, t *tomb.Tomb) error
for _, shard := range shards.Shards {
shardId := *shard.ShardId
k.shardReaderTomb.Go(func() error {
defer types.CatchPanic("crowdsec/acquis/kinesis/streaming/shard")
defer trace.CatchPanic("crowdsec/acquis/kinesis/streaming/shard")
return k.ReadFromShard(out, shardId)
})
}
@ -514,7 +516,7 @@ func (k *KinesisSource) ReadFromStream(out chan types.Event, t *tomb.Tomb) error
func (k *KinesisSource) StreamingAcquisition(out chan types.Event, t *tomb.Tomb) error {
t.Go(func() error {
defer types.CatchPanic("crowdsec/acquis/kinesis/streaming")
defer trace.CatchPanic("crowdsec/acquis/kinesis/streaming")
if k.Config.UseEnhancedFanOut {
return k.EnhancedRead(out, t)
} else {

View file

@ -12,10 +12,11 @@ import (
"testing"
"time"
"github.com/crowdsecurity/go-cs-lib/pkg/cstest"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/kinesis"
"github.com/crowdsecurity/crowdsec/pkg/cstest"
"github.com/crowdsecurity/crowdsec/pkg/types"
log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"

View file

@ -8,6 +8,8 @@ import (
"net/http"
"strings"
"github.com/crowdsecurity/go-cs-lib/pkg/trace"
"github.com/crowdsecurity/crowdsec/pkg/acquisition/configuration"
"github.com/crowdsecurity/crowdsec/pkg/types"
"github.com/pkg/errors"
@ -133,7 +135,7 @@ func (ka *KubernetesAuditSource) OneShotAcquisition(out chan types.Event, t *tom
func (ka *KubernetesAuditSource) StreamingAcquisition(out chan types.Event, t *tomb.Tomb) error {
ka.outChan = out
t.Go(func() error {
defer types.CatchPanic("crowdsec/acquis/k8s-audit/live")
defer trace.CatchPanic("crowdsec/acquis/k8s-audit/live")
ka.logger.Infof("Starting k8s-audit server on %s:%d%s", ka.config.ListenAddr, ka.config.ListenPort, ka.config.WebhookPath)
t.Go(func() error {
err := ka.server.ListenAndServe()

View file

@ -4,8 +4,9 @@ import (
"testing"
"time"
"github.com/crowdsecurity/go-cs-lib/pkg/cstest"
"github.com/stretchr/testify/require"
"github.com/crowdsecurity/crowdsec/pkg/cstest"
)
func TestPri(t *testing.T) {

View file

@ -12,6 +12,8 @@ import (
"gopkg.in/tomb.v2"
"gopkg.in/yaml.v2"
"github.com/crowdsecurity/go-cs-lib/pkg/trace"
"github.com/crowdsecurity/crowdsec/pkg/acquisition/configuration"
"github.com/crowdsecurity/crowdsec/pkg/acquisition/modules/syslog/internal/parser/rfc3164"
"github.com/crowdsecurity/crowdsec/pkg/acquisition/modules/syslog/internal/parser/rfc5424"
@ -142,7 +144,7 @@ func (s *SyslogSource) StreamingAcquisition(out chan types.Event, t *tomb.Tomb)
}
s.serverTomb = s.server.StartServer()
t.Go(func() error {
defer types.CatchPanic("crowdsec/acquis/syslog/live")
defer trace.CatchPanic("crowdsec/acquis/syslog/live")
return s.handleSyslogMsg(out, t, c)
})
return nil

View file

@ -7,7 +7,8 @@ import (
"testing"
"time"
"github.com/crowdsecurity/crowdsec/pkg/cstest"
"github.com/crowdsecurity/go-cs-lib/pkg/cstest"
"github.com/crowdsecurity/crowdsec/pkg/types"
log "github.com/sirupsen/logrus"
"gopkg.in/tomb.v2"

View file

@ -17,6 +17,8 @@ import (
"gopkg.in/tomb.v2"
"gopkg.in/yaml.v2"
"github.com/crowdsecurity/go-cs-lib/pkg/trace"
"github.com/crowdsecurity/crowdsec/pkg/acquisition/configuration"
"github.com/crowdsecurity/crowdsec/pkg/types"
)
@ -321,7 +323,7 @@ func (w *WinEventLogSource) CanRun() error {
func (w *WinEventLogSource) StreamingAcquisition(out chan types.Event, t *tomb.Tomb) error {
t.Go(func() error {
defer types.CatchPanic("crowdsec/acquis/wineventlog/streaming")
defer trace.CatchPanic("crowdsec/acquis/wineventlog/streaming")
return w.getEvents(out, t)
})
return nil

View file

@ -7,10 +7,12 @@ import (
"github.com/antonmedv/expr"
"github.com/antonmedv/expr/vm"
log "github.com/sirupsen/logrus"
"golang.org/x/exp/slices"
"github.com/crowdsecurity/crowdsec/pkg/exprhelpers"
"github.com/crowdsecurity/crowdsec/pkg/models"
"github.com/crowdsecurity/crowdsec/pkg/types"
log "github.com/sirupsen/logrus"
)
const (
@ -131,7 +133,7 @@ func EventToContext(events []types.Event) (models.Meta, []error) {
errors = append(errors, fmt.Errorf("unexpected return type for %s : %T", key, output))
continue
}
if val != "" && !types.InSlice(val, tmpContext[key]) {
if val != "" && !slices.Contains(tmpContext[key], val) {
tmpContext[key] = append(tmpContext[key], val)
}
}

View file

@ -8,7 +8,8 @@ import (
"reflect"
"testing"
"github.com/crowdsecurity/crowdsec/pkg/cwversion"
"github.com/crowdsecurity/go-cs-lib/pkg/version"
"github.com/crowdsecurity/crowdsec/pkg/models"
log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
@ -31,7 +32,7 @@ func TestAlertsListAsMachine(t *testing.T) {
client, err := NewClient(&Config{
MachineID: "test_login",
Password: "test_password",
UserAgent: fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
UserAgent: fmt.Sprintf("crowdsec/%s", version.String()),
URL: apiURL,
VersionPrefix: "v1",
})
@ -233,7 +234,7 @@ func TestAlertsGetAsMachine(t *testing.T) {
client, err := NewClient(&Config{
MachineID: "test_login",
Password: "test_password",
UserAgent: fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
UserAgent: fmt.Sprintf("crowdsec/%s", version.String()),
URL: apiURL,
VersionPrefix: "v1",
})
@ -423,7 +424,7 @@ func TestAlertsCreateAsMachine(t *testing.T) {
client, err := NewClient(&Config{
MachineID: "test_login",
Password: "test_password",
UserAgent: fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
UserAgent: fmt.Sprintf("crowdsec/%s", version.String()),
URL: apiURL,
VersionPrefix: "v1",
})
@ -467,7 +468,7 @@ func TestAlertsDeleteAsMachine(t *testing.T) {
client, err := NewClient(&Config{
MachineID: "test_login",
Password: "test_password",
UserAgent: fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
UserAgent: fmt.Sprintf("crowdsec/%s", version.String()),
URL: apiURL,
VersionPrefix: "v1",
})

View file

@ -10,7 +10,8 @@ import (
"net/url"
"testing"
"github.com/crowdsecurity/crowdsec/pkg/cwversion"
"github.com/crowdsecurity/go-cs-lib/pkg/version"
"github.com/crowdsecurity/crowdsec/pkg/models"
log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
@ -86,7 +87,7 @@ func TestWatcherRegister(t *testing.T) {
clientconfig := Config{
MachineID: "test_login",
Password: "test_password",
UserAgent: fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
UserAgent: fmt.Sprintf("crowdsec/%s", version.String()),
URL: apiURL,
VersionPrefix: "v1",
}
@ -128,7 +129,7 @@ func TestWatcherAuth(t *testing.T) {
clientConfig := &Config{
MachineID: "test_login",
Password: "test_password",
UserAgent: fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
UserAgent: fmt.Sprintf("crowdsec/%s", version.String()),
URL: apiURL,
VersionPrefix: "v1",
Scenarios: []string{"crowdsecurity/test"},
@ -216,7 +217,7 @@ func TestWatcherUnregister(t *testing.T) {
mycfg := &Config{
MachineID: "test_login",
Password: "test_password",
UserAgent: fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
UserAgent: fmt.Sprintf("crowdsec/%s", version.String()),
URL: apiURL,
VersionPrefix: "v1",
Scenarios: []string{"crowdsecurity/test"},
@ -270,7 +271,7 @@ func TestWatcherEnroll(t *testing.T) {
mycfg := &Config{
MachineID: "test_login",
Password: "test_password",
UserAgent: fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
UserAgent: fmt.Sprintf("crowdsec/%s", version.String()),
URL: apiURL,
VersionPrefix: "v1",
Scenarios: []string{"crowdsecurity/test"},

View file

@ -8,7 +8,8 @@ import (
"testing"
"time"
"github.com/crowdsecurity/crowdsec/pkg/cwversion"
"github.com/crowdsecurity/go-cs-lib/pkg/version"
"github.com/stretchr/testify/assert"
)
@ -23,7 +24,7 @@ func TestNewRequestInvalid(t *testing.T) {
client, err := NewClient(&Config{
MachineID: "test_login",
Password: "test_password",
UserAgent: fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
UserAgent: fmt.Sprintf("crowdsec/%s", version.String()),
URL: apiURL,
VersionPrefix: "v1",
})
@ -56,7 +57,7 @@ func TestNewRequestTimeout(t *testing.T) {
client, err := NewClient(&Config{
MachineID: "test_login",
Password: "test_password",
UserAgent: fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
UserAgent: fmt.Sprintf("crowdsec/%s", version.String()),
URL: apiURL,
VersionPrefix: "v1",
})

View file

@ -11,8 +11,9 @@ import (
"github.com/stretchr/testify/assert"
"github.com/crowdsecurity/crowdsec/pkg/cwversion"
log "github.com/sirupsen/logrus"
"github.com/crowdsecurity/go-cs-lib/pkg/version"
)
/*this is a ripoff of google/go-github approach :
@ -55,7 +56,7 @@ func TestNewClientOk(t *testing.T) {
client, err := NewClient(&Config{
MachineID: "test_login",
Password: "test_password",
UserAgent: fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
UserAgent: fmt.Sprintf("crowdsec/%s", version.String()),
URL: apiURL,
VersionPrefix: "v1",
})
@ -92,7 +93,7 @@ func TestNewClientKo(t *testing.T) {
client, err := NewClient(&Config{
MachineID: "test_login",
Password: "test_password",
UserAgent: fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
UserAgent: fmt.Sprintf("crowdsec/%s", version.String()),
URL: apiURL,
VersionPrefix: "v1",
})
@ -143,7 +144,7 @@ func TestNewClientRegisterKO(t *testing.T) {
_, err = RegisterClient(&Config{
MachineID: "test_login",
Password: "test_password",
UserAgent: fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
UserAgent: fmt.Sprintf("crowdsec/%s", version.String()),
URL: apiURL,
VersionPrefix: "v1",
}, &http.Client{})
@ -173,7 +174,7 @@ func TestNewClientRegisterOK(t *testing.T) {
client, err := RegisterClient(&Config{
MachineID: "test_login",
Password: "test_password",
UserAgent: fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
UserAgent: fmt.Sprintf("crowdsec/%s", version.String()),
URL: apiURL,
VersionPrefix: "v1",
}, &http.Client{})
@ -201,7 +202,7 @@ func TestNewClientBadAnswer(t *testing.T) {
_, err = RegisterClient(&Config{
MachineID: "test_login",
Password: "test_password",
UserAgent: fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
UserAgent: fmt.Sprintf("crowdsec/%s", version.String()),
URL: apiURL,
VersionPrefix: "v1",
}, &http.Client{})

View file

@ -6,6 +6,8 @@ import (
"fmt"
"net/http"
"github.com/crowdsecurity/go-cs-lib/pkg/ptr"
"github.com/crowdsecurity/crowdsec/pkg/models"
"github.com/crowdsecurity/crowdsec/pkg/modelscapi"
"github.com/crowdsecurity/crowdsec/pkg/types"
@ -102,10 +104,10 @@ func (s *DecisionsService) GetDecisionsFromGroups(decisionsGroups []*modelscapi.
partialDecisions[idx] = &models.Decision{
Scenario: decisionsGroup.Scenario,
Scope: decisionsGroup.Scope,
Type: types.StrPtr(types.DecisionTypeBan),
Type: ptr.Of(types.DecisionTypeBan),
Value: decision.Value,
Duration: decision.Duration,
Origin: types.StrPtr(types.CAPIOrigin),
Origin: ptr.Of(types.CAPIOrigin),
}
}
decisions = append(decisions, partialDecisions...)
@ -138,10 +140,10 @@ func (s *DecisionsService) FetchV3Decisions(ctx context.Context, url string) (*m
partialDecisions[idx] = &models.Decision{
Scenario: &scenarioDeleted,
Scope: decisionsGroup.Scope,
Type: types.StrPtr(types.DecisionTypeBan),
Type: ptr.Of(types.DecisionTypeBan),
Value: &decision,
Duration: &durationDeleted,
Origin: types.StrPtr(types.CAPIOrigin),
Origin: ptr.Of(types.CAPIOrigin),
}
}
v2Decisions.Deleted = append(v2Decisions.Deleted, partialDecisions...)
@ -210,7 +212,7 @@ func (s *DecisionsService) GetDecisionsFromBlocklist(ctx context.Context, blockl
Type: blocklist.Remediation,
Value: &decision,
Duration: blocklist.Duration,
Origin: types.StrPtr(types.ListOrigin),
Origin: ptr.Of(types.ListOrigin),
})
}

View file

@ -8,10 +8,11 @@ import (
"reflect"
"testing"
"github.com/crowdsecurity/crowdsec/pkg/cwversion"
"github.com/crowdsecurity/go-cs-lib/pkg/ptr"
"github.com/crowdsecurity/go-cs-lib/pkg/version"
"github.com/crowdsecurity/crowdsec/pkg/models"
"github.com/crowdsecurity/crowdsec/pkg/modelscapi"
"github.com/crowdsecurity/crowdsec/pkg/types"
log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -460,7 +461,7 @@ func TestDecisionsFromBlocklist(t *testing.T) {
Remediation: &tremediationBlocklist,
Name: &tnameBlocklist,
Duration: &tdurationBlocklist,
}, types.StrPtr("Sun, 01 Jan 2023 01:01:01 GMT"))
}, ptr.Of("Sun, 01 Jan 2023 01:01:01 GMT"))
require.NoError(t, err)
assert.False(t, isModified)
_, isModified, err = newcli.Decisions.GetDecisionsFromBlocklist(context.Background(), &modelscapi.BlocklistLink{
@ -469,7 +470,7 @@ func TestDecisionsFromBlocklist(t *testing.T) {
Remediation: &tremediationBlocklist,
Name: &tnameBlocklist,
Duration: &tdurationBlocklist,
}, types.StrPtr("Mon, 02 Jan 2023 01:01:01 GMT"))
}, ptr.Of("Mon, 02 Jan 2023 01:01:01 GMT"))
require.NoError(t, err)
assert.True(t, isModified)
}
@ -495,7 +496,7 @@ func TestDeleteDecisions(t *testing.T) {
client, err := NewClient(&Config{
MachineID: "test_login",
Password: "test_password",
UserAgent: fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
UserAgent: fmt.Sprintf("crowdsec/%s", version.String()),
URL: apiURL,
VersionPrefix: "v1",
})

View file

@ -6,9 +6,10 @@ import (
"net/http"
"time"
"github.com/crowdsecurity/crowdsec/pkg/types"
log "github.com/sirupsen/logrus"
tomb "gopkg.in/tomb.v2"
"github.com/crowdsecurity/go-cs-lib/pkg/trace"
)
type HeartBeatService service
@ -32,7 +33,7 @@ func (h *HeartBeatService) Ping(ctx context.Context) (bool, *Response, error) {
func (h *HeartBeatService) StartHeartBeat(ctx context.Context, t *tomb.Tomb) {
t.Go(func() error {
defer types.CatchPanic("crowdsec/apiClient/heartbeat")
defer trace.CatchPanic("crowdsec/apiClient/heartbeat")
hbTimer := time.NewTicker(1 * time.Minute)
for {
select {

View file

@ -28,7 +28,7 @@ type LAPI struct {
func SetupLAPITest(t *testing.T) LAPI {
t.Helper()
router, loginResp, config, err := InitMachineTest()
router, loginResp, config, err := InitMachineTest(t)
if err != nil {
t.Fatal(err)
}
@ -68,8 +68,8 @@ func (l *LAPI) RecordResponse(verb string, url string, body *strings.Reader, aut
return w
}
func InitMachineTest() (*gin.Engine, models.WatcherAuthResponse, csconfig.Config, error) {
router, config, err := NewAPITest()
func InitMachineTest(t *testing.T) (*gin.Engine, models.WatcherAuthResponse, csconfig.Config, error) {
router, config, err := NewAPITest(t)
if err != nil {
return nil, models.WatcherAuthResponse{}, config, fmt.Errorf("unable to run local API: %s", err)
}
@ -151,7 +151,7 @@ func TestCreateAlert(t *testing.T) {
func TestCreateAlertChannels(t *testing.T) {
apiServer, config, err := NewAPIServer()
apiServer, config, err := NewAPIServer(t)
if err != nil {
log.Fatalln(err)
}
@ -443,7 +443,7 @@ func TestDeleteAlertByID(t *testing.T) {
}
func TestDeleteAlertTrustedIPS(t *testing.T) {
cfg := LoadTestConfig()
cfg := LoadTestConfig(t)
// IPv6 mocking doesn't seem to work.
// cfg.API.Server.TrustedIPs = []string{"1.2.3.4", "1.2.4.0/24", "::"}
cfg.API.Server.TrustedIPs = []string{"1.2.3.4", "1.2.4.0/24"}

View file

@ -11,7 +11,7 @@ import (
)
func TestAPIKey(t *testing.T) {
router, config, err := NewAPITest()
router, config, err := NewAPITest(t)
if err != nil {
log.Fatalf("unable to run local API: %s", err)
}

View file

@ -15,11 +15,15 @@ import (
"github.com/go-openapi/strfmt"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
"golang.org/x/exp/slices"
"gopkg.in/tomb.v2"
"github.com/crowdsecurity/go-cs-lib/pkg/ptr"
"github.com/crowdsecurity/go-cs-lib/pkg/trace"
"github.com/crowdsecurity/go-cs-lib/pkg/version"
"github.com/crowdsecurity/crowdsec/pkg/apiclient"
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
"github.com/crowdsecurity/crowdsec/pkg/cwversion"
"github.com/crowdsecurity/crowdsec/pkg/database"
"github.com/crowdsecurity/crowdsec/pkg/database/ent"
"github.com/crowdsecurity/crowdsec/pkg/database/ent/alert"
@ -81,7 +85,7 @@ func (a *apic) FetchScenariosListFromDB() ([]string, error) {
machineScenarios := strings.Split(v.Scenarios, ",")
log.Debugf("%d scenarios for machine %d", len(machineScenarios), v.ID)
for _, sv := range machineScenarios {
if !types.InSlice(sv, scenarios) && sv != "" {
if !slices.Contains(scenarios, sv) && sv != "" {
scenarios = append(scenarios, sv)
}
}
@ -94,15 +98,15 @@ func decisionsToApiDecisions(decisions []*models.Decision) models.AddSignalsRequ
apiDecisions := models.AddSignalsRequestItemDecisions{}
for _, decision := range decisions {
x := &models.AddSignalsRequestItemDecisionsItem{
Duration: types.StrPtr(*decision.Duration),
Duration: ptr.Of(*decision.Duration),
ID: new(int64),
Origin: types.StrPtr(*decision.Origin),
Scenario: types.StrPtr(*decision.Scenario),
Scope: types.StrPtr(*decision.Scope),
Origin: ptr.Of(*decision.Origin),
Scenario: ptr.Of(*decision.Scenario),
Scope: ptr.Of(*decision.Scope),
//Simulated: *decision.Simulated,
Type: types.StrPtr(*decision.Type),
Type: ptr.Of(*decision.Type),
Until: decision.Until,
Value: types.StrPtr(*decision.Value),
Value: ptr.Of(*decision.Value),
UUID: decision.UUID,
}
*x.ID = decision.ID
@ -193,7 +197,7 @@ func NewAPIC(config *csconfig.OnlineApiClientCfg, dbClient *database.Client, con
ret.apiClient, err = apiclient.NewClient(&apiclient.Config{
MachineID: config.Credentials.Login,
Password: password,
UserAgent: fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
UserAgent: fmt.Sprintf("crowdsec/%s", version.String()),
URL: apiURL,
PapiURL: papiURL,
VersionPrefix: "v3",
@ -231,7 +235,7 @@ func NewAPIC(config *csconfig.OnlineApiClientCfg, dbClient *database.Client, con
// keep track of all alerts in cache and push it to CAPI every PushInterval.
func (a *apic) Push() error {
defer types.CatchPanic("lapi/pushToAPIC")
defer trace.CatchPanic("lapi/pushToAPIC")
var cache models.AddSignalsRequest
ticker := time.NewTicker(a.pushIntervalFirst)
@ -427,7 +431,7 @@ func (a *apic) HandleDeletedDecisionsV3(deletedDecisions []*modelscapi.GetDecisi
if err != nil {
return 0, errors.Wrapf(err, "converting db ret %d", dbCliDel)
}
updateCounterForDecision(delete_counters, types.StrPtr(types.CAPIOrigin), nil, dbCliDel)
updateCounterForDecision(delete_counters, ptr.Of(types.CAPIOrigin), nil, dbCliDel)
nbDeleted += dbCliDel
}
}
@ -473,26 +477,26 @@ func createAlertsForDecisions(decisions []*models.Decision) []*models.Alert {
func createAlertForDecision(decision *models.Decision) *models.Alert {
newAlert := &models.Alert{}
newAlert.Source = &models.Source{}
newAlert.Source.Scope = types.StrPtr("")
newAlert.Source.Scope = ptr.Of("")
if *decision.Origin == types.CAPIOrigin { //to make things more user friendly, we replace CAPI with community-blocklist
newAlert.Scenario = types.StrPtr(types.CAPIOrigin)
newAlert.Source.Scope = types.StrPtr(types.CAPIOrigin)
newAlert.Scenario = ptr.Of(types.CAPIOrigin)
newAlert.Source.Scope = ptr.Of(types.CAPIOrigin)
} else if *decision.Origin == types.ListOrigin {
newAlert.Scenario = types.StrPtr(*decision.Scenario)
newAlert.Source.Scope = types.StrPtr(types.ListOrigin)
newAlert.Scenario = ptr.Of(*decision.Scenario)
newAlert.Source.Scope = ptr.Of(types.ListOrigin)
} else {
log.Warningf("unknown origin %s", *decision.Origin)
}
newAlert.Message = types.StrPtr("")
newAlert.Source.Value = types.StrPtr("")
newAlert.StartAt = types.StrPtr(time.Now().UTC().Format(time.RFC3339))
newAlert.StopAt = types.StrPtr(time.Now().UTC().Format(time.RFC3339))
newAlert.Capacity = types.Int32Ptr(0)
newAlert.Simulated = types.BoolPtr(false)
newAlert.EventsCount = types.Int32Ptr(0)
newAlert.Leakspeed = types.StrPtr("")
newAlert.ScenarioHash = types.StrPtr("")
newAlert.ScenarioVersion = types.StrPtr("")
newAlert.Message = ptr.Of("")
newAlert.Source.Value = ptr.Of("")
newAlert.StartAt = ptr.Of(time.Now().UTC().Format(time.RFC3339))
newAlert.StopAt = ptr.Of(time.Now().UTC().Format(time.RFC3339))
newAlert.Capacity = ptr.Of(int32(0))
newAlert.Simulated = ptr.Of(false)
newAlert.EventsCount = ptr.Of(int32(0))
newAlert.Leakspeed = ptr.Of("")
newAlert.ScenarioHash = ptr.Of("")
newAlert.ScenarioVersion = ptr.Of("")
newAlert.MachineID = database.CapiMachineID
return newAlert
}
@ -769,16 +773,16 @@ func (a *apic) UpdateBlocklists(links *modelscapi.GetDecisionsStreamResponseLink
func setAlertScenario(add_counters map[string]map[string]int, delete_counters map[string]map[string]int, alert *models.Alert) *models.Alert {
if *alert.Source.Scope == types.CAPIOrigin {
*alert.Source.Scope = SCOPE_CAPI_ALIAS_ALIAS
alert.Scenario = types.StrPtr(fmt.Sprintf("update : +%d/-%d IPs", add_counters[types.CAPIOrigin]["all"], delete_counters[types.CAPIOrigin]["all"]))
alert.Scenario = ptr.Of(fmt.Sprintf("update : +%d/-%d IPs", add_counters[types.CAPIOrigin]["all"], delete_counters[types.CAPIOrigin]["all"]))
} else if *alert.Source.Scope == types.ListOrigin {
*alert.Source.Scope = fmt.Sprintf("%s:%s", types.ListOrigin, *alert.Scenario)
alert.Scenario = types.StrPtr(fmt.Sprintf("update : +%d/-%d IPs", add_counters[types.ListOrigin][*alert.Scenario], delete_counters[types.ListOrigin][*alert.Scenario]))
alert.Scenario = ptr.Of(fmt.Sprintf("update : +%d/-%d IPs", add_counters[types.ListOrigin][*alert.Scenario], delete_counters[types.ListOrigin][*alert.Scenario]))
}
return alert
}
func (a *apic) Pull() error {
defer types.CatchPanic("lapi/pullFromAPIC")
defer trace.CatchPanic("lapi/pullFromAPIC")
toldOnce := false
for {
@ -820,7 +824,7 @@ func (a *apic) Pull() error {
func (a *apic) GetMetrics() (*models.Metrics, error) {
metric := &models.Metrics{
ApilVersion: types.StrPtr(cwversion.VersionStr()),
ApilVersion: ptr.Of(version.String()),
Machines: make([]*models.MetricsAgentInfo, 0),
Bouncers: make([]*models.MetricsBouncerInfo, 0),
}
@ -861,7 +865,7 @@ func (a *apic) GetMetrics() (*models.Metrics, error) {
}
func (a *apic) SendMetrics(stop chan (bool)) {
defer types.CatchPanic("lapi/metricsToAPIC")
defer trace.CatchPanic("lapi/metricsToAPIC")
ticker := time.NewTicker(a.metricsIntervalFirst)

View file

@ -20,10 +20,12 @@ import (
"github.com/stretchr/testify/require"
"gopkg.in/tomb.v2"
"github.com/crowdsecurity/go-cs-lib/pkg/cstest"
"github.com/crowdsecurity/go-cs-lib/pkg/ptr"
"github.com/crowdsecurity/go-cs-lib/pkg/version"
"github.com/crowdsecurity/crowdsec/pkg/apiclient"
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
"github.com/crowdsecurity/crowdsec/pkg/cstest"
"github.com/crowdsecurity/crowdsec/pkg/cwversion"
"github.com/crowdsecurity/crowdsec/pkg/database"
"github.com/crowdsecurity/crowdsec/pkg/database/ent/decision"
"github.com/crowdsecurity/crowdsec/pkg/database/ent/machine"
@ -59,10 +61,10 @@ func getAPIC(t *testing.T) *apic {
metricsTomb: tomb.Tomb{},
scenarioList: make([]string, 0),
consoleConfig: &csconfig.ConsoleConfig{
ShareManualDecisions: types.BoolPtr(false),
ShareTaintedScenarios: types.BoolPtr(false),
ShareCustomScenarios: types.BoolPtr(false),
ShareContext: types.BoolPtr(false),
ShareManualDecisions: ptr.Of(false),
ShareTaintedScenarios: ptr.Of(false),
ShareCustomScenarios: ptr.Of(false),
ShareContext: ptr.Of(false),
},
isPulling: make(chan bool, 1),
}
@ -205,7 +207,7 @@ func TestNewAPIC(t *testing.T) {
action: func() {},
args: args{
dbClient: getDBClient(t),
consoleConfig: LoadTestConfig().API.Server.ConsoleConfig,
consoleConfig: LoadTestConfig(t).API.Server.ConsoleConfig,
},
},
{
@ -213,7 +215,7 @@ func TestNewAPIC(t *testing.T) {
action: func() { testConfig.Credentials.URL = "foobar http://" },
args: args{
dbClient: getDBClient(t),
consoleConfig: LoadTestConfig().API.Server.ConsoleConfig,
consoleConfig: LoadTestConfig(t).API.Server.ConsoleConfig,
},
expectedErr: "first path segment in URL cannot contain colon",
},
@ -265,11 +267,11 @@ func TestAPICHandleDeletedDecisions(t *testing.T) {
assertTotalDecisionCount(t, api.dbClient, 2)
nbDeleted, err := api.HandleDeletedDecisions([]*models.Decision{{
Value: types.StrPtr("1.2.3.4"),
Origin: types.StrPtr(types.CAPIOrigin),
Value: ptr.Of("1.2.3.4"),
Origin: ptr.Of(types.CAPIOrigin),
Type: &decision1.Type,
Scenario: types.StrPtr("crowdsec/test"),
Scope: types.StrPtr("IP"),
Scenario: ptr.Of("crowdsec/test"),
Scope: ptr.Of("IP"),
}}, deleteCounters)
assert.NoError(t, err)
@ -293,7 +295,7 @@ func TestAPICGetMetrics(t *testing.T) {
machineIDs: []string{},
bouncers: []string{},
expectedMetric: &models.Metrics{
ApilVersion: types.StrPtr(cwversion.VersionStr()),
ApilVersion: ptr.Of(version.String()),
Bouncers: []*models.MetricsBouncerInfo{},
Machines: []*models.MetricsAgentInfo{},
},
@ -303,7 +305,7 @@ func TestAPICGetMetrics(t *testing.T) {
machineIDs: []string{"a", "b", "c"},
bouncers: []string{"1", "2", "3"},
expectedMetric: &models.Metrics{
ApilVersion: types.StrPtr(cwversion.VersionStr()),
ApilVersion: ptr.Of(version.String()),
Bouncers: []*models.MetricsBouncerInfo{
{
CustomName: "1",
@ -374,23 +376,23 @@ func TestAPICGetMetrics(t *testing.T) {
func TestCreateAlertsForDecision(t *testing.T) {
httpBfDecisionList := &models.Decision{
Origin: types.StrPtr(types.ListOrigin),
Scenario: types.StrPtr("crowdsecurity/http-bf"),
Origin: ptr.Of(types.ListOrigin),
Scenario: ptr.Of("crowdsecurity/http-bf"),
}
sshBfDecisionList := &models.Decision{
Origin: types.StrPtr(types.ListOrigin),
Scenario: types.StrPtr("crowdsecurity/ssh-bf"),
Origin: ptr.Of(types.ListOrigin),
Scenario: ptr.Of("crowdsecurity/ssh-bf"),
}
httpBfDecisionCommunity := &models.Decision{
Origin: types.StrPtr(types.CAPIOrigin),
Scenario: types.StrPtr("crowdsecurity/http-bf"),
Origin: ptr.Of(types.CAPIOrigin),
Scenario: ptr.Of("crowdsecurity/http-bf"),
}
sshBfDecisionCommunity := &models.Decision{
Origin: types.StrPtr(types.CAPIOrigin),
Scenario: types.StrPtr("crowdsecurity/ssh-bf"),
Origin: ptr.Of(types.CAPIOrigin),
Scenario: ptr.Of("crowdsecurity/ssh-bf"),
}
type args struct {
decisions []*models.Decision
@ -453,27 +455,27 @@ func TestCreateAlertsForDecision(t *testing.T) {
func TestFillAlertsWithDecisions(t *testing.T) {
httpBfDecisionCommunity := &models.Decision{
Origin: types.StrPtr(types.CAPIOrigin),
Scenario: types.StrPtr("crowdsecurity/http-bf"),
Scope: types.StrPtr("ip"),
Origin: ptr.Of(types.CAPIOrigin),
Scenario: ptr.Of("crowdsecurity/http-bf"),
Scope: ptr.Of("ip"),
}
sshBfDecisionCommunity := &models.Decision{
Origin: types.StrPtr(types.CAPIOrigin),
Scenario: types.StrPtr("crowdsecurity/ssh-bf"),
Scope: types.StrPtr("ip"),
Origin: ptr.Of(types.CAPIOrigin),
Scenario: ptr.Of("crowdsecurity/ssh-bf"),
Scope: ptr.Of("ip"),
}
httpBfDecisionList := &models.Decision{
Origin: types.StrPtr(types.ListOrigin),
Scenario: types.StrPtr("crowdsecurity/http-bf"),
Scope: types.StrPtr("ip"),
Origin: ptr.Of(types.ListOrigin),
Scenario: ptr.Of("crowdsecurity/http-bf"),
Scope: ptr.Of("ip"),
}
sshBfDecisionList := &models.Decision{
Origin: types.StrPtr(types.ListOrigin),
Scenario: types.StrPtr("crowdsecurity/ssh-bf"),
Scope: types.StrPtr("ip"),
Origin: ptr.Of(types.ListOrigin),
Scenario: ptr.Of("crowdsecurity/ssh-bf"),
Scope: ptr.Of("ip"),
}
type args struct {
alerts []*models.Alert
@ -572,58 +574,58 @@ func TestAPICWhitelists(t *testing.T) {
"9.9.9.9", // This is already present in DB
"9.1.9.9", // This not present in DB
},
Scope: types.StrPtr("Ip"),
Scope: ptr.Of("Ip"),
}, // This is already present in DB
},
New: modelscapi.GetDecisionsStreamResponseNew{
&modelscapi.GetDecisionsStreamResponseNewItem{
Scenario: types.StrPtr("crowdsecurity/test1"),
Scope: types.StrPtr("Ip"),
Scenario: ptr.Of("crowdsecurity/test1"),
Scope: ptr.Of("Ip"),
Decisions: []*modelscapi.GetDecisionsStreamResponseNewItemDecisionsItems0{
{
Value: types.StrPtr("13.2.3.4"), //wl by cidr
Duration: types.StrPtr("24h"),
Value: ptr.Of("13.2.3.4"), //wl by cidr
Duration: ptr.Of("24h"),
},
},
},
&modelscapi.GetDecisionsStreamResponseNewItem{
Scenario: types.StrPtr("crowdsecurity/test1"),
Scope: types.StrPtr("Ip"),
Scenario: ptr.Of("crowdsecurity/test1"),
Scope: ptr.Of("Ip"),
Decisions: []*modelscapi.GetDecisionsStreamResponseNewItemDecisionsItems0{
{
Value: types.StrPtr("2.2.3.4"),
Duration: types.StrPtr("24h"),
Value: ptr.Of("2.2.3.4"),
Duration: ptr.Of("24h"),
},
},
},
&modelscapi.GetDecisionsStreamResponseNewItem{
Scenario: types.StrPtr("crowdsecurity/test2"),
Scope: types.StrPtr("Ip"),
Scenario: ptr.Of("crowdsecurity/test2"),
Scope: ptr.Of("Ip"),
Decisions: []*modelscapi.GetDecisionsStreamResponseNewItemDecisionsItems0{
{
Value: types.StrPtr("13.2.3.5"), //wl by cidr
Duration: types.StrPtr("24h"),
Value: ptr.Of("13.2.3.5"), //wl by cidr
Duration: ptr.Of("24h"),
},
},
}, // These two are from community list.
&modelscapi.GetDecisionsStreamResponseNewItem{
Scenario: types.StrPtr("crowdsecurity/test1"),
Scope: types.StrPtr("Ip"),
Scenario: ptr.Of("crowdsecurity/test1"),
Scope: ptr.Of("Ip"),
Decisions: []*modelscapi.GetDecisionsStreamResponseNewItemDecisionsItems0{
{
Value: types.StrPtr("6.2.3.4"),
Duration: types.StrPtr("24h"),
Value: ptr.Of("6.2.3.4"),
Duration: ptr.Of("24h"),
},
},
},
&modelscapi.GetDecisionsStreamResponseNewItem{
Scenario: types.StrPtr("crowdsecurity/test1"),
Scope: types.StrPtr("Ip"),
Scenario: ptr.Of("crowdsecurity/test1"),
Scope: ptr.Of("Ip"),
Decisions: []*modelscapi.GetDecisionsStreamResponseNewItemDecisionsItems0{
{
Value: types.StrPtr("9.2.3.4"), //wl by ip
Duration: types.StrPtr("24h"),
Value: ptr.Of("9.2.3.4"), //wl by ip
Duration: ptr.Of("24h"),
},
},
},
@ -631,18 +633,18 @@ func TestAPICWhitelists(t *testing.T) {
Links: &modelscapi.GetDecisionsStreamResponseLinks{
Blocklists: []*modelscapi.BlocklistLink{
{
URL: types.StrPtr("http://api.crowdsec.net/blocklist1"),
Name: types.StrPtr("blocklist1"),
Scope: types.StrPtr("Ip"),
Remediation: types.StrPtr("ban"),
Duration: types.StrPtr("24h"),
URL: ptr.Of("http://api.crowdsec.net/blocklist1"),
Name: ptr.Of("blocklist1"),
Scope: ptr.Of("Ip"),
Remediation: ptr.Of("ban"),
Duration: ptr.Of("24h"),
},
{
URL: types.StrPtr("http://api.crowdsec.net/blocklist2"),
Name: types.StrPtr("blocklist2"),
Scope: types.StrPtr("Ip"),
Remediation: types.StrPtr("ban"),
Duration: types.StrPtr("24h"),
URL: ptr.Of("http://api.crowdsec.net/blocklist2"),
Name: ptr.Of("blocklist2"),
Scope: ptr.Of("Ip"),
Remediation: ptr.Of("ban"),
Duration: ptr.Of("24h"),
},
},
},
@ -661,7 +663,7 @@ func TestAPICWhitelists(t *testing.T) {
apic, err := apiclient.NewDefaultClient(
url,
"/api",
fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
fmt.Sprintf("crowdsec/%s", version.String()),
nil,
)
require.NoError(t, err)
@ -734,27 +736,27 @@ func TestAPICPullTop(t *testing.T) {
"9.9.9.9", // This is already present in DB
"9.1.9.9", // This not present in DB
},
Scope: types.StrPtr("Ip"),
Scope: ptr.Of("Ip"),
}, // This is already present in DB
},
New: modelscapi.GetDecisionsStreamResponseNew{
&modelscapi.GetDecisionsStreamResponseNewItem{
Scenario: types.StrPtr("crowdsecurity/test1"),
Scope: types.StrPtr("Ip"),
Scenario: ptr.Of("crowdsecurity/test1"),
Scope: ptr.Of("Ip"),
Decisions: []*modelscapi.GetDecisionsStreamResponseNewItemDecisionsItems0{
{
Value: types.StrPtr("1.2.3.4"),
Duration: types.StrPtr("24h"),
Value: ptr.Of("1.2.3.4"),
Duration: ptr.Of("24h"),
},
},
},
&modelscapi.GetDecisionsStreamResponseNewItem{
Scenario: types.StrPtr("crowdsecurity/test2"),
Scope: types.StrPtr("Ip"),
Scenario: ptr.Of("crowdsecurity/test2"),
Scope: ptr.Of("Ip"),
Decisions: []*modelscapi.GetDecisionsStreamResponseNewItemDecisionsItems0{
{
Value: types.StrPtr("1.2.3.5"),
Duration: types.StrPtr("24h"),
Value: ptr.Of("1.2.3.5"),
Duration: ptr.Of("24h"),
},
},
}, // These two are from community list.
@ -762,18 +764,18 @@ func TestAPICPullTop(t *testing.T) {
Links: &modelscapi.GetDecisionsStreamResponseLinks{
Blocklists: []*modelscapi.BlocklistLink{
{
URL: types.StrPtr("http://api.crowdsec.net/blocklist1"),
Name: types.StrPtr("blocklist1"),
Scope: types.StrPtr("Ip"),
Remediation: types.StrPtr("ban"),
Duration: types.StrPtr("24h"),
URL: ptr.Of("http://api.crowdsec.net/blocklist1"),
Name: ptr.Of("blocklist1"),
Scope: ptr.Of("Ip"),
Remediation: ptr.Of("ban"),
Duration: ptr.Of("24h"),
},
{
URL: types.StrPtr("http://api.crowdsec.net/blocklist2"),
Name: types.StrPtr("blocklist2"),
Scope: types.StrPtr("Ip"),
Remediation: types.StrPtr("ban"),
Duration: types.StrPtr("24h"),
URL: ptr.Of("http://api.crowdsec.net/blocklist2"),
Name: ptr.Of("blocklist2"),
Scope: ptr.Of("Ip"),
Remediation: ptr.Of("ban"),
Duration: ptr.Of("24h"),
},
},
},
@ -792,7 +794,7 @@ func TestAPICPullTop(t *testing.T) {
apic, err := apiclient.NewDefaultClient(
url,
"/api",
fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
fmt.Sprintf("crowdsec/%s", version.String()),
nil,
)
require.NoError(t, err)
@ -840,12 +842,12 @@ func TestAPICPullTopBLCacheFirstCall(t *testing.T) {
modelscapi.GetDecisionsStreamResponse{
New: modelscapi.GetDecisionsStreamResponseNew{
&modelscapi.GetDecisionsStreamResponseNewItem{
Scenario: types.StrPtr("crowdsecurity/test1"),
Scope: types.StrPtr("Ip"),
Scenario: ptr.Of("crowdsecurity/test1"),
Scope: ptr.Of("Ip"),
Decisions: []*modelscapi.GetDecisionsStreamResponseNewItemDecisionsItems0{
{
Value: types.StrPtr("1.2.3.4"),
Duration: types.StrPtr("24h"),
Value: ptr.Of("1.2.3.4"),
Duration: ptr.Of("24h"),
},
},
},
@ -853,11 +855,11 @@ func TestAPICPullTopBLCacheFirstCall(t *testing.T) {
Links: &modelscapi.GetDecisionsStreamResponseLinks{
Blocklists: []*modelscapi.BlocklistLink{
{
URL: types.StrPtr("http://api.crowdsec.net/blocklist1"),
Name: types.StrPtr("blocklist1"),
Scope: types.StrPtr("Ip"),
Remediation: types.StrPtr("ban"),
Duration: types.StrPtr("24h"),
URL: ptr.Of("http://api.crowdsec.net/blocklist1"),
Name: ptr.Of("blocklist1"),
Scope: ptr.Of("Ip"),
Remediation: ptr.Of("ban"),
Duration: ptr.Of("24h"),
},
},
},
@ -874,7 +876,7 @@ func TestAPICPullTopBLCacheFirstCall(t *testing.T) {
apic, err := apiclient.NewDefaultClient(
url,
"/api",
fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
fmt.Sprintf("crowdsec/%s", version.String()),
nil,
)
require.NoError(t, err)
@ -883,7 +885,7 @@ func TestAPICPullTopBLCacheFirstCall(t *testing.T) {
err = api.PullTop(false)
require.NoError(t, err)
blocklistConfigItemName := fmt.Sprintf("blocklist:%s:last_pull", *types.StrPtr("blocklist1"))
blocklistConfigItemName := "blocklist:blocklist1:last_pull"
lastPullTimestamp, err := api.dbClient.GetConfigItem(blocklistConfigItemName)
require.NoError(t, err)
assert.NotEqual(t, "", *lastPullTimestamp)
@ -927,12 +929,12 @@ func TestAPICPullTopBLCacheForceCall(t *testing.T) {
modelscapi.GetDecisionsStreamResponse{
New: modelscapi.GetDecisionsStreamResponseNew{
&modelscapi.GetDecisionsStreamResponseNewItem{
Scenario: types.StrPtr("crowdsecurity/test1"),
Scope: types.StrPtr("Ip"),
Scenario: ptr.Of("crowdsecurity/test1"),
Scope: ptr.Of("Ip"),
Decisions: []*modelscapi.GetDecisionsStreamResponseNewItemDecisionsItems0{
{
Value: types.StrPtr("1.2.3.4"),
Duration: types.StrPtr("24h"),
Value: ptr.Of("1.2.3.4"),
Duration: ptr.Of("24h"),
},
},
},
@ -940,11 +942,11 @@ func TestAPICPullTopBLCacheForceCall(t *testing.T) {
Links: &modelscapi.GetDecisionsStreamResponseLinks{
Blocklists: []*modelscapi.BlocklistLink{
{
URL: types.StrPtr("http://api.crowdsec.net/blocklist1"),
Name: types.StrPtr("blocklist1"),
Scope: types.StrPtr("Ip"),
Remediation: types.StrPtr("ban"),
Duration: types.StrPtr("24h"),
URL: ptr.Of("http://api.crowdsec.net/blocklist1"),
Name: ptr.Of("blocklist1"),
Scope: ptr.Of("Ip"),
Remediation: ptr.Of("ban"),
Duration: ptr.Of("24h"),
},
},
},
@ -961,7 +963,7 @@ func TestAPICPullTopBLCacheForceCall(t *testing.T) {
apic, err := apiclient.NewDefaultClient(
url,
"/api",
fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
fmt.Sprintf("crowdsec/%s", version.String()),
nil,
)
require.NoError(t, err)
@ -981,10 +983,10 @@ func TestAPICPush(t *testing.T) {
name: "simple single alert",
alerts: []*models.Alert{
{
Scenario: types.StrPtr("crowdsec/test"),
ScenarioHash: types.StrPtr("certified"),
ScenarioVersion: types.StrPtr("v1.0"),
Simulated: types.BoolPtr(false),
Scenario: ptr.Of("crowdsec/test"),
ScenarioHash: ptr.Of("certified"),
ScenarioVersion: ptr.Of("v1.0"),
Simulated: ptr.Of(false),
Source: &models.Source{},
},
},
@ -994,10 +996,10 @@ func TestAPICPush(t *testing.T) {
name: "simulated alert is not pushed",
alerts: []*models.Alert{
{
Scenario: types.StrPtr("crowdsec/test"),
ScenarioHash: types.StrPtr("certified"),
ScenarioVersion: types.StrPtr("v1.0"),
Simulated: types.BoolPtr(true),
Scenario: ptr.Of("crowdsec/test"),
ScenarioHash: ptr.Of("certified"),
ScenarioVersion: ptr.Of("v1.0"),
Simulated: ptr.Of(true),
Source: &models.Source{},
},
},
@ -1010,10 +1012,10 @@ func TestAPICPush(t *testing.T) {
alerts := make([]*models.Alert, 100)
for i := 0; i < 100; i++ {
alerts[i] = &models.Alert{
Scenario: types.StrPtr("crowdsec/test"),
ScenarioHash: types.StrPtr("certified"),
ScenarioVersion: types.StrPtr("v1.0"),
Simulated: types.BoolPtr(false),
Scenario: ptr.Of("crowdsec/test"),
ScenarioHash: ptr.Of("certified"),
ScenarioVersion: ptr.Of("v1.0"),
Simulated: ptr.Of(false),
Source: &models.Source{},
}
}
@ -1036,7 +1038,7 @@ func TestAPICPush(t *testing.T) {
apic, err := apiclient.NewDefaultClient(
url,
"/api",
fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
fmt.Sprintf("crowdsec/%s", version.String()),
nil,
)
require.NoError(t, err)
@ -1111,7 +1113,7 @@ func TestAPICSendMetrics(t *testing.T) {
apiClient, err := apiclient.NewDefaultClient(
url,
"/api",
fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
fmt.Sprintf("crowdsec/%s", version.String()),
nil,
)
require.NoError(t, err)
@ -1179,7 +1181,7 @@ func TestAPICPull(t *testing.T) {
apic, err := apiclient.NewDefaultClient(
url,
"/api",
fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
fmt.Sprintf("crowdsec/%s", version.String()),
nil,
)
require.NoError(t, err)
@ -1188,12 +1190,12 @@ func TestAPICPull(t *testing.T) {
modelscapi.GetDecisionsStreamResponse{
New: modelscapi.GetDecisionsStreamResponseNew{
&modelscapi.GetDecisionsStreamResponseNewItem{
Scenario: types.StrPtr("crowdsecurity/ssh-bf"),
Scope: types.StrPtr("Ip"),
Scenario: ptr.Of("crowdsecurity/ssh-bf"),
Scope: ptr.Of("Ip"),
Decisions: []*modelscapi.GetDecisionsStreamResponseNewItemDecisionsItems0{
{
Value: types.StrPtr("1.2.3.5"),
Duration: types.StrPtr("24h"),
Value: ptr.Of("1.2.3.5"),
Duration: ptr.Of("24h"),
},
},
},
@ -1228,29 +1230,29 @@ func TestShouldShareAlert(t *testing.T) {
{
name: "custom alert should be shared if config enables it",
consoleConfig: &csconfig.ConsoleConfig{
ShareCustomScenarios: types.BoolPtr(true),
ShareCustomScenarios: ptr.Of(true),
},
alert: &models.Alert{Simulated: types.BoolPtr(false)},
alert: &models.Alert{Simulated: ptr.Of(false)},
expectedRet: true,
expectedTrust: "custom",
},
{
name: "custom alert should not be shared if config disables it",
consoleConfig: &csconfig.ConsoleConfig{
ShareCustomScenarios: types.BoolPtr(false),
ShareCustomScenarios: ptr.Of(false),
},
alert: &models.Alert{Simulated: types.BoolPtr(false)},
alert: &models.Alert{Simulated: ptr.Of(false)},
expectedRet: false,
expectedTrust: "custom",
},
{
name: "manual alert should be shared if config enables it",
consoleConfig: &csconfig.ConsoleConfig{
ShareManualDecisions: types.BoolPtr(true),
ShareManualDecisions: ptr.Of(true),
},
alert: &models.Alert{
Simulated: types.BoolPtr(false),
Decisions: []*models.Decision{{Origin: types.StrPtr(types.CscliOrigin)}},
Simulated: ptr.Of(false),
Decisions: []*models.Decision{{Origin: ptr.Of(types.CscliOrigin)}},
},
expectedRet: true,
expectedTrust: "manual",
@ -1258,11 +1260,11 @@ func TestShouldShareAlert(t *testing.T) {
{
name: "manual alert should not be shared if config disables it",
consoleConfig: &csconfig.ConsoleConfig{
ShareManualDecisions: types.BoolPtr(false),
ShareManualDecisions: ptr.Of(false),
},
alert: &models.Alert{
Simulated: types.BoolPtr(false),
Decisions: []*models.Decision{{Origin: types.StrPtr(types.CscliOrigin)}},
Simulated: ptr.Of(false),
Decisions: []*models.Decision{{Origin: ptr.Of(types.CscliOrigin)}},
},
expectedRet: false,
expectedTrust: "manual",
@ -1270,11 +1272,11 @@ func TestShouldShareAlert(t *testing.T) {
{
name: "manual alert should be shared if config enables it",
consoleConfig: &csconfig.ConsoleConfig{
ShareTaintedScenarios: types.BoolPtr(true),
ShareTaintedScenarios: ptr.Of(true),
},
alert: &models.Alert{
Simulated: types.BoolPtr(false),
ScenarioHash: types.StrPtr("whateverHash"),
Simulated: ptr.Of(false),
ScenarioHash: ptr.Of("whateverHash"),
},
expectedRet: true,
expectedTrust: "tainted",
@ -1282,11 +1284,11 @@ func TestShouldShareAlert(t *testing.T) {
{
name: "manual alert should not be shared if config disables it",
consoleConfig: &csconfig.ConsoleConfig{
ShareTaintedScenarios: types.BoolPtr(false),
ShareTaintedScenarios: ptr.Of(false),
},
alert: &models.Alert{
Simulated: types.BoolPtr(false),
ScenarioHash: types.StrPtr("whateverHash"),
Simulated: ptr.Of(false),
ScenarioHash: ptr.Of("whateverHash"),
},
expectedRet: false,
expectedTrust: "tainted",

View file

@ -12,6 +12,8 @@ import (
"strings"
"time"
"github.com/crowdsecurity/go-cs-lib/pkg/trace"
"github.com/crowdsecurity/crowdsec/pkg/apiclient"
"github.com/crowdsecurity/crowdsec/pkg/apiserver/controllers"
v1 "github.com/crowdsecurity/crowdsec/pkg/apiserver/middlewares/v1"
@ -87,7 +89,7 @@ func CustomRecoveryWithWriter() gin.HandlerFunc {
log.Warningf("client %s disconnected : %s", c.ClientIP(), err)
c.Abort()
} else {
filename := types.WriteStackTrace(err)
filename := trace.WriteStackTrace(err)
log.Warningf("client %s error : %s", c.ClientIP(), err)
log.Warningf("stacktrace written to %s, please join to your issue", filename)
c.AbortWithStatus(http.StatusInternalServerError)
@ -311,7 +313,13 @@ func (s *APIServer) GetTLSConfig() (*tls.Config, error) {
if err != nil {
return nil, errors.Wrap(err, "Error opening cert file")
}
caCertPool = x509.NewCertPool()
caCertPool, err = x509.SystemCertPool()
if err != nil {
log.Warnf("Error loading system CA certificates: %s", err)
}
if caCertPool == nil {
caCertPool = x509.NewCertPool()
}
caCertPool.AppendCertsFromPEM(caCert)
}
}
@ -325,7 +333,7 @@ func (s *APIServer) GetTLSConfig() (*tls.Config, error) {
}
func (s *APIServer) Run(apiReady chan bool) error {
defer types.CatchPanic("lapi/runServer")
defer trace.CatchPanic("lapi/runServer")
tlsCfg, err := s.GetTLSConfig()
if err != nil {
return errors.Wrap(err, "while creating TLS config")

View file

@ -11,8 +11,9 @@ import (
"testing"
"time"
"github.com/crowdsecurity/go-cs-lib/pkg/version"
middlewares "github.com/crowdsecurity/crowdsec/pkg/apiserver/middlewares/v1"
"github.com/crowdsecurity/crowdsec/pkg/cwversion"
"github.com/crowdsecurity/crowdsec/pkg/models"
"github.com/crowdsecurity/crowdsec/pkg/types"
"github.com/go-openapi/strfmt"
@ -33,16 +34,19 @@ var MachineTest = models.WatcherAuthRequest{
Password: &testPassword,
}
var UserAgent = fmt.Sprintf("crowdsec-test/%s", cwversion.Version)
var UserAgent = fmt.Sprintf("crowdsec-test/%s", version.Version)
var emptyBody = strings.NewReader("")
func LoadTestConfig() csconfig.Config {
func LoadTestConfig(t *testing.T) csconfig.Config {
config := csconfig.Config{}
maxAge := "1h"
flushConfig := csconfig.FlushDBCfg{
MaxAge: &maxAge,
}
tempDir, _ := os.MkdirTemp("", "crowdsec_tests")
t.Cleanup(func() { os.RemoveAll(tempDir) })
dbconfig := csconfig.DatabaseCfg{
Type: "sqlite",
DbPath: filepath.Join(tempDir, "ent"),
@ -68,13 +72,16 @@ func LoadTestConfig() csconfig.Config {
return config
}
func LoadTestConfigForwardedFor() csconfig.Config {
func LoadTestConfigForwardedFor(t *testing.T) csconfig.Config {
config := csconfig.Config{}
maxAge := "1h"
flushConfig := csconfig.FlushDBCfg{
MaxAge: &maxAge,
}
tempDir, _ := os.MkdirTemp("", "crowdsec_tests")
t.Cleanup(func() { os.RemoveAll(tempDir) })
dbconfig := csconfig.DatabaseCfg{
Type: "sqlite",
DbPath: filepath.Join(tempDir, "ent"),
@ -102,8 +109,8 @@ func LoadTestConfigForwardedFor() csconfig.Config {
return config
}
func NewAPIServer() (*APIServer, csconfig.Config, error) {
config := LoadTestConfig()
func NewAPIServer(t *testing.T) (*APIServer, csconfig.Config, error) {
config := LoadTestConfig(t)
os.Remove("./ent")
apiServer, err := NewServer(config.API.Server)
if err != nil {
@ -114,8 +121,8 @@ func NewAPIServer() (*APIServer, csconfig.Config, error) {
return apiServer, config, nil
}
func NewAPITest() (*gin.Engine, csconfig.Config, error) {
apiServer, config, err := NewAPIServer()
func NewAPITest(t *testing.T) (*gin.Engine, csconfig.Config, error) {
apiServer, config, err := NewAPIServer(t)
if err != nil {
return nil, config, fmt.Errorf("unable to run local API: %s", err)
}
@ -130,8 +137,8 @@ func NewAPITest() (*gin.Engine, csconfig.Config, error) {
return router, config, nil
}
func NewAPITestForwardedFor() (*gin.Engine, csconfig.Config, error) {
config := LoadTestConfigForwardedFor()
func NewAPITestForwardedFor(t *testing.T) (*gin.Engine, csconfig.Config, error) {
config := LoadTestConfigForwardedFor(t)
os.Remove("./ent")
apiServer, err := NewServer(config.API.Server)
@ -284,7 +291,7 @@ func CreateTestBouncer(config *csconfig.DatabaseCfg) (string, error) {
}
func TestWithWrongDBConfig(t *testing.T) {
config := LoadTestConfig()
config := LoadTestConfig(t)
config.API.Server.DbConfig.Type = "test"
apiServer, err := NewServer(config.API.Server)
@ -293,7 +300,7 @@ func TestWithWrongDBConfig(t *testing.T) {
}
func TestWithWrongFlushConfig(t *testing.T) {
config := LoadTestConfig()
config := LoadTestConfig(t)
maxItems := -1
config.API.Server.DbConfig.Flush.MaxItems = &maxItems
apiServer, err := NewServer(config.API.Server)
@ -303,7 +310,7 @@ func TestWithWrongFlushConfig(t *testing.T) {
}
func TestUnknownPath(t *testing.T) {
router, _, err := NewAPITest()
router, _, err := NewAPITest(t)
if err != nil {
log.Fatalf("unable to run local API: %s", err)
}
@ -333,13 +340,15 @@ ListenURI string `yaml:"listen_uri,omitempty"` //127.0
*/
func TestLoggingDebugToFileConfig(t *testing.T) {
/*declare settings*/
maxAge := "1h"
flushConfig := csconfig.FlushDBCfg{
MaxAge: &maxAge,
}
tempDir, _ := os.MkdirTemp("", "crowdsec_tests")
t.Cleanup(func() { os.RemoveAll(tempDir) })
dbconfig := csconfig.DatabaseCfg{
Type: "sqlite",
DbPath: filepath.Join(tempDir, "ent"),
@ -397,7 +406,10 @@ func TestLoggingErrorToFileConfig(t *testing.T) {
flushConfig := csconfig.FlushDBCfg{
MaxAge: &maxAge,
}
tempDir, _ := os.MkdirTemp("", "crowdsec_tests")
t.Cleanup(func() { os.RemoveAll(tempDir) })
dbconfig := csconfig.DatabaseCfg{
Type: "sqlite",
DbPath: filepath.Join(tempDir, "ent"),

View file

@ -11,7 +11,7 @@ import (
)
func TestLogin(t *testing.T) {
router, config, err := NewAPITest()
router, config, err := NewAPITest(t)
if err != nil {
log.Fatalf("unable to run local API: %s", err)
}

View file

@ -12,7 +12,7 @@ import (
)
func TestCreateMachine(t *testing.T) {
router, _, err := NewAPITest()
router, _, err := NewAPITest(t)
if err != nil {
log.Fatalf("unable to run local API: %s", err)
}
@ -53,7 +53,7 @@ func TestCreateMachine(t *testing.T) {
}
func TestCreateMachineWithForwardedFor(t *testing.T) {
router, config, err := NewAPITestForwardedFor()
router, config, err := NewAPITestForwardedFor(t)
if err != nil {
log.Fatalf("unable to run local API: %s", err)
}
@ -82,7 +82,7 @@ func TestCreateMachineWithForwardedFor(t *testing.T) {
}
func TestCreateMachineWithForwardedForNoConfig(t *testing.T) {
router, config, err := NewAPITest()
router, config, err := NewAPITest(t)
if err != nil {
log.Fatalf("unable to run local API: %s", err)
}
@ -113,7 +113,7 @@ func TestCreateMachineWithForwardedForNoConfig(t *testing.T) {
}
func TestCreateMachineWithoutForwardedFor(t *testing.T) {
router, config, err := NewAPITestForwardedFor()
router, config, err := NewAPITestForwardedFor(t)
if err != nil {
log.Fatalf("unable to run local API: %s", err)
}
@ -143,7 +143,7 @@ func TestCreateMachineWithoutForwardedFor(t *testing.T) {
}
func TestCreateMachineAlreadyExist(t *testing.T) {
router, _, err := NewAPITest()
router, _, err := NewAPITest(t)
if err != nil {
log.Fatalf("unable to run local API: %s", err)
}

View file

@ -8,6 +8,8 @@ import (
"sync"
"time"
"github.com/crowdsecurity/go-cs-lib/pkg/trace"
"github.com/crowdsecurity/crowdsec/pkg/apiclient"
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
"github.com/crowdsecurity/crowdsec/pkg/database"
@ -217,8 +219,7 @@ func (p *Papi) PullOnce(since time.Time, sync bool) error {
// PullPAPI is the long polling client for real-time decisions from PAPI
func (p *Papi) Pull() error {
defer types.CatchPanic("lapi/PullPAPI")
defer trace.CatchPanic("lapi/PullPAPI")
p.Logger.Infof("Starting Polling API Pull")
lastTimestamp := time.Time{}
@ -270,7 +271,7 @@ func (p *Papi) Pull() error {
}
func (p *Papi) SyncDecisions() error {
defer types.CatchPanic("lapi/syncDecisionsToCAPI")
defer trace.CatchPanic("lapi/syncDecisionsToCAPI")
var cache models.DecisionsDeleteRequest
ticker := time.NewTicker(p.SyncInterval)

View file

@ -5,11 +5,13 @@ import (
"fmt"
"time"
log "github.com/sirupsen/logrus"
"github.com/crowdsecurity/go-cs-lib/pkg/ptr"
"github.com/crowdsecurity/crowdsec/pkg/apiclient"
"github.com/crowdsecurity/crowdsec/pkg/models"
"github.com/crowdsecurity/crowdsec/pkg/types"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
)
type deleteDecisions struct {
@ -75,7 +77,7 @@ func AlertCmd(message *Message, p *Papi, sync bool) error {
alert := &models.Alert{}
if err := json.Unmarshal(data, alert); err != nil {
return errors.Wrapf(err, "message for '%s' contains bad alert format", message.Header.OperationType)
return fmt.Errorf("message for '%s' contains bad alert format: %w", message.Header.OperationType, err)
}
log.Infof("Received order %s from PAPI (%d decisions)", alert.UUID, len(alert.Decisions))
@ -83,20 +85,20 @@ func AlertCmd(message *Message, p *Papi, sync bool) error {
/*Fix the alert with missing mandatory items*/
if alert.StartAt == nil || *alert.StartAt == "" {
log.Warnf("Alert %d has no StartAt, setting it to now", alert.ID)
alert.StartAt = types.StrPtr(time.Now().UTC().Format(time.RFC3339))
alert.StartAt = ptr.Of(time.Now().UTC().Format(time.RFC3339))
}
if alert.StopAt == nil || *alert.StopAt == "" {
log.Warnf("Alert %d has no StopAt, setting it to now", alert.ID)
alert.StopAt = types.StrPtr(time.Now().UTC().Format(time.RFC3339))
alert.StopAt = ptr.Of(time.Now().UTC().Format(time.RFC3339))
}
alert.EventsCount = types.Int32Ptr(0)
alert.Capacity = types.Int32Ptr(0)
alert.Leakspeed = types.StrPtr("")
alert.Simulated = types.BoolPtr(false)
alert.ScenarioHash = types.StrPtr("")
alert.ScenarioVersion = types.StrPtr("")
alert.Message = types.StrPtr("")
alert.Scenario = types.StrPtr("")
alert.EventsCount = ptr.Of(int32(0))
alert.Capacity = ptr.Of(int32(0))
alert.Leakspeed = ptr.Of("")
alert.Simulated = ptr.Of(false)
alert.ScenarioHash = ptr.Of("")
alert.ScenarioVersion = ptr.Of("")
alert.Message = ptr.Of("")
alert.Scenario = ptr.Of("")
alert.Source = &models.Source{}
//if we're setting Source.Scope to types.ConsoleOrigin, it messes up the alert's value
@ -105,7 +107,7 @@ func AlertCmd(message *Message, p *Papi, sync bool) error {
alert.Source.Value = alert.Decisions[0].Value
} else {
log.Warningf("No decision found in alert for Polling API (%s : %s)", message.Header.Source.User, message.Header.Message)
alert.Source.Scope = types.StrPtr(types.ConsoleOrigin)
alert.Source.Scope = ptr.Of(types.ConsoleOrigin)
alert.Source.Value = &message.Header.Source.User
}
alert.Scenario = &message.Header.Message

View file

@ -9,13 +9,13 @@ import (
"strings"
"time"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
"gopkg.in/yaml.v2"
"github.com/crowdsecurity/go-cs-lib/pkg/ptr"
"github.com/crowdsecurity/go-cs-lib/pkg/yamlpatch"
"github.com/crowdsecurity/crowdsec/pkg/apiclient"
"github.com/crowdsecurity/crowdsec/pkg/types"
"github.com/crowdsecurity/crowdsec/pkg/yamlpatch"
)
type APICfg struct {
@ -82,11 +82,11 @@ func (o *OnlineApiClientCfg) Load() error {
o.Credentials = new(ApiCredentialsCfg)
fcontent, err := os.ReadFile(o.CredentialsFilePath)
if err != nil {
return errors.Wrapf(err, "failed to read api server credentials configuration file '%s'", o.CredentialsFilePath)
return fmt.Errorf("failed to read api server credentials configuration file '%s': %w", o.CredentialsFilePath, err)
}
err = yaml.UnmarshalStrict(fcontent, o.Credentials)
if err != nil {
return errors.Wrapf(err, "failed unmarshaling api server credentials configuration file '%s'", o.CredentialsFilePath)
return fmt.Errorf("failed unmarshaling api server credentials configuration file '%s': %w", o.CredentialsFilePath, err)
}
if o.Credentials.Login == "" || o.Credentials.Password == "" || o.Credentials.URL == "" {
log.Warningf("can't load CAPI credentials from '%s' (missing field)", o.CredentialsFilePath)
@ -104,7 +104,7 @@ func (l *LocalApiClientCfg) Load() error {
}
err = yaml.UnmarshalStrict(fcontent, &l.Credentials)
if err != nil {
return errors.Wrapf(err, "failed unmarshaling api client credential configuration file '%s'", l.CredentialsFilePath)
return fmt.Errorf("failed unmarshaling api client credential configuration file '%s': %w", l.CredentialsFilePath, err)
}
if l.Credentials == nil || l.Credentials.URL == "" {
return fmt.Errorf("no credentials or URL found in api client configuration '%s'", l.CredentialsFilePath)
@ -129,10 +129,16 @@ func (l *LocalApiClientCfg) Load() error {
if l.Credentials.CACertPath != "" {
caCert, err := os.ReadFile(l.Credentials.CACertPath)
if err != nil {
return errors.Wrapf(err, "failed to load cacert")
return fmt.Errorf("failed to load cacert: %w", err)
}
caCertPool := x509.NewCertPool()
caCertPool, err := x509.SystemCertPool()
if err != nil {
log.Warningf("Error loading system CA certificates: %s", err)
}
if caCertPool == nil {
caCertPool = x509.NewCertPool()
}
caCertPool.AppendCertsFromPEM(caCert)
apiclient.CaCertPool = caCertPool
}
@ -140,7 +146,7 @@ func (l *LocalApiClientCfg) Load() error {
if l.Credentials.CertPath != "" && l.Credentials.KeyPath != "" {
cert, err := tls.LoadX509KeyPair(l.Credentials.CertPath, l.Credentials.KeyPath)
if err != nil {
return errors.Wrapf(err, "failed to load api client certificate")
return fmt.Errorf("failed to load api client certificate: %w", err)
}
apiclient.Cert = &cert
@ -222,47 +228,49 @@ func (c *Config) LoadAPIServer() error {
log.Warning("crowdsec local API is disabled from flag")
}
if c.API.Server != nil {
//inherit log level from common, then api->server
var logLevel log.Level
if c.API.Server.LogLevel != nil {
logLevel = *c.API.Server.LogLevel
} else if c.Common.LogLevel != nil {
logLevel = *c.Common.LogLevel
} else {
logLevel = log.InfoLevel
}
if c.API.Server.PapiLogLevel == nil {
c.API.Server.PapiLogLevel = &logLevel
}
if c.API.Server.OnlineClient != nil && c.API.Server.OnlineClient.CredentialsFilePath != "" {
if err := c.API.Server.OnlineClient.Load(); err != nil {
return errors.Wrap(err, "loading online client credentials")
}
}
if c.API.Server.OnlineClient == nil || c.API.Server.OnlineClient.Credentials == nil {
log.Printf("push and pull to Central API disabled")
}
if err := c.LoadDBConfig(); err != nil {
return err
}
if err := c.API.Server.LoadCapiWhitelists(); err != nil {
return err
}
} else {
if c.API.Server == nil {
log.Warning("crowdsec local API is disabled")
c.DisableAPI = true
return nil
}
//inherit log level from common, then api->server
var logLevel log.Level
if c.API.Server.LogLevel != nil {
logLevel = *c.API.Server.LogLevel
} else if c.Common.LogLevel != nil {
logLevel = *c.Common.LogLevel
} else {
logLevel = log.InfoLevel
}
if c.API.Server.PapiLogLevel == nil {
c.API.Server.PapiLogLevel = &logLevel
}
if c.API.Server.OnlineClient != nil && c.API.Server.OnlineClient.CredentialsFilePath != "" {
if err := c.API.Server.OnlineClient.Load(); err != nil {
return fmt.Errorf("loading online client credentials: %w", err)
}
}
if c.API.Server.OnlineClient == nil || c.API.Server.OnlineClient.Credentials == nil {
log.Printf("push and pull to Central API disabled")
}
if err := c.LoadDBConfig(); err != nil {
return err
}
if err := c.API.Server.LoadCapiWhitelists(); err != nil {
return err
}
if c.API.Server.CapiWhitelistsPath != "" {
log.Infof("loaded capi whitelist from %s: %d IPs, %d CIDRs", c.API.Server.CapiWhitelistsPath, len(c.API.Server.CapiWhitelists.Ips), len(c.API.Server.CapiWhitelists.Cidrs))
}
if c.API.Server.Enable == nil {
// if the option is not present, it is enabled by default
c.API.Server.Enable = types.BoolPtr(true)
c.API.Server.Enable = ptr.Of(true)
}
if !*c.API.Server.Enable {
@ -291,18 +299,18 @@ func (c *Config) LoadAPIServer() error {
c.API.Server.UseForwardedForHeaders = true
}
if err := c.API.Server.LoadProfiles(); err != nil {
return errors.Wrap(err, "while loading profiles for LAPI")
return fmt.Errorf("while loading profiles for LAPI: %w", err)
}
if c.API.Server.ConsoleConfigPath == "" {
c.API.Server.ConsoleConfigPath = DefaultConsoleConfigFilePath
}
if err := c.API.Server.LoadConsoleConfig(); err != nil {
return errors.Wrap(err, "while loading console options")
return fmt.Errorf("while loading console options: %w", err)
}
if c.API.Server.OnlineClient != nil && c.API.Server.OnlineClient.CredentialsFilePath != "" {
if err := c.API.Server.OnlineClient.Load(); err != nil {
return errors.Wrap(err, "loading online client credentials")
return fmt.Errorf("loading online client credentials: %w", err)
}
}
if c.API.Server.OnlineClient == nil || c.API.Server.OnlineClient.Credentials == nil {
@ -311,7 +319,7 @@ func (c *Config) LoadAPIServer() error {
if c.API.CTI != nil {
if err := c.API.CTI.Load(); err != nil {
return errors.Wrap(err, "loading CTI configuration")
return fmt.Errorf("loading CTI configuration: %w", err)
}
}
@ -354,7 +362,7 @@ func (s *LocalApiServerCfg) LoadCapiWhitelists() error {
for _, v := range fromCfg.Cidrs {
_, tnet, err := net.ParseCIDR(v)
if err != nil {
return fmt.Errorf("unable to parse cidr whitelist '%s' : %v.", v, err)
return fmt.Errorf("unable to parse cidr whitelist '%s' : %v", v, err)
}
s.CapiWhitelists.Cidrs = append(s.CapiWhitelists.Cidrs, tnet)
}

View file

@ -7,12 +7,12 @@ import (
"strings"
"testing"
"github.com/crowdsecurity/crowdsec/pkg/types"
log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v2"
"github.com/crowdsecurity/crowdsec/pkg/cstest"
"github.com/crowdsecurity/go-cs-lib/pkg/cstest"
"github.com/crowdsecurity/go-cs-lib/pkg/ptr"
)
func TestLoadLocalApiClientCfg(t *testing.T) {
@ -53,7 +53,7 @@ func TestLoadLocalApiClientCfg(t *testing.T) {
name: "valid configuration with insecure skip verify",
input: &LocalApiClientCfg{
CredentialsFilePath: "./tests/lapi-secrets.yaml",
InsecureSkipVerify: types.BoolPtr(false),
InsecureSkipVerify: ptr.Of(false),
},
expected: &ApiCredentialsCfg{
URL: "http://localhost:8080/",
@ -188,21 +188,21 @@ func TestLoadAPIServer(t *testing.T) {
DisableAPI: false,
},
expected: &LocalApiServerCfg{
Enable: types.BoolPtr(true),
Enable: ptr.Of(true),
ListenURI: "http://crowdsec.api",
TLS: nil,
DbConfig: &DatabaseCfg{
DbPath: "./tests/test.db",
Type: "sqlite",
MaxOpenConns: types.IntPtr(DEFAULT_MAX_OPEN_CONNS),
MaxOpenConns: ptr.Of(DEFAULT_MAX_OPEN_CONNS),
},
ConsoleConfigPath: DefaultConfigPath("console.yaml"),
ConsoleConfig: &ConsoleConfig{
ShareManualDecisions: types.BoolPtr(false),
ShareTaintedScenarios: types.BoolPtr(true),
ShareCustomScenarios: types.BoolPtr(true),
ShareContext: types.BoolPtr(false),
ConsoleManagement: types.BoolPtr(false),
ShareManualDecisions: ptr.Of(false),
ShareTaintedScenarios: ptr.Of(true),
ShareCustomScenarios: ptr.Of(true),
ShareContext: ptr.Of(false),
ConsoleManagement: ptr.Of(false),
},
LogDir: LogDirFullPath,
LogMedia: "stdout",

View file

@ -5,13 +5,12 @@ import (
"os"
"path/filepath"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
"gopkg.in/yaml.v2"
"github.com/crowdsecurity/crowdsec/pkg/csstring"
"github.com/crowdsecurity/crowdsec/pkg/types"
"github.com/crowdsecurity/crowdsec/pkg/yamlpatch"
"github.com/crowdsecurity/go-cs-lib/pkg/csstring"
"github.com/crowdsecurity/go-cs-lib/pkg/ptr"
"github.com/crowdsecurity/go-cs-lib/pkg/yamlpatch"
)
// defaultConfigDir is the base path to all configuration files, to be overridden in the Makefile */
@ -41,18 +40,18 @@ type Config struct {
func (c *Config) Dump() error {
out, err := yaml.Marshal(c)
if err != nil {
return errors.Wrap(err, "failed marshaling config")
return fmt.Errorf("failed marshaling config: %w", err)
}
fmt.Printf("%s", string(out))
return nil
}
func NewConfig(configFile string, disableAgent bool, disableAPI bool, quiet bool) (*Config, error) {
func NewConfig(configFile string, disableAgent bool, disableAPI bool, quiet bool) (*Config, string, error) {
patcher := yamlpatch.NewPatcher(configFile, ".local")
patcher.SetQuiet(quiet)
fcontent, err := patcher.MergedPatchContent()
if err != nil {
return nil, err
return nil, "", err
}
configData := csstring.StrictExpand(string(fcontent), os.LookupEnv)
cfg := Config{
@ -64,9 +63,9 @@ func NewConfig(configFile string, disableAgent bool, disableAPI bool, quiet bool
err = yaml.UnmarshalStrict([]byte(configData), &cfg)
if err != nil {
// this is actually the "merged" yaml
return nil, errors.Wrap(err, configFile)
return nil, "", fmt.Errorf("%s: %w", configFile, err)
}
return &cfg, nil
return &cfg, configData, nil
}
func NewDefaultConfig() *Config {
@ -112,14 +111,14 @@ func NewDefaultConfig() *Config {
},
},
CTI: &CTICfg{
Enabled: types.BoolPtr(false),
Enabled: ptr.Of(false),
},
}
dbConfig := DatabaseCfg{
Type: "sqlite",
DbPath: DefaultDataPath("crowdsec.db"),
MaxOpenConns: types.IntPtr(DEFAULT_MAX_OPEN_CONNS),
MaxOpenConns: ptr.Of(DEFAULT_MAX_OPEN_CONNS),
}
globalCfg := Config{

View file

@ -6,17 +6,17 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/crowdsecurity/crowdsec/pkg/cstest"
"github.com/crowdsecurity/go-cs-lib/pkg/cstest"
)
func TestNormalLoad(t *testing.T) {
_, err := NewConfig("./tests/config.yaml", false, false, false)
_, _, err := NewConfig("./tests/config.yaml", false, false, false)
require.NoError(t, err)
_, err = NewConfig("./tests/xxx.yaml", false, false, false)
_, _, err = NewConfig("./tests/xxx.yaml", false, false, false)
assert.EqualError(t, err, "while reading yaml file: open ./tests/xxx.yaml: "+cstest.FileNotFoundMessage)
_, err = NewConfig("./tests/simulation.yaml", false, false, false)
_, _, err = NewConfig("./tests/simulation.yaml", false, false, false)
assert.EqualError(t, err, "./tests/simulation.yaml: yaml: unmarshal errors:\n line 1: field simulation not found in type csconfig.Config")
}

Some files were not shown because too many files have changed in this diff Show more