mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[Security Solution] Session Data eventing switch in Linux Endpoint policy (#128149)
This commit is contained in:
parent
6ef78e69a0
commit
96554163ad
8 changed files with 166 additions and 47 deletions
|
@ -12,7 +12,12 @@ import type { PackagePolicy } from '../../../../common';
|
|||
import { migratePackagePolicyToV820 as migration } from './to_v8_2_0';
|
||||
|
||||
describe('8.2.0 Endpoint Package Policy migration', () => {
|
||||
const policyDoc = ({ windowsMalware = {}, macMalware = {}, linuxMalware = {} }) => {
|
||||
const policyDoc = ({
|
||||
windowsMalware = {},
|
||||
macMalware = {},
|
||||
linuxMalware = {},
|
||||
linuxEvents = {},
|
||||
}) => {
|
||||
return {
|
||||
id: 'mock-saved-object-id',
|
||||
attributes: {
|
||||
|
@ -48,6 +53,7 @@ describe('8.2.0 Endpoint Package Policy migration', () => {
|
|||
},
|
||||
linux: {
|
||||
...linuxMalware,
|
||||
...linuxEvents,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -64,12 +70,14 @@ describe('8.2.0 Endpoint Package Policy migration', () => {
|
|||
windowsMalware: { malware: { mode: 'off' } },
|
||||
macMalware: { malware: { mode: 'off' } },
|
||||
linuxMalware: { malware: { mode: 'off' } },
|
||||
linuxEvents: { events: { process: true, file: true, network: true } },
|
||||
});
|
||||
|
||||
const migratedDoc = policyDoc({
|
||||
windowsMalware: { malware: { mode: 'off', blocklist: false } },
|
||||
macMalware: { malware: { mode: 'off', blocklist: false } },
|
||||
linuxMalware: { malware: { mode: 'off', blocklist: false } },
|
||||
linuxEvents: { events: { process: true, file: true, network: true, session_data: false } },
|
||||
});
|
||||
|
||||
expect(migration(initialDoc, {} as SavedObjectMigrationContext)).toEqual(migratedDoc);
|
||||
|
@ -80,12 +88,14 @@ describe('8.2.0 Endpoint Package Policy migration', () => {
|
|||
windowsMalware: { malware: { mode: 'prevent' } },
|
||||
macMalware: { malware: { mode: 'prevent' } },
|
||||
linuxMalware: { malware: { mode: 'prevent' } },
|
||||
linuxEvents: { events: { process: true, file: true, network: true } },
|
||||
});
|
||||
|
||||
const migratedDoc = policyDoc({
|
||||
windowsMalware: { malware: { mode: 'prevent', blocklist: true } },
|
||||
macMalware: { malware: { mode: 'prevent', blocklist: true } },
|
||||
linuxMalware: { malware: { mode: 'prevent', blocklist: true } },
|
||||
linuxEvents: { events: { process: true, file: true, network: true, session_data: false } },
|
||||
});
|
||||
|
||||
expect(migration(initialDoc, {} as SavedObjectMigrationContext)).toEqual(migratedDoc);
|
||||
|
@ -96,12 +106,14 @@ describe('8.2.0 Endpoint Package Policy migration', () => {
|
|||
windowsMalware: { malware: { mode: 'detect' } },
|
||||
macMalware: { malware: { mode: 'detect' } },
|
||||
linuxMalware: { malware: { mode: 'detect' } },
|
||||
linuxEvents: { events: { process: true, file: true, network: true } },
|
||||
});
|
||||
|
||||
const migratedDoc = policyDoc({
|
||||
windowsMalware: { malware: { mode: 'detect', blocklist: true } },
|
||||
macMalware: { malware: { mode: 'detect', blocklist: true } },
|
||||
linuxMalware: { malware: { mode: 'detect', blocklist: true } },
|
||||
linuxEvents: { events: { process: true, file: true, network: true, session_data: false } },
|
||||
});
|
||||
|
||||
expect(migration(initialDoc, {} as SavedObjectMigrationContext)).toEqual(migratedDoc);
|
||||
|
|
|
@ -28,6 +28,8 @@ export const migratePackagePolicyToV820: SavedObjectMigrationFn<PackagePolicy, P
|
|||
policy.windows.malware.blocklist = policy.windows.malware.mode !== 'off';
|
||||
policy.mac.malware.blocklist = policy.mac.malware.mode !== 'off';
|
||||
policy.linux.malware.blocklist = policy.linux.malware.mode !== 'off';
|
||||
|
||||
policy.linux.events.session_data = false;
|
||||
}
|
||||
|
||||
return updatedPackagePolicyDoc;
|
||||
|
|
|
@ -104,6 +104,7 @@ export const policyFactory = (): PolicyConfig => {
|
|||
process: true,
|
||||
file: true,
|
||||
network: true,
|
||||
session_data: false,
|
||||
},
|
||||
malware: {
|
||||
mode: ProtectionModes.prevent,
|
||||
|
|
|
@ -984,6 +984,7 @@ export interface PolicyConfig {
|
|||
file: boolean;
|
||||
process: boolean;
|
||||
network: boolean;
|
||||
session_data: boolean;
|
||||
};
|
||||
malware: ProtectionFields & BlocklistFields;
|
||||
behavior_protection: ProtectionFields & SupportedFields;
|
||||
|
|
|
@ -873,4 +873,15 @@ export const AdvancedPolicySchema: AdvancedPolicySchemaType[] = [
|
|||
}
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'linux.advanced.kernel.capture_mode',
|
||||
first_supported_version: '8.2',
|
||||
documentation: i18n.translate(
|
||||
'xpack.securitySolution.endpoint.policy.advanced.linux.advanced.kernel.capture_mode',
|
||||
{
|
||||
defaultMessage:
|
||||
'Allows users to control whether kprobes or ebpf are used to gather data. Possible options are kprobes, ebpf, or auto. Default: auto',
|
||||
}
|
||||
),
|
||||
},
|
||||
];
|
||||
|
|
|
@ -332,7 +332,7 @@ describe('policy details: ', () => {
|
|||
logging: { file: 'info' },
|
||||
},
|
||||
linux: {
|
||||
events: { process: true, file: true, network: true },
|
||||
events: { process: true, file: true, network: true, session_data: false },
|
||||
logging: { file: 'info' },
|
||||
malware: { mode: 'prevent', blocklist: true },
|
||||
behavior_protection: { mode: 'off', supported: false },
|
||||
|
|
|
@ -5,10 +5,21 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, { useContext, useCallback } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiCheckbox, EuiSpacer, EuiText, htmlIdGenerator } from '@elastic/eui';
|
||||
import {
|
||||
EuiCheckbox,
|
||||
EuiSpacer,
|
||||
EuiText,
|
||||
htmlIdGenerator,
|
||||
EuiSwitch,
|
||||
EuiIconTip,
|
||||
EuiBetaBadge,
|
||||
EuiFlexItem,
|
||||
EuiFlexGroup,
|
||||
} from '@elastic/eui';
|
||||
import { OperatingSystem } from '@kbn/securitysolution-utils';
|
||||
import { ThemeContext } from 'styled-components';
|
||||
import { PolicyOperatingSystem, UIPolicyConfig } from '../../../../../../../common/endpoint/types';
|
||||
import { ConfigForm, ConfigFormHeading } from '../../components/config_form';
|
||||
|
||||
|
@ -34,54 +45,110 @@ export interface EventFormOption<T extends OperatingSystem> {
|
|||
protectionField: ProtectionField<T>;
|
||||
}
|
||||
|
||||
export interface SupplementalEventFormOption<T extends OperatingSystem> {
|
||||
name: string;
|
||||
protectionField: ProtectionField<T>;
|
||||
tooltipText?: string;
|
||||
beta?: boolean;
|
||||
}
|
||||
|
||||
export interface EventsFormProps<T extends OperatingSystem> {
|
||||
os: T;
|
||||
options: ReadonlyArray<EventFormOption<T>>;
|
||||
selection: EventFormSelection<T>;
|
||||
onValueSelection: (value: ProtectionField<T>, selected: boolean) => void;
|
||||
supplementalOptions?: ReadonlyArray<SupplementalEventFormOption<T>>;
|
||||
}
|
||||
|
||||
const countSelected = <T extends OperatingSystem>(selection: EventFormSelection<T>) => {
|
||||
return Object.values(selection).filter((value) => value).length;
|
||||
};
|
||||
|
||||
export const EventsForm = <T extends OperatingSystem>({
|
||||
const InnerEventsForm = <T extends OperatingSystem>({
|
||||
os,
|
||||
options,
|
||||
selection,
|
||||
onValueSelection,
|
||||
}: EventsFormProps<T>) => (
|
||||
<ConfigForm
|
||||
type={i18n.translate('xpack.securitySolution.endpoint.policy.details.eventCollection', {
|
||||
defaultMessage: 'Event collection',
|
||||
})}
|
||||
supportedOss={[os]}
|
||||
rightCorner={
|
||||
<EuiText size="s" color="subdued">
|
||||
{i18n.translate('xpack.securitySolution.endpoint.policy.details.eventCollectionsEnabled', {
|
||||
defaultMessage: '{selected} / {total} event collections enabled',
|
||||
values: { selected: countSelected(selection), total: options.length },
|
||||
})}
|
||||
</EuiText>
|
||||
}
|
||||
>
|
||||
<ConfigFormHeading>
|
||||
{i18n.translate('xpack.securitySolution.endpoint.policyDetailsConfig.eventingEvents', {
|
||||
defaultMessage: 'Events',
|
||||
})}
|
||||
</ConfigFormHeading>
|
||||
<EuiSpacer size="s" />
|
||||
{options.map(({ name, protectionField }) => (
|
||||
<EuiCheckbox
|
||||
key={String(protectionField)}
|
||||
id={htmlIdGenerator()()}
|
||||
label={name}
|
||||
data-test-subj={`policy${OPERATING_SYSTEM_TO_TEST_SUBJ[os]}Event_${protectionField}`}
|
||||
checked={selection[protectionField]}
|
||||
onChange={(event) => onValueSelection(protectionField, event.target.checked)}
|
||||
/>
|
||||
))}
|
||||
</ConfigForm>
|
||||
);
|
||||
supplementalOptions,
|
||||
}: EventsFormProps<T>) => {
|
||||
const theme = useContext(ThemeContext);
|
||||
const countSelected = useCallback(() => {
|
||||
const supplementalSelectionFields: string[] = supplementalOptions
|
||||
? supplementalOptions.map((value) => value.protectionField as string)
|
||||
: [];
|
||||
return Object.entries(selection).filter(([key, value]) =>
|
||||
!supplementalSelectionFields.includes(key) ? value : false
|
||||
).length;
|
||||
}, [selection, supplementalOptions]);
|
||||
|
||||
EventsForm.displayName = 'EventsForm';
|
||||
return (
|
||||
<ConfigForm
|
||||
type={i18n.translate('xpack.securitySolution.endpoint.policy.details.eventCollection', {
|
||||
defaultMessage: 'Event collection',
|
||||
})}
|
||||
supportedOss={[os]}
|
||||
rightCorner={
|
||||
<EuiText size="s" color="subdued">
|
||||
{i18n.translate(
|
||||
'xpack.securitySolution.endpoint.policy.details.eventCollectionsEnabled',
|
||||
{
|
||||
defaultMessage: '{selected} / {total} event collections enabled',
|
||||
values: {
|
||||
selected: countSelected(),
|
||||
total: options.length,
|
||||
},
|
||||
}
|
||||
)}
|
||||
</EuiText>
|
||||
}
|
||||
>
|
||||
<ConfigFormHeading>
|
||||
{i18n.translate('xpack.securitySolution.endpoint.policyDetailsConfig.eventingEvents', {
|
||||
defaultMessage: 'Events',
|
||||
})}
|
||||
</ConfigFormHeading>
|
||||
<EuiSpacer size="s" />
|
||||
{options.map(({ name, protectionField }) => {
|
||||
return (
|
||||
<EuiCheckbox
|
||||
key={String(protectionField)}
|
||||
id={htmlIdGenerator()()}
|
||||
label={name}
|
||||
data-test-subj={`policy${OPERATING_SYSTEM_TO_TEST_SUBJ[os]}Event_${protectionField}`}
|
||||
checked={selection[protectionField]}
|
||||
onChange={(event) => onValueSelection(protectionField, event.target.checked)}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
{supplementalOptions &&
|
||||
supplementalOptions.map(({ name, protectionField, tooltipText, beta }) => {
|
||||
return (
|
||||
<div key={String(protectionField)} style={{ paddingLeft: theme.eui.paddingSizes.s }}>
|
||||
<EuiFlexGroup direction="row" gutterSize="xs" alignItems="center">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiSwitch
|
||||
id={htmlIdGenerator()()}
|
||||
label={name}
|
||||
data-test-subj={`policy${OPERATING_SYSTEM_TO_TEST_SUBJ[os]}Event_${protectionField}`}
|
||||
checked={selection[protectionField]}
|
||||
onChange={(event) => onValueSelection(protectionField, event.target.checked)}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
{tooltipText && (
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiIconTip position="right" content={tooltipText} />
|
||||
</EuiFlexItem>
|
||||
)}
|
||||
{beta && (
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiBetaBadge label="beta" size="s" />
|
||||
</EuiFlexItem>
|
||||
)}
|
||||
</EuiFlexGroup>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</ConfigForm>
|
||||
);
|
||||
};
|
||||
|
||||
InnerEventsForm.displayName = 'EventsForm';
|
||||
|
||||
export const EventsForm = React.memo(InnerEventsForm) as typeof InnerEventsForm;
|
||||
|
|
|
@ -12,7 +12,11 @@ import { OperatingSystem } from '@kbn/securitysolution-utils';
|
|||
import { policyConfig } from '../../../store/policy_details/selectors';
|
||||
import { setIn } from '../../../models/policy_details_config';
|
||||
import { usePolicyDetailsSelector } from '../../policy_hooks';
|
||||
import { EventFormOption, EventsForm } from '../../components/events_form';
|
||||
import {
|
||||
EventFormOption,
|
||||
EventsForm,
|
||||
SupplementalEventFormOption,
|
||||
} from '../../components/events_form';
|
||||
|
||||
const OPTIONS: ReadonlyArray<EventFormOption<OperatingSystem.LINUX>> = [
|
||||
{
|
||||
|
@ -21,6 +25,15 @@ const OPTIONS: ReadonlyArray<EventFormOption<OperatingSystem.LINUX>> = [
|
|||
}),
|
||||
protectionField: 'file',
|
||||
},
|
||||
{
|
||||
name: i18n.translate(
|
||||
'xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.network',
|
||||
{
|
||||
defaultMessage: 'Network',
|
||||
}
|
||||
),
|
||||
protectionField: 'network',
|
||||
},
|
||||
{
|
||||
name: i18n.translate(
|
||||
'xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.process',
|
||||
|
@ -30,14 +43,25 @@ const OPTIONS: ReadonlyArray<EventFormOption<OperatingSystem.LINUX>> = [
|
|||
),
|
||||
protectionField: 'process',
|
||||
},
|
||||
];
|
||||
|
||||
const SUPPLEMENTAL_OPTIONS: ReadonlyArray<SupplementalEventFormOption<OperatingSystem.LINUX>> = [
|
||||
{
|
||||
name: i18n.translate(
|
||||
'xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.network',
|
||||
'xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.session_data',
|
||||
{
|
||||
defaultMessage: 'Network',
|
||||
defaultMessage: 'Include session data',
|
||||
}
|
||||
),
|
||||
protectionField: 'network',
|
||||
protectionField: 'session_data',
|
||||
tooltipText: i18n.translate(
|
||||
'xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.session_data.tooltip',
|
||||
{
|
||||
defaultMessage:
|
||||
'Capture the extended process event data required for Session View. Session View helps you investigate process, user, and service activity on your Linux infrastructure by displaying session and process execution data organized in a tree according to the Linux process model. NOTE: Capturing extended process events substantially increases data usage.',
|
||||
}
|
||||
),
|
||||
beta: true,
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -50,6 +74,7 @@ export const LinuxEvents = memo(() => {
|
|||
os={OperatingSystem.LINUX}
|
||||
selection={policyDetailsConfig.linux.events}
|
||||
options={OPTIONS}
|
||||
supplementalOptions={SUPPLEMENTAL_OPTIONS}
|
||||
onValueSelection={(value, selected) =>
|
||||
dispatch({
|
||||
type: 'userChangedPolicyConfig',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue