Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Security Solution] Adding tests for dns pipeline in the endpoint package #79177

Merged
Original file line number Diff line number Diff line change
Expand Up @@ -718,7 +718,10 @@ export type SafeEndpointEvent = Partial<{
forwarded_ip: ECSField<string>;
}>;
dns: Partial<{
question: Partial<{ name: ECSField<string> }>;
question: Partial<{
name: ECSField<string>;
type: ECSField<string>;
}>;
}>;
process: Partial<{
entity_id: ECSField<string>;
Expand Down
Binary file not shown.
2 changes: 1 addition & 1 deletion x-pack/test/ingest_manager_api_integration/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { defineDockerServersConfig } from '@kbn/test';
// Docker image to use for Ingest Manager API integration tests.
// This hash comes from the commit hash here: https://github.com/elastic/package-storage/commit
export const dockerImage =
'docker.elastic.co/package-registry/distribution:a5132271ad37209d6978018bfe6e224546d719a8';
'docker.elastic.co/package-registry/distribution:fb58d670bafbac7e9e28baf6d6f99ba65cead548';

export default async function ({ readConfigFile }: FtrConfigProviderContext) {
const xPackAPITestsConfig = await readConfigFile(require.resolve('../api_integration/config.ts'));
Expand Down
74 changes: 74 additions & 0 deletions x-pack/test/security_solution_endpoint_api_int/apis/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@
*/
import expect from '@kbn/expect';
import { SearchResponse } from 'elasticsearch';
import {
ResolverPaginatedEvents,
SafeEndpointEvent,
} from '../../../plugins/security_solution/common/endpoint/types';
import { eventsIndexPattern } from '../../../plugins/security_solution/common/endpoint/constants';
import {
EndpointDocGenerator,
Event,
} from '../../../plugins/security_solution/common/endpoint/generate_data';
import { FtrProviderContext } from '../ftr_provider_context';
import { InsertedEvents, processEventsIndex } from '../services/resolver';
import { deleteEventsStream } from './data_stream_helper';

interface EventIngested {
event: {
Expand All @@ -35,6 +40,8 @@ interface NetworkEvent {
const networkIndex = 'logs-endpoint.events.network-default';

export default function ({ getService }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const supertest = getService('supertest');
const resolver = getService('resolverGenerator');
const es = getService('es');
const generator = new EndpointDocGenerator('data');
Expand All @@ -59,6 +66,72 @@ export default function ({ getService }: FtrProviderContext) {
};

describe('Endpoint package', () => {
describe('network processors', () => {
let networkIndexData: InsertedEvents;

after(async () => {
await resolver.deleteData(networkIndexData);
});

it('handles events without the `network.protocol` field being defined', async () => {
const eventWithoutNetworkObject = generator.generateEvent();
// ensure that `network.protocol` does not exist in the event to test that the pipeline handles those type of events
delete eventWithoutNetworkObject.network;

// this call will fail if the pipeline fails
networkIndexData = await resolver.insertEvents([eventWithoutNetworkObject], networkIndex);
const eventWithBothIPs = await searchForID<SafeEndpointEvent>(
networkIndexData.eventsInfo[0]._id
);

// ensure that the event was inserted into ES
expect(eventWithBothIPs.body.hits.hits[0]._source.event?.id).to.be(
eventWithoutNetworkObject.event?.id
);
});
});

describe('dns processor', () => {
before(async () => {
await esArchiver.load('endpoint/pipeline/dns', { useCreate: true });
});

after(async () => {
await deleteEventsStream(getService);
});

it('does not set dns.question.type if it is already populated', async () => {
// this id comes from the es archive file endpoint/pipeline/dns
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❔ Do you need to change it if something in that file changes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah we'd have to change the event.id we look for here if the archive changed. I don't expect to have to update that archive very much though. The pipeline shouldn't change that often.

const id = 'LrLSOVHVsFY94TAi++++++eF';
const { body }: { body: ResolverPaginatedEvents } = await supertest
.post(`/api/endpoint/resolver/events?limit=1`)
.set('kbn-xsrf', 'xxx')
.send({
filter: `event.id:"${id}"`,
})
.expect(200);
expect(body.events.length).to.eql(1);
expect((body.events[0] as SafeEndpointEvent).dns?.question?.name).to.eql('www.google.com');
expect((body.events[0] as SafeEndpointEvent).dns?.question?.type).to.eql('INVALID_VALUE');
});

it('sets dns.question.type if it is not populated', async () => {
// this id comes from the es archive file endpoint/pipeline/dns
const id = 'LrLSOVHVsFY94TAi++++++eP';
const { body }: { body: ResolverPaginatedEvents } = await supertest
.post(`/api/endpoint/resolver/events?limit=1`)
.set('kbn-xsrf', 'xxx')
.send({
filter: `event.id:"${id}"`,
})
.expect(200);
expect(body.events.length).to.eql(1);
expect((body.events[0] as SafeEndpointEvent).dns?.question?.name).to.eql('www.aol.com');
// This value is parsed out of the message field in the event. type 28 = AAAA
expect((body.events[0] as SafeEndpointEvent).dns?.question?.type).to.eql('AAAA');
});
});

describe('ingested processor', () => {
let event: Event;
let genData: InsertedEvents;
Expand Down Expand Up @@ -92,6 +165,7 @@ export default function ({ getService }: FtrProviderContext) {
const eventWithSourceOnly = generator.generateEvent({
extensions: { source: { ip: '8.8.8.8' } },
});

networkIndexData = await resolver.insertEvents(
[eventWithBothIPs, eventWithSourceOnly],
networkIndex
Expand Down