support ip and cidr based whitelists for capi and 3rd party blocklists (#2132)

* support ip and cidr based whitelists for capi and 3rd party blocklist
This commit is contained in:
Thibault "bui" Koechlin 2023-03-21 11:50:10 +01:00 committed by GitHub
parent d87f088b8f
commit a74e424d53
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 292 additions and 5 deletions

View file

@ -173,6 +173,11 @@ func toValidCIDR(ip string) string {
return ip + "/32"
}
type CapiWhitelist struct {
Ips []net.IP `yaml:"ips,omitempty"`
Cidrs []*net.IPNet `yaml:"cidrs,omitempty"`
}
/*local api service configuration*/
type LocalApiServerCfg struct {
Enable *bool `yaml:"enable"`
@ -196,6 +201,8 @@ type LocalApiServerCfg struct {
TrustedIPs []string `yaml:"trusted_ips,omitempty"`
PapiLogLevel *log.Level `yaml:"papi_log_level"`
DisableRemoteLapiRegistration bool `yaml:"disable_remote_lapi_registration,omitempty"`
CapiWhitelistsPath string `yaml:"capi_whitelists_path,omitempty"`
CapiWhitelists *CapiWhitelist `yaml:"-"`
}
type TLSCfg struct {
@ -242,6 +249,11 @@ func (c *Config) LoadAPIServer() error {
if err := c.LoadDBConfig(); err != nil {
return err
}
if err := c.API.Server.LoadCapiWhitelists(); err != nil {
return err
}
} else {
log.Warning("crowdsec local API is disabled")
c.DisableAPI = true
@ -306,6 +318,49 @@ func (c *Config) LoadAPIServer() error {
return nil
}
// we cannot unmarshal to type net.IPNet, so we need to do it manually
type capiWhitelists struct {
Ips []string `yaml:"ips"`
Cidrs []string `yaml:"cidrs"`
}
func (s *LocalApiServerCfg) LoadCapiWhitelists() error {
if s.CapiWhitelistsPath == "" {
return nil
}
if _, err := os.Stat(s.CapiWhitelistsPath); os.IsNotExist(err) {
return fmt.Errorf("capi whitelist file '%s' does not exist", s.CapiWhitelistsPath)
}
fd, err := os.Open(s.CapiWhitelistsPath)
if err != nil {
return fmt.Errorf("unable to open capi whitelist file '%s': %s", s.CapiWhitelistsPath, err)
}
var fromCfg capiWhitelists
s.CapiWhitelists = &CapiWhitelist{}
defer fd.Close()
decoder := yaml.NewDecoder(fd)
if err := decoder.Decode(&fromCfg); err != nil {
return fmt.Errorf("while parsing capi whitelist file '%s': %s", s.CapiWhitelistsPath, err)
}
for _, v := range fromCfg.Ips {
ip := net.ParseIP(v)
if ip == nil {
return fmt.Errorf("unable to parse ip whitelist '%s'", v)
}
s.CapiWhitelists.Ips = append(s.CapiWhitelists.Ips, ip)
}
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)
}
s.CapiWhitelists.Cidrs = append(s.CapiWhitelists.Cidrs, tnet)
}
return nil
}
func (c *Config) LoadAPIClient() error {
if c.API == nil || c.API.Client == nil || c.API.Client.CredentialsFilePath == "" || c.DisableAgent {
return fmt.Errorf("no API client section in configuration")