2020-11-30 09:37:17 +00:00
|
|
|
package csconfig
|
|
|
|
|
2021-03-24 17:16:17 +00:00
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
|
|
|
|
log "github.com/sirupsen/logrus"
|
2023-01-04 15:50:02 +00:00
|
|
|
"gopkg.in/yaml.v2"
|
2022-10-17 15:32:08 +00:00
|
|
|
|
2023-06-01 14:31:56 +00:00
|
|
|
"github.com/crowdsecurity/go-cs-lib/pkg/ptr"
|
2021-03-24 17:16:17 +00:00
|
|
|
)
|
|
|
|
|
2022-10-17 15:32:08 +00:00
|
|
|
// CrowdsecServiceCfg contains the location of parsers/scenarios/... and acquisition files
|
2020-11-30 09:37:17 +00:00
|
|
|
type CrowdsecServiceCfg struct {
|
2023-01-04 15:50:02 +00:00
|
|
|
Enable *bool `yaml:"enable"`
|
|
|
|
AcquisitionFilePath string `yaml:"acquisition_path,omitempty"`
|
|
|
|
AcquisitionDirPath string `yaml:"acquisition_dir,omitempty"`
|
|
|
|
ConsoleContextPath string `yaml:"console_context_path"`
|
|
|
|
ConsoleContextValueLength int `yaml:"console_context_value_length"`
|
|
|
|
AcquisitionFiles []string `yaml:"-"`
|
|
|
|
ParserRoutinesCount int `yaml:"parser_routines"`
|
|
|
|
BucketsRoutinesCount int `yaml:"buckets_routines"`
|
|
|
|
OutputRoutinesCount int `yaml:"output_routines"`
|
|
|
|
SimulationConfig *SimulationConfig `yaml:"-"`
|
|
|
|
LintOnly bool `yaml:"-"` // if set to true, exit after loading configs
|
|
|
|
BucketStateFile string `yaml:"state_input_file,omitempty"` // if we need to unserialize buckets at start
|
|
|
|
BucketStateDumpDir string `yaml:"state_output_dir,omitempty"` // if we need to unserialize buckets on shutdown
|
|
|
|
BucketsGCEnabled bool `yaml:"-"` // we need to garbage collect buckets when in forensic mode
|
|
|
|
|
|
|
|
HubDir string `yaml:"-"`
|
|
|
|
DataDir string `yaml:"-"`
|
|
|
|
ConfigDir string `yaml:"-"`
|
|
|
|
HubIndexFile string `yaml:"-"`
|
|
|
|
SimulationFilePath string `yaml:"-"`
|
|
|
|
ContextToSend map[string][]string `yaml:"-"`
|
2020-11-30 09:37:17 +00:00
|
|
|
}
|
2021-03-24 17:16:17 +00:00
|
|
|
|
|
|
|
func (c *Config) LoadCrowdsec() error {
|
|
|
|
var err error
|
2022-10-17 15:32:08 +00:00
|
|
|
|
2021-03-24 17:16:17 +00:00
|
|
|
if c.Crowdsec == nil {
|
2022-06-22 07:38:23 +00:00
|
|
|
log.Warning("crowdsec agent is disabled")
|
2021-03-24 17:16:17 +00:00
|
|
|
c.DisableAgent = true
|
|
|
|
return nil
|
|
|
|
}
|
2022-09-12 12:38:29 +00:00
|
|
|
|
|
|
|
if c.Crowdsec.Enable == nil {
|
|
|
|
// if the option is not present, it is enabled by default
|
2023-06-01 14:31:56 +00:00
|
|
|
c.Crowdsec.Enable = ptr.Of(true)
|
2022-09-12 12:38:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if !*c.Crowdsec.Enable {
|
|
|
|
log.Warning("crowdsec agent is disabled")
|
|
|
|
c.DisableAgent = true
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-10-17 15:32:08 +00:00
|
|
|
if c.Crowdsec.AcquisitionFiles == nil {
|
|
|
|
c.Crowdsec.AcquisitionFiles = []string{}
|
|
|
|
}
|
|
|
|
|
2021-03-24 17:16:17 +00:00
|
|
|
if c.Crowdsec.AcquisitionFilePath != "" {
|
2022-10-17 15:32:08 +00:00
|
|
|
log.Debugf("non-empty acquisition_path %s", c.Crowdsec.AcquisitionFilePath)
|
|
|
|
if _, err = os.Stat(c.Crowdsec.AcquisitionFilePath); err != nil {
|
|
|
|
return fmt.Errorf("while checking acquisition_path: %w", err)
|
2021-03-24 17:16:17 +00:00
|
|
|
}
|
|
|
|
c.Crowdsec.AcquisitionFiles = append(c.Crowdsec.AcquisitionFiles, c.Crowdsec.AcquisitionFilePath)
|
|
|
|
}
|
2022-10-17 15:32:08 +00:00
|
|
|
|
2021-03-24 17:16:17 +00:00
|
|
|
if c.Crowdsec.AcquisitionDirPath != "" {
|
|
|
|
c.Crowdsec.AcquisitionDirPath, err = filepath.Abs(c.Crowdsec.AcquisitionDirPath)
|
|
|
|
if err != nil {
|
2023-06-01 14:31:56 +00:00
|
|
|
return fmt.Errorf("can't get absolute path of '%s': %w", c.Crowdsec.AcquisitionDirPath, err)
|
2021-03-24 17:16:17 +00:00
|
|
|
}
|
2022-10-17 15:32:08 +00:00
|
|
|
|
|
|
|
var files []string
|
|
|
|
|
|
|
|
files, err = filepath.Glob(c.Crowdsec.AcquisitionDirPath + "/*.yaml")
|
2021-03-24 17:16:17 +00:00
|
|
|
if err != nil {
|
2023-06-01 14:31:56 +00:00
|
|
|
return fmt.Errorf("while globbing acquis_dir: %w", err)
|
2021-03-24 17:16:17 +00:00
|
|
|
}
|
|
|
|
c.Crowdsec.AcquisitionFiles = append(c.Crowdsec.AcquisitionFiles, files...)
|
2021-12-02 14:55:50 +00:00
|
|
|
|
|
|
|
files, err = filepath.Glob(c.Crowdsec.AcquisitionDirPath + "/*.yml")
|
|
|
|
if err != nil {
|
2023-06-01 14:31:56 +00:00
|
|
|
return fmt.Errorf("while globbing acquis_dir: %w", err)
|
2021-12-02 14:55:50 +00:00
|
|
|
}
|
|
|
|
c.Crowdsec.AcquisitionFiles = append(c.Crowdsec.AcquisitionFiles, files...)
|
2021-03-24 17:16:17 +00:00
|
|
|
}
|
2022-10-17 15:32:08 +00:00
|
|
|
|
2021-03-24 17:16:17 +00:00
|
|
|
if c.Crowdsec.AcquisitionDirPath == "" && c.Crowdsec.AcquisitionFilePath == "" {
|
2022-10-17 15:32:08 +00:00
|
|
|
log.Warning("no acquisition_path or acquisition_dir specified")
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(c.Crowdsec.AcquisitionFiles) == 0 {
|
|
|
|
log.Warning("no acquisition file found")
|
2021-03-24 17:16:17 +00:00
|
|
|
}
|
2022-10-17 15:32:08 +00:00
|
|
|
|
|
|
|
if err = c.LoadSimulation(); err != nil {
|
2023-06-01 14:31:56 +00:00
|
|
|
return fmt.Errorf("load error (simulation): %w", err)
|
2021-05-17 09:54:28 +00:00
|
|
|
}
|
2021-03-24 17:16:17 +00:00
|
|
|
|
|
|
|
c.Crowdsec.ConfigDir = c.ConfigPaths.ConfigDir
|
|
|
|
c.Crowdsec.DataDir = c.ConfigPaths.DataDir
|
|
|
|
c.Crowdsec.HubDir = c.ConfigPaths.HubDir
|
|
|
|
c.Crowdsec.HubIndexFile = c.ConfigPaths.HubIndexFile
|
2022-10-17 15:32:08 +00:00
|
|
|
|
2021-03-24 17:16:17 +00:00
|
|
|
if c.Crowdsec.ParserRoutinesCount <= 0 {
|
|
|
|
c.Crowdsec.ParserRoutinesCount = 1
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.Crowdsec.BucketsRoutinesCount <= 0 {
|
|
|
|
c.Crowdsec.BucketsRoutinesCount = 1
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.Crowdsec.OutputRoutinesCount <= 0 {
|
|
|
|
c.Crowdsec.OutputRoutinesCount = 1
|
|
|
|
}
|
|
|
|
|
|
|
|
var crowdsecCleanup = []*string{
|
|
|
|
&c.Crowdsec.AcquisitionFilePath,
|
|
|
|
}
|
2022-10-17 15:32:08 +00:00
|
|
|
|
2021-03-24 17:16:17 +00:00
|
|
|
for _, k := range crowdsecCleanup {
|
|
|
|
if *k == "" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
*k, err = filepath.Abs(*k)
|
|
|
|
if err != nil {
|
2023-06-01 14:31:56 +00:00
|
|
|
return fmt.Errorf("failed to get absolute path of '%s': %w", *k, err)
|
2021-03-24 17:16:17 +00:00
|
|
|
}
|
|
|
|
}
|
2022-10-17 15:32:08 +00:00
|
|
|
|
|
|
|
// Convert relative paths to absolute paths
|
2021-03-24 17:16:17 +00:00
|
|
|
for i, file := range c.Crowdsec.AcquisitionFiles {
|
|
|
|
f, err := filepath.Abs(file)
|
|
|
|
if err != nil {
|
2023-06-01 14:31:56 +00:00
|
|
|
return fmt.Errorf("failed to get absolute path of '%s': %w", file, err)
|
2021-03-24 17:16:17 +00:00
|
|
|
}
|
|
|
|
c.Crowdsec.AcquisitionFiles[i] = f
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := c.LoadAPIClient(); err != nil {
|
2022-06-22 13:53:53 +00:00
|
|
|
return fmt.Errorf("loading api client: %s", err)
|
2021-03-24 17:16:17 +00:00
|
|
|
}
|
2022-10-17 15:32:08 +00:00
|
|
|
|
2021-03-24 17:16:17 +00:00
|
|
|
if err := c.LoadHub(); err != nil {
|
2023-06-01 14:31:56 +00:00
|
|
|
return fmt.Errorf("while loading hub: %w", err)
|
2021-03-24 17:16:17 +00:00
|
|
|
}
|
2022-10-17 15:32:08 +00:00
|
|
|
|
2023-01-04 15:50:02 +00:00
|
|
|
c.Crowdsec.ContextToSend = make(map[string][]string, 0)
|
|
|
|
fallback := false
|
|
|
|
if c.Crowdsec.ConsoleContextPath == "" {
|
|
|
|
// fallback to default config file
|
|
|
|
c.Crowdsec.ConsoleContextPath = filepath.Join(c.Crowdsec.ConfigDir, "console", "context.yaml")
|
|
|
|
fallback = true
|
|
|
|
}
|
|
|
|
|
|
|
|
f, err := filepath.Abs(c.Crowdsec.ConsoleContextPath)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("fail to get absolute path of %s: %s", c.Crowdsec.ConsoleContextPath, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
c.Crowdsec.ConsoleContextPath = f
|
|
|
|
yamlFile, err := os.ReadFile(c.Crowdsec.ConsoleContextPath)
|
|
|
|
if err != nil {
|
|
|
|
if fallback {
|
|
|
|
log.Debugf("Default context config file doesn't exist, will not use it")
|
|
|
|
} else {
|
|
|
|
return fmt.Errorf("failed to open context file: %s", err)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
err = yaml.Unmarshal(yamlFile, c.Crowdsec.ContextToSend)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("unmarshaling labels console config file '%s': %s", c.Crowdsec.ConsoleContextPath, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *CrowdsecServiceCfg) DumpContextConfigFile() error {
|
|
|
|
var out []byte
|
|
|
|
var err error
|
|
|
|
|
|
|
|
if out, err = yaml.Marshal(c.ContextToSend); err != nil {
|
2023-06-01 14:31:56 +00:00
|
|
|
return fmt.Errorf("while marshaling ConsoleConfig (for %s): %w", c.ConsoleContextPath, err)
|
2023-01-04 15:50:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if err := os.WriteFile(c.ConsoleContextPath, out, 0600); err != nil {
|
2023-06-01 14:31:56 +00:00
|
|
|
return fmt.Errorf("while dumping console config to %s: %w", c.ConsoleContextPath, err)
|
2023-01-04 15:50:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
log.Infof("%s file saved", c.ConsoleContextPath)
|
|
|
|
|
2021-03-24 17:16:17 +00:00
|
|
|
return nil
|
|
|
|
}
|