From f5267b9c5bb64c28ef0bd6141a3f482a829faf32 Mon Sep 17 00:00:00 2001 From: Gene Wood Date: Wed, 31 Oct 2018 16:36:31 -0700 Subject: [PATCH 1/3] Move secrets from json file to environment variables sourced from bash file --- .gitignore | 3 ++- cloudy_mozdef/Makefile | 14 +++++++++----- cloudy_mozdef/aws_parameters.example.sh | 1 + cloudy_mozdef/dmake | 1 + 4 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 cloudy_mozdef/aws_parameters.example.sh diff --git a/.gitignore b/.gitignore index d04be998..945d7939 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,5 @@ alerts/generic_alerts /.project /data .vscode -cloudy_mozdef/aws_parameters.json \ No newline at end of file +cloudy_mozdef/aws_parameters.json +cloudy_mozdef/aws_parameters.sh \ No newline at end of file diff --git a/cloudy_mozdef/Makefile b/cloudy_mozdef/Makefile index ff0ae9ee..309a2598 100644 --- a/cloudy_mozdef/Makefile +++ b/cloudy_mozdef/Makefile @@ -8,7 +8,8 @@ STACK_PARAMS := file://aws_parameters.json S3_BUCKET_NAME := mozdef.infosec.allizom.org S3_BUCKET_PATH := cf S3_BUCKET_URI := s3://$(S3_BUCKET_NAME)/$(S3_BUCKET_PATH) -S3_STACK_URI := https://s3-$(AWS_REGION).amazonaws.com/$(S3_BUCKET_NAME)/$(S3_BUCKET_PATH)/mozdef-parent.yml +S3_STACK_URI := https://s3-$(AWS_REGION).amazonaws.com/$(S3_BUCKET_NAME)/$(S3_BUCKET_PATH)/ +# OIDC_CLIENT_SECRET is set in an environment variable by running ". aws_parameters.sh" all: @echo 'Available make targets:' @@ -23,10 +24,12 @@ packer-build: ## Build the base AMI with packer .PHONY: create-stack create-stack: test ## Create everything you need for a fresh new stack! @export AWS_REGION=$(AWS_REGION) - @echo "Make sure you have a param file ($(STACK_PARAMS)) with OIDCClientSecret set." - aws cloudformation create-stack --stack-name $(STACK_NAME) --template-url $(S3_STACK_URI) \ + @echo "Make sure you have an environment variable OIDC_CLIENT_SECRET set." + aws cloudformation create-stack --stack-name $(STACK_NAME) --template-url $(S3_STACK_URI)mozdef-parent.yml \ --capabilities CAPABILITY_IAM \ --parameters $(STACK_PARAMS) \ + --parameters ParameterKey=S3TemplateLocation,ParameterValue=$(S3_STACK_URI) \ + ParameterKey=OIDCClientSecret,ParameterValue=$(OIDC_CLIENT_SECRET) \ --output text .PHONY: create-s3-bucket @@ -37,9 +40,10 @@ create-s3-bucket: .PHONY: updated-nested-stack update-stack: test ## Updates the nested stack on AWS @export AWS_REGION=$(AWS_REGION) - aws cloudformation update-stack --stack-name $(STACK_NAME) --template-url $(S3_STACK_URI) \ + aws cloudformation update-stack --stack-name $(STACK_NAME) --template-url $(S3_STACK_URI)mozdef-parent.yml \ --capabilities CAPABILITY_IAM \ - --parameters $(STACK_PARAMS) \ + --parameters ParameterKey=S3TemplateLocation,ParameterValue=$(S3_STACK_URI) \ + ParameterKey=OIDCClientSecret,ParameterValue=$(OIDC_CLIENT_SECRET) \ --output text # --ignore-checks=E2502 : https://github.com/awslabs/cfn-python-lint/issues/408 diff --git a/cloudy_mozdef/aws_parameters.example.sh b/cloudy_mozdef/aws_parameters.example.sh new file mode 100644 index 00000000..ce6075ae --- /dev/null +++ b/cloudy_mozdef/aws_parameters.example.sh @@ -0,0 +1 @@ +export OIDC_CLIENT_SECRET=secretgoeshere \ No newline at end of file diff --git a/cloudy_mozdef/dmake b/cloudy_mozdef/dmake index 9fe1c779..b0f5567a 100755 --- a/cloudy_mozdef/dmake +++ b/cloudy_mozdef/dmake @@ -37,4 +37,5 @@ exec docker run --rm --name ${CONTAINER_NAME} \ -e "AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}" \ -e "AWS_SESSION_TOKEN=${AWS_SESSION_TOKEN}" \ -e "AWS_DEFAULT_REGION=${AWS_DEFAULT_REGION}" \ + -e "OIDC_CLIENT_SECRET=${OIDC_CLIENT_SECRET}" ${HUB}/${IMG_NAME}:latest make $@ From f047650041c3da4a0ce0d3f266f1011351d607cc Mon Sep 17 00:00:00 2001 From: Gene Wood Date: Wed, 31 Oct 2018 16:37:24 -0700 Subject: [PATCH 2/3] Add ES Service Link IAM Role --- cloudy_mozdef/cloudformation/base-iam.yml | 12 ++++++ .../cloudformation/mozdef-parent.yml | 42 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/cloudy_mozdef/cloudformation/base-iam.yml b/cloudy_mozdef/cloudformation/base-iam.yml index 3ec65e43..19533f1f 100644 --- a/cloudy_mozdef/cloudformation/base-iam.yml +++ b/cloudy_mozdef/cloudformation/base-iam.yml @@ -14,9 +14,15 @@ Parameters: MozDefSQSQueueArn: Type: String Description: The ARN of the SQS queue that receives events destined for MozDef + ESServiceLinkedRoleExists: + Type: String + Description: Does the ES Service Linked Role already exist. true or false + Default: 'true' Conditions: IAMRoleSet: !Not [!Equals [!Ref CloudTrailS3BucketIAMRoleArn, '']] + CreateESServiceLinkedRole: + !Not [!Equals [!Ref ESServiceLinkedRoleExists, 'true']] # Match either True or 'true' but not 'True' Resources: MozDefCloudTrailPolicy: Type: AWS::IAM::ManagedPolicy @@ -116,6 +122,12 @@ Resources: Properties: Roles: - Ref: MozDefIAMRole + ESServiceLinkedIAMRole: + Type: "AWS::IAM::ServiceLinkedRole" + Condition: CreateESServiceLinkedRole + DeletionPolicy: Retain + Properties: + AWSServiceName: es.amazonaws.com Outputs: InstanceProfileArn: Description: The arn of the Instance Profile diff --git a/cloudy_mozdef/cloudformation/mozdef-parent.yml b/cloudy_mozdef/cloudformation/mozdef-parent.yml index 29f73476..9227c840 100644 --- a/cloudy_mozdef/cloudformation/mozdef-parent.yml +++ b/cloudy_mozdef/cloudformation/mozdef-parent.yml @@ -72,6 +72,7 @@ Resources: CloudTrailSQSQueueArn: !GetAtt MozDefCloudTrail.Outputs.CloudTrailSQSQueueArn MozDefSQSQueueArn: !GetAtt MozDefSQS.Outputs.SQSQueueArn # CloudTrailS3BucketIAMRoleArn we leave empty as we will consume CloudTrail logs from our own account + ESServiceLinkedRoleExists: !GetAtt ESServiceLinkedRoleExists.RoleExists Tags: - Key: application Value: mozdef @@ -105,6 +106,7 @@ Resources: TemplateURL: !Join [ '', [ !Ref S3TemplateLocation, mozdef-instance.yml ] ] MozDefES: Type: AWS::CloudFormation::Stack + DependsOn: MozDefIAMRoleAndInstanceProfile Properties: Parameters: SubnetIds: !Join [ ',', !Ref PublicSubnetIds ] @@ -172,6 +174,7 @@ Resources: Effect: Allow Action: - logs:* + - iam:ListRoles Resource: '*' GetArrayLengthLambdaFunction: Type: AWS::Lambda::Function @@ -204,3 +207,42 @@ Resources: Properties: Array: !Ref PublicSubnetIds ServiceToken: !GetAtt GetArrayLengthLambdaFunction.Arn + DoesRoleExistLambdaFunction: + Type: AWS::Lambda::Function + DependsOn: CloudFormationLambdaIAMRole + # This DependsOn shouldn't be needed because the "Role" value is set to + # "!GetAtt CloudFormationLambdaIAMRole.Arn" but without DependsOn the error + # "Template error: IAM role mozdef-aws-nested-CloudFormationLambdaIAMRole-108UCUPESC6WG doesn't exist" + # occurs on stack creation for this Lambda Function resource. The DependsOn + # prevents the error. + Properties: + Code: + ZipFile: | + import cfnresponse + import boto3, secrets, string + def handler(event, context): + paginator = boto3.client('iam').get_paginator('list_roles') + args = {'PathPrefix': event['ResourceProperties']['PathPrefix']} if 'PathPrefix' in event['ResourceProperties'] else {} + iterator = paginator.paginate(**args).search( + "Roles[?RoleName == '%s'][]" % event['ResourceProperties']['RoleName']) + response = {'RoleExists': len([x for x in iterator]) > 0} + physical_id = ''.join( + secrets.choice(string.ascii_uppercase + string.digits) for i in + range(13)) + cfnresponse.send(event, context, cfnresponse.SUCCESS, response, + "DoesRoleExist-%s" % physical_id) + Handler: index.handler + Runtime: python3.6 + Role: !GetAtt CloudFormationLambdaIAMRole.Arn + Tags: + - Key: application + Value: mozdef + - Key: stack + Value: !Ref AWS::StackName + Timeout: 20 + ESServiceLinkedRoleExists: + Type: AWS::CloudFormation::CustomResource + Properties: + RoleName: AWSServiceRoleForAmazonElasticsearchService + PathPrefix: '/aws-service-role/es.amazonaws.com/' + ServiceToken: !GetAtt DoesRoleExistLambdaFunction.Arn \ No newline at end of file From 4cd20a400c9e1220794defe39e10a720af90681a Mon Sep 17 00:00:00 2001 From: "Guillaume Destuynder (:kang)" Date: Thu, 1 Nov 2018 07:15:42 -0700 Subject: [PATCH 3/3] Clarify source instructions Co-Authored-By: gene1wood --- cloudy_mozdef/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloudy_mozdef/Makefile b/cloudy_mozdef/Makefile index 309a2598..cec558b1 100644 --- a/cloudy_mozdef/Makefile +++ b/cloudy_mozdef/Makefile @@ -9,7 +9,7 @@ S3_BUCKET_NAME := mozdef.infosec.allizom.org S3_BUCKET_PATH := cf S3_BUCKET_URI := s3://$(S3_BUCKET_NAME)/$(S3_BUCKET_PATH) S3_STACK_URI := https://s3-$(AWS_REGION).amazonaws.com/$(S3_BUCKET_NAME)/$(S3_BUCKET_PATH)/ -# OIDC_CLIENT_SECRET is set in an environment variable by running ". aws_parameters.sh" +# OIDC_CLIENT_SECRET is set in an environment variable by running "source aws_parameters.sh" all: @echo 'Available make targets:'