Last active
August 9, 2020 12:32
-
-
Save ritesh/5828305923e1a9ab9d8282f7670a7c3a to your computer and use it in GitHub Desktop.
AddPublishingDestinationGdduty
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
AWSTemplateFormatVersion: "2010-09-09" | |
Description: | | |
Publishes findings from a detector in one region to an S3 bucket | |
Parameters: | |
DestinationArn: | |
Type: String | |
Description: ARN of the S3 bucket that you want GuardDuty to push findings to, GuardDuty must have permissions to write to this bucket | |
KmsKeyArn: | |
Type: String | |
Description: The key that GuardDuty should use to encrypt findings | |
Resources: | |
GuardDutyPublishingDestination: | |
Type: AWS::Lambda::Function | |
Properties: | |
Code: | |
ZipFile: | | |
import logging | |
import boto3 | |
import cfnresponse | |
import os | |
import json | |
logger = logging.getLogger() | |
logger.setLevel(logging.INFO) | |
gdduty = boto3.client('guardduty') | |
def lambda_handler(event, context): | |
logger.info('got event {}'.format(event)) | |
responseData = {} | |
detector = None | |
try: | |
resp = gdduty.list_detectors() | |
detector = resp['DetectorIds'][0] | |
if detector is None: | |
logger.error("No detector found, make sure you have a gdduty detector set up in this region") | |
cfnresponse.send(event, context, cfnresponse.FAILED, responseData, "GuardDutyS3Exporter") | |
return | |
except Exception as e: | |
logger.error("Couldn't list detectors %s", e) | |
return | |
if event['RequestType'] in ('Create', 'Update'): | |
try: | |
resp = gdduty.create_publishing_destination(DetectorId=detector, DestinationType='S3', DestinationProperties={'DestinationArn': event['ResourceProperties'].get('DestinationArn'), | |
'KmsKeyArn': event['ResourceProperties'].get('KmsKeyArn')}) | |
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "GuardDutyS3Exporter") | |
return | |
except Exception as e: | |
logger.error("Couldn't create publishing destination %s", e) | |
cfnresponse.send(event, context, cfnresponse.FAILED, responseData, "GuardDutyS3Exporter") | |
return | |
elif event['RequestType'] == 'Delete': | |
try: | |
resp = gdduty.list_publishing_destinations(DetectorId=detector) | |
try: | |
destination = resp['Destinations'][0]['DestinationId'] | |
except KeyError as e: | |
logger.info("Couldn't find destination, maybe it was never created? Returning a successful delete") | |
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "GuardDutyS3Exporter") | |
if destination is None: | |
logger.info("no destination found") | |
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "GuardDutyS3Exporter") | |
return | |
resp = gdduty.delete_publishing_destination(DetectorId=detector, DestinationId=destination) | |
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "GuardDutyS3Exporter") | |
return | |
except Exception as e: | |
logger.error('failed to delete this resource: %s', e) | |
cfnresponse.send(event, context, cfnresponse.FAILED, responseData, "GuardDutyS3Exporter") | |
return | |
logger.info("Neither CREATE nor UPDATE or DELETE, not sure what to do here") | |
cfnresponse.send(event, context, cfnresponse.FAILED, responseData, "GuardDutyS3Exporter") | |
Handler: "index.lambda_handler" | |
Timeout: 30 | |
Role: !GetAtt GuardDutyPublishDestinationRole.Arn | |
Runtime: python3.6 | |
GuardDutyPublishDestinationRole: | |
Type: AWS::IAM::Role | |
Properties: | |
AssumeRolePolicyDocument: | |
Version: 2012-10-17 | |
Statement: | |
- | |
Effect: Allow | |
Principal: | |
Service: | |
- lambda.amazonaws.com | |
Action: | |
- sts:AssumeRole | |
Path: / | |
Policies: | |
- PolicyName: "lambda-logs" | |
PolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
- | |
Effect: Allow | |
Action: | |
- logs:CreateLogGroup | |
- logs:CreateLogStream | |
- logs:PutLogEvents | |
Resource: | |
- "arn:aws:logs:*:*:*" | |
- | |
Effect: Allow | |
Action: | |
- guardduty:DeletePublishingDestination | |
- guardduty:List* | |
- guardduty:CreatePublishingDestination | |
Resource: "*" | |
EnableGuardDutyPublishingDestination: | |
Type: Custom::EnableGuardDutyPublishingDestination | |
Properties: | |
ServiceToken: !GetAtt GuardDutyPublishingDestination.Arn | |
DestinationArn: !Ref DestinationArn | |
KmsKeyArn: !Ref KmsKeyArn |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
AWSTemplateFormatVersion: "2010-09-09" | |
Description: | | |
Set up resources in the security account to receive guardduty findings | |
Parameters: | |
NameOfBucket: | |
Type: String | |
Description: ARN of the S3 bucket that you want GuardDuty to push findings to, this must exist and allow the guardduty service principal to write to it | |
AccessLogsBucket: | |
Type: String | |
Description: Where access logs for the guardduty findings bucket are stored | |
LogPrefix: | |
Type: String | |
Description: Access Logs prefix | |
Default: "/" | |
SplunkIAMGroup: | |
Type: String | |
Description: ARN of IAM group that is allowed to read/write messages from the queue | |
Resources: | |
GDFindingsKey: | |
Type: AWS::KMS::Key | |
Properties: | |
EnableKeyRotation: true | |
KeyPolicy: | |
Version: 2012-10-17 | |
Id: bucket-key-1 | |
Statement: | |
- Sid: Allow GuardDuty to use the key | |
Effect: Allow | |
Principal: | |
Service: guardduty.amazonaws.com | |
Action: 'kms:GenerateDataKey' | |
Resource: '*' | |
- Sid: Enable IAM User Permissions | |
Effect: Allow | |
Principal: | |
AWS: !Join | |
- '' | |
- - 'arn:aws:iam::' | |
- !Ref 'AWS::AccountId' | |
- ':root' | |
Action: 'kms:*' | |
Resource: '*' | |
GDFindingsKeyAlias: | |
Type: AWS::KMS::Alias | |
Properties: | |
AliasName: !Join | |
- '' | |
- - 'alias/s3-' | |
- !Ref NameOfBucket | |
TargetKeyId: | |
Ref: GDFindingsKey | |
GDFindingsBucket: | |
Type: AWS::S3::Bucket | |
Properties: | |
LoggingConfiguration: | |
DestinationBucketName: !Ref AccessLogsBucket | |
LogFilePrefix: !Ref LogPrefix | |
AccessControl: BucketOwnerFullControl | |
NotificationConfiguration: | |
QueueConfigurations: | |
- Event: s3:ObjectCreated:* | |
Queue: !GetAtt SplunkSQSQueue.Arn | |
BucketEncryption: | |
ServerSideEncryptionConfiguration: | |
- ServerSideEncryptionByDefault: | |
KMSMasterKeyID: !Ref GDFindingsKey | |
SSEAlgorithm: aws:kms | |
BucketName: !Ref NameOfBucket | |
BucketPolicy: | |
Type: AWS::S3::BucketPolicy | |
Properties: | |
Bucket: | |
Ref: "GDFindingsBucket" | |
PolicyDocument: | |
Version: '2012-10-17' | |
Id: PutObjPolicy | |
Statement: | |
- Sid: AllowGuardDutyToGetBucketLocation | |
Effect: Allow | |
Principal: | |
Service: guardduty.amazonaws.com | |
Action: s3:GetBucketLocation | |
Resource: !Join | |
- '' | |
- - 'arn:aws:s3:::' | |
- !Ref NameOfBucket | |
- Sid: AllowGuardDutyToPutObjects | |
Effect: Allow | |
Principal: | |
Service: guardduty.amazonaws.com | |
Action: s3:PutObject | |
Resource: !Join | |
- '' | |
- - 'arn:aws:s3:::' | |
- !Ref NameOfBucket | |
- /* | |
- Sid: DenyIncorrectEncryptionHeader | |
Effect: Deny | |
Principal: "*" | |
Action: s3:PutObject | |
Resource: !Join | |
- '' | |
- - 'arn:aws:s3:::' | |
- !Ref GDFindingsBucket | |
- /* | |
Condition: | |
StringNotEquals: | |
s3:x-amz-server-side-encryption: aws:kms | |
- Sid: DenyUnEncryptedObjectUploads | |
Effect: Deny | |
Principal: "*" | |
Action: s3:PutObject | |
Resource: !Join | |
- '' | |
- - 'arn:aws:s3:::' | |
- !Ref GDFindingsBucket | |
- /* | |
Condition: | |
'Null': | |
s3:x-amz-server-side-encryption: true | |
- Sid: DenyPublicReadACL | |
Effect: Deny | |
Principal: "*" | |
Action: | |
- s3:PutObject | |
- s3:PutObjectAcl | |
Resource: !Join | |
- '' | |
- - 'arn:aws:s3:::' | |
- !Ref GDFindingsBucket | |
- /* | |
Condition: | |
StringEquals: | |
s3:x-amz-acl: | |
- public-read | |
- public-read-write | |
- authenticated-read | |
- Sid: DenyPublicReadGrant | |
Effect: Deny | |
Principal: "*" | |
Action: | |
- s3:PutObject | |
- s3:PutObjectAcl | |
Resource: !Join | |
- '' | |
- - 'arn:aws:s3:::' | |
- !Ref GDFindingsBucket | |
- /** | |
Condition: | |
StringLike: | |
s3:x-amz-grant-read: | |
- "*http://acs.amazonaws.com/groups/global/AllUsers*" | |
- "*http://acs.amazonaws.com/groups/global/AuthenticatedUsers*" | |
SplunkSQSQueue: | |
Type: AWS::SQS::Queue | |
SQSQueuePolicy: | |
Type: AWS::SQS::QueuePolicy | |
Properties: | |
Queues: | |
- !Ref SplunkSQSQueue | |
PolicyDocument: | |
Statement: | |
- | |
Action: "SQS:*" | |
Effect: "Allow" | |
Resource: !GetAtt SplunkSQSQueue.Arn | |
Principal: "*" | |
Condition: | |
ArnLike: | |
aws:SourceArn: !Ref SplunkIAMGroup | |
- | |
Action: "SQS:SendMessage" | |
Effect: "Allow" | |
Resource: !GetAtt SplunkSQSQueue.Arn | |
Principal: "*" | |
Condition: | |
StringEquals: | |
aws:SourceAccount: !Sub ${AWS::AccountId} | |
ArnLike: | |
aws:SourceArn: !Join | |
- '' | |
- - 'arn:aws:s3:*:*:' | |
- !Ref NameOfBucket | |
# Outputs: | |
# KmsKey: | |
# Description: The CMK that GuardDuty should use | |
# Value: !GetAtt KMSKeyForGuardDutyFindings.Arn | |
# BucketName: | |
# Description: The bucket that GuardDuty will use | |
# Value: !GetAtt |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment