github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/controller/config.go (about)

     1  package controller
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"sync"
     7  	"time"
     8  
     9  	"github.com/blang/semver"
    10  	"go.aporeto.io/enforcerd/trireme-lib/collector"
    11  	"go.aporeto.io/enforcerd/trireme-lib/common"
    12  	"go.aporeto.io/enforcerd/trireme-lib/controller/constants"
    13  	"go.aporeto.io/enforcerd/trireme-lib/controller/internal/enforcer"
    14  	enforcerproxy "go.aporeto.io/enforcerd/trireme-lib/controller/internal/enforcer/proxy"
    15  	"go.aporeto.io/enforcerd/trireme-lib/controller/internal/enforcer/utils/rpcwrapper"
    16  	"go.aporeto.io/enforcerd/trireme-lib/controller/internal/supervisor"
    17  	supervisornoop "go.aporeto.io/enforcerd/trireme-lib/controller/internal/supervisor/noop"
    18  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/env"
    19  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/fqconfig"
    20  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/packetprocessor"
    21  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/secrets"
    22  	"go.aporeto.io/enforcerd/trireme-lib/controller/runtime"
    23  
    24  	"go.aporeto.io/enforcerd/trireme-lib/policy"
    25  	"go.uber.org/zap"
    26  )
    27  
    28  // config specifies all configurations accepted by trireme to start.
    29  type config struct {
    30  	// Required Parameters.
    31  	serverID string
    32  
    33  	// External Interface implementations that we allow to plugin to components.
    34  	collector collector.EventCollector
    35  	service   packetprocessor.PacketProcessor
    36  	secret    secrets.Secrets
    37  
    38  	// Configurations for fine tuning internal components.
    39  	mode                   constants.ModeType
    40  	fq                     fqconfig.FilterQueue
    41  	isBPFEnabled           bool
    42  	linuxProcess           bool
    43  	mutualAuth             bool
    44  	packetLogs             bool
    45  	validity               time.Duration
    46  	procMountPoint         string
    47  	externalIPcacheTimeout time.Duration
    48  	runtimeCfg             *runtime.Configuration
    49  	runtimeErrorChannel    chan *policy.RuntimeError
    50  	remoteParameters       *env.RemoteParameters
    51  	tokenIssuer            common.ServiceTokenIssuer
    52  	ipv6Enabled            bool
    53  	agentVersion           semver.Version
    54  	iptablesLockfile       string
    55  }
    56  
    57  // Option is provided using functional arguments.
    58  type Option func(*config)
    59  
    60  // OptionBPFEnabled is an option
    61  func OptionBPFEnabled(bpfEnabled bool) Option {
    62  	return func(cfg *config) {
    63  		cfg.isBPFEnabled = bpfEnabled
    64  	}
    65  }
    66  
    67  // OptionIptablesLockfile is a string option to set the path to the iptables lockfile
    68  func OptionIptablesLockfile(iptablesLockfile string) Option {
    69  	return func(cfg *config) {
    70  		cfg.iptablesLockfile = iptablesLockfile
    71  	}
    72  }
    73  
    74  //OptionIPv6Enable is an option to enable ipv6
    75  func OptionIPv6Enable(ipv6Enabled bool) Option {
    76  	return func(cfg *config) {
    77  		cfg.ipv6Enabled = ipv6Enabled
    78  	}
    79  }
    80  
    81  // OptionCollector is an option to provide an external collector implementation.
    82  func OptionCollector(c collector.EventCollector) Option {
    83  	return func(cfg *config) {
    84  		cfg.collector = c
    85  	}
    86  }
    87  
    88  // OptionDatapathService is an option to provide an external datapath service implementation.
    89  func OptionDatapathService(s packetprocessor.PacketProcessor) Option {
    90  	return func(cfg *config) {
    91  		cfg.service = s
    92  	}
    93  }
    94  
    95  // OptionSecret is an option to provide an external datapath service implementation.
    96  func OptionSecret(s secrets.Secrets) Option {
    97  	return func(cfg *config) {
    98  		cfg.secret = s
    99  	}
   100  }
   101  
   102  // OptionEnforceLinuxProcess is an option to request support for linux process support.
   103  func OptionEnforceLinuxProcess() Option {
   104  	return func(cfg *config) {
   105  		cfg.linuxProcess = true
   106  	}
   107  }
   108  
   109  // OptionEnforceFqConfig is an option to override filter queues.
   110  func OptionEnforceFqConfig(f fqconfig.FilterQueue) Option {
   111  	return func(cfg *config) {
   112  		cfg.fq = f
   113  	}
   114  }
   115  
   116  // OptionDisableMutualAuth is an option to disable MutualAuth (enabled by default)
   117  func OptionDisableMutualAuth() Option {
   118  	return func(cfg *config) {
   119  		cfg.mutualAuth = false
   120  	}
   121  }
   122  
   123  // OptionRuntimeConfiguration is an option to provide target network configuration.
   124  func OptionRuntimeConfiguration(c *runtime.Configuration) Option {
   125  	return func(cfg *config) {
   126  		cfg.runtimeCfg = c
   127  	}
   128  }
   129  
   130  // OptionProcMountPoint is an option to provide proc mount point.
   131  func OptionProcMountPoint(p string) Option {
   132  	return func(cfg *config) {
   133  		cfg.procMountPoint = p
   134  	}
   135  }
   136  
   137  // OptionRuntimeErrorChannel configures the error channel for the policy engine.
   138  func OptionRuntimeErrorChannel(errorChannel chan *policy.RuntimeError) Option {
   139  	return func(cfg *config) {
   140  		cfg.runtimeErrorChannel = errorChannel
   141  	}
   142  
   143  }
   144  
   145  // OptionPacketLogs is an option to enable packet level logging.
   146  func OptionPacketLogs() Option {
   147  	return func(cfg *config) {
   148  		cfg.packetLogs = true
   149  	}
   150  }
   151  
   152  // OptionRemoteParameters is an option to set the parameters for the remote
   153  func OptionRemoteParameters(p *env.RemoteParameters) Option {
   154  	return func(cfg *config) {
   155  		cfg.remoteParameters = p
   156  	}
   157  }
   158  
   159  // OptionTokenIssuer provides the token issuer.
   160  func OptionTokenIssuer(t common.ServiceTokenIssuer) Option {
   161  	return func(cfg *config) {
   162  		cfg.tokenIssuer = t
   163  	}
   164  }
   165  
   166  // OptionAgentVersion is an option to set agent version.
   167  func OptionAgentVersion(v semver.Version) Option {
   168  	return func(cfg *config) {
   169  		cfg.agentVersion = v
   170  	}
   171  }
   172  
   173  func (t *trireme) newEnforcers(ctx context.Context) error {
   174  	zap.L().Debug("LinuxProcessSupport", zap.Bool("Status", t.config.linuxProcess))
   175  	var err error
   176  	if t.config.linuxProcess {
   177  		t.enforcers[constants.LocalServer], err = enforcer.New(
   178  			t.config.mutualAuth,
   179  			t.config.fq,
   180  			t.config.collector,
   181  			t.config.secret,
   182  			t.config.serverID,
   183  			t.config.validity,
   184  			constants.LocalServer,
   185  			t.config.procMountPoint,
   186  			t.config.externalIPcacheTimeout,
   187  			t.config.packetLogs,
   188  			t.config.runtimeCfg,
   189  			t.config.tokenIssuer,
   190  			t.config.isBPFEnabled,
   191  			t.config.agentVersion,
   192  			policy.None,
   193  		)
   194  		if err != nil {
   195  			return fmt.Errorf("Failed to initialize LocalServer enforcer: %s ", err)
   196  		}
   197  		err = t.setupEnvoyAuthorizer()
   198  		if err != nil {
   199  			return fmt.Errorf("Failed to initialize LocalEnvoyAuthorizer enforcer: %s ", err)
   200  		}
   201  	}
   202  
   203  	if t.config.mode == constants.RemoteContainer {
   204  		enforcerProxy := enforcerproxy.NewProxyEnforcer(
   205  			ctx,
   206  			t.config.mutualAuth,
   207  			t.config.fq,
   208  			t.config.collector,
   209  			t.config.secret,
   210  			t.config.serverID,
   211  			t.config.validity,
   212  			"enforce",
   213  			t.config.procMountPoint,
   214  			t.config.externalIPcacheTimeout,
   215  			t.config.packetLogs,
   216  			t.config.runtimeCfg,
   217  			t.config.runtimeErrorChannel,
   218  			t.config.remoteParameters,
   219  			t.config.tokenIssuer,
   220  			t.config.isBPFEnabled,
   221  			t.config.ipv6Enabled,
   222  			t.config.iptablesLockfile,
   223  			rpcwrapper.NewRPCServer(),
   224  		)
   225  		t.enforcers[constants.RemoteContainer] = enforcerProxy
   226  		t.enforcers[constants.RemoteContainerEnvoyAuthorizer] = enforcerProxy
   227  	}
   228  
   229  	zap.L().Debug("TriremeMode", zap.Int("Status", int(t.config.mode)))
   230  	return nil
   231  }
   232  
   233  func (t *trireme) newSupervisors() error {
   234  
   235  	noopSup := supervisornoop.NewNoopSupervisor()
   236  
   237  	if t.config.linuxProcess {
   238  		sup, err := supervisor.NewSupervisor(
   239  			t.config.collector,
   240  			t.enforcers[constants.LocalServer],
   241  			constants.LocalServer,
   242  			t.config.runtimeCfg,
   243  			t.config.ipv6Enabled,
   244  			t.config.iptablesLockfile,
   245  		)
   246  		if err != nil {
   247  			return fmt.Errorf("Could Not create process supervisor :: received error %v", err)
   248  		}
   249  
   250  		t.supervisors[constants.LocalServer] = sup
   251  		err = t.setupEnvoySupervisor(noopSup)
   252  		if err != nil {
   253  			return fmt.Errorf("Could Not create envoy supervisor :: received error %v", err)
   254  		}
   255  	}
   256  
   257  	if t.config.mode == constants.RemoteContainer {
   258  		t.supervisors[constants.RemoteContainer] = noopSup
   259  		t.supervisors[constants.RemoteContainerEnvoyAuthorizer] = noopSup
   260  	}
   261  
   262  	return nil
   263  }
   264  
   265  // newTrireme returns a reference to the trireme object based on the parameter subelements.
   266  func newTrireme(ctx context.Context, c *config) TriremeController {
   267  
   268  	var err error
   269  
   270  	t := &trireme{
   271  		config:               c,
   272  		enforcers:            map[constants.ModeType]enforcer.Enforcer{},
   273  		supervisors:          map[constants.ModeType]supervisor.Supervisor{},
   274  		puTypeToEnforcerType: map[common.PUType]constants.ModeType{},
   275  		locks:                sync.Map{},
   276  		enablingTrace:        make(chan *traceTrigger, 10),
   277  	}
   278  
   279  	zap.L().Debug("Creating Enforcers")
   280  	if err = t.newEnforcers(ctx); err != nil {
   281  		zap.L().Error("Unable to create datapath enforcers", zap.Error(err))
   282  		return nil
   283  	}
   284  
   285  	zap.L().Debug("Creating Supervisors")
   286  	if err = t.newSupervisors(); err != nil {
   287  		zap.L().Error("Unable to start datapath supervisor", zap.Error(err))
   288  		return nil
   289  	}
   290  
   291  	if c.linuxProcess {
   292  		t.puTypeToEnforcerType[common.LinuxProcessPU] = constants.LocalServer
   293  		t.puTypeToEnforcerType[common.WindowsProcessPU] = constants.LocalServer
   294  		t.puTypeToEnforcerType[common.HostPU] = constants.LocalServer
   295  		t.puTypeToEnforcerType[common.HostNetworkPU] = constants.LocalServer
   296  	}
   297  
   298  	if t.config.mode == constants.RemoteContainer {
   299  		t.puTypeToEnforcerType[common.ContainerPU] = constants.RemoteContainer
   300  		t.puTypeToEnforcerType[common.KubernetesPU] = constants.RemoteContainer
   301  	}
   302  
   303  	return t
   304  }