diff --git a/pkg/config/setup/system_probe.go b/pkg/config/setup/system_probe.go index d3e214503c59bc..edeee3ade54a3d 100644 --- a/pkg/config/setup/system_probe.go +++ b/pkg/config/setup/system_probe.go @@ -367,6 +367,7 @@ func InitSystemProbeConfig(cfg pkgconfigmodel.Config) { eventMonitorBindEnvAndSetDefault(cfg, join(evNS, "network.lazy_interface_prefixes"), []string{}) eventMonitorBindEnvAndSetDefault(cfg, join(evNS, "network.classifier_priority"), 10) eventMonitorBindEnvAndSetDefault(cfg, join(evNS, "network.classifier_handle"), 0) + eventMonitorBindEnvAndSetDefault(cfg, join(evNS, "network.raw_classifier_handle"), 0) eventMonitorBindEnvAndSetDefault(cfg, join(evNS, "event_stream.use_ring_buffer"), true) eventMonitorBindEnvAndSetDefault(cfg, join(evNS, "event_stream.use_fentry"), false) eventMonitorBindEnvAndSetDefault(cfg, join(evNS, "event_stream.use_fentry_amd64"), false) diff --git a/pkg/security/ebpf/probes/all.go b/pkg/security/ebpf/probes/all.go index ece52381b31f35..e501a61ff926f6 100644 --- a/pkg/security/ebpf/probes/all.go +++ b/pkg/security/ebpf/probes/all.go @@ -76,7 +76,7 @@ func AllProbes(fentry bool) []*manager.Probe { allProbes = append(allProbes, getSpliceProbes(fentry)...) allProbes = append(allProbes, getFlowProbes()...) allProbes = append(allProbes, getNetDeviceProbes()...) - allProbes = append(allProbes, GetTCProbes(true)...) + allProbes = append(allProbes, GetTCProbes(true, true)...) allProbes = append(allProbes, getBindProbes(fentry)...) allProbes = append(allProbes, getConnectProbes(fentry)...) allProbes = append(allProbes, getSyscallMonitorProbes()...) diff --git a/pkg/security/ebpf/probes/tc.go b/pkg/security/ebpf/probes/tc.go index 5fb7349870a258..0a26151ce75902 100644 --- a/pkg/security/ebpf/probes/tc.go +++ b/pkg/security/ebpf/probes/tc.go @@ -16,7 +16,7 @@ import ( ) // GetTCProbes returns the list of TCProbes -func GetTCProbes(withNetworkIngress bool) []*manager.Probe { +func GetTCProbes(withNetworkIngress bool, withRawPacket bool) []*manager.Probe { out := []*manager.Probe{ { ProbeIdentificationPair: manager.ProbeIdentificationPair{ @@ -27,7 +27,10 @@ func GetTCProbes(withNetworkIngress bool) []*manager.Probe { TCFilterProtocol: unix.ETH_P_ALL, KeepProgramSpec: true, }, - { + } + + if withRawPacket { + out = append(out, &manager.Probe{ ProbeIdentificationPair: manager.ProbeIdentificationPair{ UID: SecurityAgentUID, EBPFFuncName: "classifier_raw_packet_egress", @@ -35,7 +38,7 @@ func GetTCProbes(withNetworkIngress bool) []*manager.Probe { NetworkDirection: manager.Egress, TCFilterProtocol: unix.ETH_P_ALL, KeepProgramSpec: true, - }, + }) } if withNetworkIngress { @@ -48,15 +51,18 @@ func GetTCProbes(withNetworkIngress bool) []*manager.Probe { TCFilterProtocol: unix.ETH_P_ALL, KeepProgramSpec: true, }) - out = append(out, &manager.Probe{ - ProbeIdentificationPair: manager.ProbeIdentificationPair{ - UID: SecurityAgentUID, - EBPFFuncName: "classifier_raw_packet_ingress", - }, - NetworkDirection: manager.Ingress, - TCFilterProtocol: unix.ETH_P_ALL, - KeepProgramSpec: true, - }) + + if withRawPacket { + out = append(out, &manager.Probe{ + ProbeIdentificationPair: manager.ProbeIdentificationPair{ + UID: SecurityAgentUID, + EBPFFuncName: "classifier_raw_packet_ingress", + }, + NetworkDirection: manager.Ingress, + TCFilterProtocol: unix.ETH_P_ALL, + KeepProgramSpec: true, + }) + } } return out @@ -94,7 +100,7 @@ func GetAllTCProgramFunctions() []string { "classifier_raw_packet", } - for _, tcProbe := range GetTCProbes(true) { + for _, tcProbe := range GetTCProbes(true, true) { output = append(output, tcProbe.EBPFFuncName) } diff --git a/pkg/security/probe/config/config.go b/pkg/security/probe/config/config.go index ab86af5410f4eb..8a5942074a7f0c 100644 --- a/pkg/security/probe/config/config.go +++ b/pkg/security/probe/config/config.go @@ -121,6 +121,9 @@ type Config struct { // NetworkClassifierHandle defines the handle at which CWS should insert its TC classifiers. NetworkClassifierHandle uint16 + // RawNetworkClassifierHandle defines the handle at which CWS should insert its Raw TC classifiers. + RawNetworkClassifierHandle uint16 + // ProcessConsumerEnabled defines if the process-agent wants to receive kernel events ProcessConsumerEnabled bool @@ -173,6 +176,7 @@ func NewConfig() (*Config, error) { NetworkLazyInterfacePrefixes: getStringSlice("network.lazy_interface_prefixes"), NetworkClassifierPriority: uint16(getInt("network.classifier_priority")), NetworkClassifierHandle: uint16(getInt("network.classifier_handle")), + RawNetworkClassifierHandle: uint16(getInt("network.raw_classifier_handle")), EventStreamUseRingBuffer: getBool("event_stream.use_ring_buffer"), EventStreamBufferSize: getInt("event_stream.buffer_size"), EventStreamUseFentry: getEventStreamFentryValue(), @@ -208,6 +212,18 @@ func (c *Config) sanitize() error { c.MapDentryResolutionEnabled = true } + if c.NetworkRawPacketEnabled { + if c.RawNetworkClassifierHandle != c.NetworkClassifierHandle { + if c.NetworkClassifierHandle*c.RawNetworkClassifierHandle == 0 { + return fmt.Errorf("none or both of network.classifier_handle and network.raw_classifier_handle must be provided: got classifier_handle:%d raw_classifier_handle:%d", c.NetworkClassifierHandle, c.RawNetworkClassifierHandle) + } + } else { + if c.NetworkClassifierHandle*c.RawNetworkClassifierHandle != 0 { + return fmt.Errorf("network.classifier_handle and network.raw_classifier_handle can't be equal and not null: got classifier_handle:%d raw_classifier_handle:%d", c.NetworkClassifierHandle, c.RawNetworkClassifierHandle) + } + } + } + // not enable at the system-probe level, disable for cws as well if !c.Config.EnableRuntimeCompiler { c.RuntimeCompilationEnabled = false diff --git a/pkg/security/resolvers/netns/resolver.go b/pkg/security/resolvers/netns/resolver.go index 73a5d92f8920c0..fb2506a4f806a6 100644 --- a/pkg/security/resolvers/netns/resolver.go +++ b/pkg/security/resolvers/netns/resolver.go @@ -163,7 +163,9 @@ func (nn *NetworkNamespace) dequeueNetworkDevices(tcResolver *tc.Resolver, manag }() for _, queuedDevice := range nn.networkDevicesQueue { - _ = tcResolver.SetupNewTCClassifierWithNetNSHandle(queuedDevice, handle, manager) + if err = tcResolver.SetupNewTCClassifierWithNetNSHandle(queuedDevice, handle, manager); err != nil { + seclog.Errorf("error setting up new tc classifier on queued device: %v", err) + } } nn.flushNetworkDevicesQueue() } @@ -346,6 +348,8 @@ func (nr *Resolver) snapshotNetworkDevices(netns *NetworkNamespace) int { if !nr.IsLazyDeletionInterface(device.Name) && attrs.HardwareAddr.String() != "" { attachedDeviceCountNoLazyDeletion++ } + } else { + seclog.Errorf("error setting up new tc classifier on snapshot: %v", err) } } diff --git a/pkg/security/resolvers/tc/resolver.go b/pkg/security/resolvers/tc/resolver.go index 379311999c3b31..eef9bbf1dfde9f 100644 --- a/pkg/security/resolvers/tc/resolver.go +++ b/pkg/security/resolvers/tc/resolver.go @@ -94,11 +94,7 @@ func (tcr *Resolver) SetupNewTCClassifierWithNetNSHandle(device model.NetDevice, defer tcr.Unlock() var combinedErr multierror.Error - for _, tcProbe := range probes.GetTCProbes(tcr.config.NetworkIngressEnabled) { - if !tcr.config.NetworkRawPacketEnabled && slices.Contains(probes.RawPacketTCProgram, tcProbe.EBPFFuncName) { - continue - } - + for _, tcProbe := range probes.GetTCProbes(tcr.config.NetworkIngressEnabled, tcr.config.NetworkRawPacketEnabled) { // make sure we're not overriding an existing network probe progKey := ProgramKey{ UID: tcProbe.UID, @@ -120,7 +116,12 @@ func (tcr *Resolver) SetupNewTCClassifierWithNetNSHandle(device model.NetDevice, newProbe.IfIndexNetnsID = device.NetNS newProbe.KeepProgramSpec = false newProbe.TCFilterPrio = tcr.config.NetworkClassifierPriority - newProbe.TCFilterHandle = netlink.MakeHandle(0, tcr.config.NetworkClassifierHandle) + + if slices.Contains(probes.RawPacketTCProgram, tcProbe.EBPFFuncName) { + newProbe.TCFilterHandle = netlink.MakeHandle(0, tcr.config.RawNetworkClassifierHandle) + } else { + newProbe.TCFilterHandle = netlink.MakeHandle(0, tcr.config.NetworkClassifierHandle) + } netnsEditor := []manager.ConstantEditor{ {