Browse Source

Make plugin runner configurable and run only registered plugins (#944)

* Make plugin runner configurable and run only registered plugins
Shivam Sandbhor 3 years ago
parent
commit
b8e24a1e0b
5 changed files with 25 additions and 6 deletions
  1. 1 1
      cmd/crowdsec/api.go
  2. 3 0
      config/config.yaml
  3. 1 0
      pkg/csconfig/config.go
  4. 6 0
      pkg/csconfig/plugin_config.go
  5. 14 5
      pkg/csplugin/broker.go

+ 1 - 1
cmd/crowdsec/api.go

@@ -18,7 +18,7 @@ func initAPIServer(cConfig *csconfig.Config) (*apiserver.APIServer, error) {
 
 
 	if hasPlugins(cConfig.API.Server.Profiles) {
 	if hasPlugins(cConfig.API.Server.Profiles) {
 		log.Info("initiating plugin broker")
 		log.Info("initiating plugin broker")
-		err = pluginBroker.Init(cConfig.API.Server.Profiles, cConfig.ConfigPaths)
+		err = pluginBroker.Init(cConfig.PluginConfig, cConfig.API.Server.Profiles, cConfig.ConfigPaths)
 		if err != nil {
 		if err != nil {
 			return nil, fmt.Errorf("unable to run local API: %s", err)
 			return nil, fmt.Errorf("unable to run local API: %s", err)
 		}
 		}

+ 3 - 0
config/config.yaml

@@ -30,6 +30,9 @@ db_config:
   flush:
   flush:
     max_items: 5000
     max_items: 5000
     max_age: 7d
     max_age: 7d
+plugin_config:
+  user: nobody # plugin process would be ran on behalf of this user
+  group: nogroup # plugin process would be ran on behalf of this group
 api:
 api:
   client:
   client:
     insecure_skip_verify: false
     insecure_skip_verify: false

+ 1 - 0
pkg/csconfig/config.go

@@ -22,6 +22,7 @@ type Config struct {
 	DbConfig     *DatabaseCfg        `yaml:"db_config,omitempty"`
 	DbConfig     *DatabaseCfg        `yaml:"db_config,omitempty"`
 	API          *APICfg             `yaml:"api,omitempty"`
 	API          *APICfg             `yaml:"api,omitempty"`
 	ConfigPaths  *ConfigurationPaths `yaml:"config_paths,omitempty"`
 	ConfigPaths  *ConfigurationPaths `yaml:"config_paths,omitempty"`
+	PluginConfig *PluginCfg          `yaml:"plugin_config,omitempty"`
 	DisableAPI   bool                `yaml:"-"`
 	DisableAPI   bool                `yaml:"-"`
 	DisableAgent bool                `yaml:"-"`
 	DisableAgent bool                `yaml:"-"`
 	Hub          *Hub                `yaml:"-"`
 	Hub          *Hub                `yaml:"-"`

+ 6 - 0
pkg/csconfig/plugin_config.go

@@ -0,0 +1,6 @@
+package csconfig
+
+type PluginCfg struct {
+	User  string
+	Group string
+}

+ 14 - 5
pkg/csplugin/broker.go

@@ -47,6 +47,8 @@ type PluginBroker struct {
 	notificationPluginByName        map[string]Notifier
 	notificationPluginByName        map[string]Notifier
 	watcher                         PluginWatcher
 	watcher                         PluginWatcher
 	pluginKillMethods               []func()
 	pluginKillMethods               []func()
+	pluginProcConfig                *csconfig.PluginCfg
+	pluginsTypesToDispatch          map[string]struct{}
 }
 }
 
 
 // holder to determine where to dispatch config and how to format messages
 // holder to determine where to dispatch config and how to format messages
@@ -69,7 +71,7 @@ type ProfileAlert struct {
 	Alert     *models.Alert
 	Alert     *models.Alert
 }
 }
 
 
-func (pb *PluginBroker) Init(profileConfigs []*csconfig.ProfileCfg, configPaths *csconfig.ConfigurationPaths) error {
+func (pb *PluginBroker) Init(pluginCfg *csconfig.PluginCfg, profileConfigs []*csconfig.ProfileCfg, configPaths *csconfig.ConfigurationPaths) error {
 	pb.PluginChannel = make(chan ProfileAlert)
 	pb.PluginChannel = make(chan ProfileAlert)
 	pb.notificationConfigsByPluginType = make(map[string][][]byte)
 	pb.notificationConfigsByPluginType = make(map[string][][]byte)
 	pb.notificationPluginByName = make(map[string]Notifier)
 	pb.notificationPluginByName = make(map[string]Notifier)
@@ -77,6 +79,8 @@ func (pb *PluginBroker) Init(profileConfigs []*csconfig.ProfileCfg, configPaths
 	pb.pluginConfigByName = make(map[string]PluginConfig)
 	pb.pluginConfigByName = make(map[string]PluginConfig)
 	pb.alertsByPluginName = make(map[string][]*models.Alert)
 	pb.alertsByPluginName = make(map[string][]*models.Alert)
 	pb.profileConfigs = profileConfigs
 	pb.profileConfigs = profileConfigs
+	pb.pluginProcConfig = pluginCfg
+	pb.pluginsTypesToDispatch = make(map[string]struct{})
 	if err := pb.loadConfig(configPaths.NotificationDir); err != nil {
 	if err := pb.loadConfig(configPaths.NotificationDir); err != nil {
 		return errors.Wrap(err, "while loading plugin config")
 		return errors.Wrap(err, "while loading plugin config")
 	}
 	}
@@ -178,6 +182,7 @@ func (pb *PluginBroker) verifyPluginConfigsWithProfile() error {
 			if _, ok := pb.pluginConfigByName[pluginName]; !ok {
 			if _, ok := pb.pluginConfigByName[pluginName]; !ok {
 				return fmt.Errorf("config file for plugin %s not found", pluginName)
 				return fmt.Errorf("config file for plugin %s not found", pluginName)
 			}
 			}
+			pb.pluginsTypesToDispatch[pb.pluginConfigByName[pluginName].Type] = struct{}{}
 		}
 		}
 	}
 	}
 	return nil
 	return nil
@@ -200,6 +205,10 @@ func (pb *PluginBroker) loadPlugins(path string) error {
 			continue
 			continue
 		}
 		}
 
 
+		if _, ok := pb.pluginsTypesToDispatch[pSubtype]; !ok {
+			continue
+		}
+
 		pluginClient, err := pb.loadNotificationPlugin(pSubtype, binaryPath)
 		pluginClient, err := pb.loadNotificationPlugin(pSubtype, binaryPath)
 		if err != nil {
 		if err != nil {
 			return err
 			return err
@@ -231,7 +240,7 @@ func (pb *PluginBroker) loadNotificationPlugin(name string, binaryPath string) (
 		return nil, err
 		return nil, err
 	}
 	}
 	cmd := exec.Command(binaryPath)
 	cmd := exec.Command(binaryPath)
-	cmd.SysProcAttr, err = getProccessAtr()
+	cmd.SysProcAttr, err = getProccessAtr(pb.pluginProcConfig.User, pb.pluginProcConfig.Group)
 	if err != nil {
 	if err != nil {
 		return nil, errors.Wrap(err, "while getting process attributes")
 		return nil, errors.Wrap(err, "while getting process attributes")
 	}
 	}
@@ -378,12 +387,12 @@ func getPluginTypeAndSubtypeFromPath(path string) (string, string, error) {
 	return strings.Join(parts[:len(parts)-1], "-"), parts[len(parts)-1], nil
 	return strings.Join(parts[:len(parts)-1], "-"), parts[len(parts)-1], nil
 }
 }
 
 
-func getProccessAtr() (*syscall.SysProcAttr, error) {
-	u, err := user.Lookup("nobody")
+func getProccessAtr(username string, groupname string) (*syscall.SysProcAttr, error) {
+	u, err := user.Lookup(username)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
-	g, err := user.LookupGroup("nogroup")
+	g, err := user.LookupGroup(groupname)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}