From 78c6561f27f417bb6b842a52032f7898d3b1472e Mon Sep 17 00:00:00 2001 From: Simon Lukasik Date: Wed, 7 Sep 2022 15:13:05 +0100 Subject: [PATCH] Introduce aws_sqs backend --- config/config.ini | 11 +++++++++ config/defaults.ini | 3 +++ fig/backends/__init__.py | 2 ++ fig/backends/aws_sqs/README.md | 39 ++++++++++++++++++++++++++++++++ fig/backends/aws_sqs/__init__.py | 39 ++++++++++++++++++++++++++++++++ fig/config/__init__.py | 9 +++++++- 6 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 fig/backends/aws_sqs/README.md create mode 100644 fig/backends/aws_sqs/__init__.py diff --git a/config/config.ini b/config/config.ini index 8bb0605..5211825 100644 --- a/config/config.ini +++ b/config/config.ini @@ -48,10 +48,21 @@ [aws] # AWS section is applicable only when AWS backend is enabled in the [main] section. +# AWS Backend publishes Falcon Detection events to AWS Security Hub # Uncomment to provide aws region. Alternatively, use AWS_REGION env variable #region = eu-west-1 +[aws_sqs] +# AWS SQS section is applicable only when AWS backend is enabled in the [main] section. +# AWS SQS Backend publishes raw events to SQS queue + +# Uncomment to provide AWS region. Alternatively, use AWS_REGION env variable +#region = eu-west-1 + +# Uncomment to provide name of AWS SQS. Alternatively, use AWS_SQS env variable +#sqs_queue_name = my-sqs-queue-for-falcon + [workspaceone] # Workspace One section is applicable only when Workspace One backend is enabled in the [main] section. diff --git a/config/defaults.ini b/config/defaults.ini index 2a06cc2..1ee2c02 100644 --- a/config/defaults.ini +++ b/config/defaults.ini @@ -27,6 +27,9 @@ primary_key = [aws] region = + +[aws_sqs] +region = sqs_queue_name = [workspaceone] diff --git a/fig/backends/__init__.py b/fig/backends/__init__.py index f43af7b..54d0545 100644 --- a/fig/backends/__init__.py +++ b/fig/backends/__init__.py @@ -1,5 +1,6 @@ from fig.backends import chronicle from . import aws +from . import aws_sqs from . import azure from . import gcp from . import workspaceone @@ -8,6 +9,7 @@ ALL_BACKENDS = { 'AWS': aws, + 'AWS_SQS': aws_sqs, 'AZURE': azure, 'GCP': gcp, 'WORKSPACEONE': workspaceone, diff --git a/fig/backends/aws_sqs/README.md b/fig/backends/aws_sqs/README.md new file mode 100644 index 0000000..a015049 --- /dev/null +++ b/fig/backends/aws_sqs/README.md @@ -0,0 +1,39 @@ +# AWS SQS Backend + +Integration with AWS SQS -- pushes raw events from CrowdStrike event stream to AWS SQS. Deduplication of the events is done on SQS side. + +### Example Configuration file + +[config/config.ini](https://github.com/CrowdStrike/falcon-integration-gateway/blob/main/config/config.ini) configures Falcon Integration Gateway. Below is a minimal configuration example for AWS SQS backend: +``` +[main] +# Cloud backends that are enabled. The gateway will push events to the cloud providers specified below +backends=AWS_SQS + +[aws_sqs] +# AWS section is applicable only when AWS backend is enabled in the [main] section. + +# Uncomment to provide aws region. Alternatively, use AWS_REGION env variable +#region=eu-west-1 + +# Uncomment to provide name of AWS SQS. Alternatively, use AWS_SQS env variable +#sqs_queue_name = my-sqs-queue-for-falcon +``` + +### Developer Guide + + - Build the image + ``` + docker build . -t falcon-integration-gateway + ``` + - Run the application + ``` + docker run -it --rm \ + -e FALCON_CLIENT_ID="$FALCON_CLIENT_ID" \ + -e FALCON_CLIENT_SECRET="$FALCON_CLIENT_SECRET" \ + -e FALCON_CLOUD_REGION="us-1" \ + -e AWS_SQS=my-queue \ + -e AWS_REGION=mars-west-2 \ + -v ~/.aws:/fig/.aws \ + falcon-integration-gateway:latest + ``` diff --git a/fig/backends/aws_sqs/__init__.py b/fig/backends/aws_sqs/__init__.py new file mode 100644 index 0000000..326bada --- /dev/null +++ b/fig/backends/aws_sqs/__init__.py @@ -0,0 +1,39 @@ +import json +import boto3 +from botocore.exceptions import ClientError +from ...config import config +from ...log import log + + +class Submitter(): + def __init__(self): + aws_region = config.get('aws_sqs', 'region') + sqs_queue_name = config.get('aws_sqs', 'sqs_queue_name') + log.debug("Attempting to connect to AWS (region %s) SQS: %s", aws_region, sqs_queue_name) + try: + aws_client = boto3.resource('sqs', region_name=aws_region) + self.queue = aws_client.get_queue_by_name(QueueName=sqs_queue_name) + except ClientError: # pylint: disable=W0703 + log.exception("Cannot configure AWS SQS Queue: %s in %s", aws_region, sqs_queue_name) + self.queue = None + raise + + def submit(self, event): + self.queue.send_message(MessageBody=json.dumps(event.original_event)) + + +class Runtime(): + RELEVANT_EVENT_TYPES = ['DetectionSummaryEvent'] + + def __init__(self): + log.info("AWS SQS Backend is enabled.") + self.submitter = Submitter() + + def is_relevant(self, falcon_event): + return True + + def process(self, falcon_event): + self.submitter.submit(falcon_event) + + +__all__ = ['Runtime'] diff --git a/fig/config/__init__.py b/fig/config/__init__.py index 18b7fba..d9109da 100644 --- a/fig/config/__init__.py +++ b/fig/config/__init__.py @@ -3,7 +3,7 @@ class FigConfig(configparser.SafeConfigParser): - ALL_BACKENDS = {'AWS', 'AZURE', 'GCP', 'WORKSPACEONE', 'CHRONICLE'} + ALL_BACKENDS = {'AWS', 'AWS_SQS', 'AZURE', 'GCP', 'WORKSPACEONE', 'CHRONICLE'} FALCON_CLOUD_REGIONS = {'us-1', 'us-2', 'eu-1', 'us-gov-1'} ENV_DEFAULTS = [ ['falcon', 'cloud_region', 'FALCON_CLOUD_REGION'], @@ -12,6 +12,8 @@ class FigConfig(configparser.SafeConfigParser): ['azure', 'workspace_id', 'WORKSPACE_ID'], ['azure', 'primary_key', 'PRIMARY_KEY'], ['aws', 'region', 'AWS_REGION'], + ['aws_sqs', 'region', 'AWS_REGION'], + ['aws_sqs', 'sqs_queue_name', 'AWS_SQS'], ['workspaceone', 'token', 'WORKSPACEONE_TOKEN'], ['workspaceone', 'syslog_host', 'SYSLOG_HOST'], ['workspaceone', 'syslog_port', 'SYSLOG_PORT'], @@ -65,6 +67,11 @@ def validate_backends(self): if 'AWS' in self.backends: if len(self.get('aws', 'region')) == 0: raise Exception('Malformed Configuration: expected aws.region to be non-empty') + if 'AWS_SQS' in self.backends: + if len(self.get('aws_sqs', 'region')) == 0: + raise Exception('Malformed Configuration: expected aws_sqs.region to be non-empty') + if len(self.get('aws_sqs', 'sqs_queue_name')) == 0: + raise Exception('Malformed Configuration: expected aws_sqs.sqs_queue_name to be non-empty') if 'WORKSPACEONE' in self.backends: if len(self.get('workspaceone', 'token')) == 0: raise Exception('Malformed Configuration: expected workspaceone.token to be non-empty')