diff --git a/.gitignore b/.gitignore index f294b2a..6c38796 100644 --- a/.gitignore +++ b/.gitignore @@ -161,6 +161,16 @@ cython_debug/ # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ +# JetBrains IDE +.idea/ + +.DS_Store + +.taskcat/ +taskcat_outputs/ +*.zip +======= + .DS_Store # Taskcat files @@ -172,4 +182,4 @@ taskcat_outputs aggregated_results.txt # Package files -lambda.zip \ No newline at end of file +lambda.zip diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..82bae0a --- /dev/null +++ b/.gitmodules @@ -0,0 +1,12 @@ +[submodule "submodules/cfn-abi-aws-securityhub"] + path = submodules/cfn-abi-aws-securityhub + url = https://github.com/aws-ia/cfn-abi-aws-securityhub.git +[submodule "submodules/lacework-control-tower-cfn"] + path = submodules/lacework-control-tower-cfn + url = https://github.com/lacework-alliances/lacework-control-tower-cfn.git +[submodule "submodules/cfn-abi-amazon-guardduty"] + path = submodules/cfn-abi-amazon-guardduty + url = https://github.com/aws-ia/cfn-abi-amazon-guardduty.git +[submodule "submodules/--force"] + path = submodules/--force + url = https://github.com/aws-ia/cfn-abi-amazon-guardduty.git diff --git a/.taskcat.yml b/.taskcat.yml index 1d06399..fb810cb 100644 --- a/.taskcat.yml +++ b/.taskcat.yml @@ -1,33 +1,19 @@ project: - name: update-me-to-project-repo-name - owner: quickstart@amazon.com - package_lambda: false + name: cfn-abi-lacework-polygraph + owner: jeff.fry@lacework.net + package_lambda: true + s3_regional_buckets: false regions: - - ap-northeast-1 - - ap-northeast-2 - - ap-southeast-1 - - ap-southeast-2 - - eu-central-1 - - eu-west-1 - - sa-east-1 - us-east-1 - - us-west-1 - - us-west-2 tests: - sample: - parameters: - Param1: 'Inputs to Stack' - # Examples: of other taskcat dynamic input parameters for more into see http://taskcat.io - # - # AvailabilityZones: $[taskcat_genaz_3] - # ByteValue: 1 - # PasswordA: $[taskcat_genpass_8A] - # PasswordB: $[taskcat_genpass_32S] - # RandomNumber: $[taskcat_random-numbers] - # RandomString: $[taskcat_random-string] - # StackName: TestStack - # UUID: $[taskcat_genuuid] - # + cfn-abi-lacework-polygraph-multi-org-multi-sub-mapping: regions: - - us-east-1 - template: templates/sample-workload.template.yaml + - us-east-1 # Control Tower Home region for Pilot + template: templates/cfn-abi-lacework-polygraph.template.yaml + parameters: + pSRAStagingS3KeyPrefix: $[taskcat_project_name] + pSRASourceS3BucketName: $[taskcat_autobucket] + pSRAS3BucketRegion: $[taskcat_current_region] + LaceworkURL: laceworkalliances.lacework.net + LaceworkAccessKeyID: $[taskcat_ssm_/lacework/LaceworkAccessKeyID] + LaceworkSecretKey: $[taskcat_ssm_/lacework/LaceworkSecretKey] \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..c096b38 --- /dev/null +++ b/README.md @@ -0,0 +1,331 @@ +## Overview + +With the Lacework AWS Built-in Package, enrolling a new AWS account ensures security best practices and monitoring are +automatically applied consistently across your organization. Account administrators can automatically add Lacework's +security auditing and monitoring to AWS accounts seamlessly. All the required Lacework and AWS account configurations +that allow access to AWS configuration and CloudTrail logs are managed for you by Lacework. Additionally, automatic +enablement of Amazon GuardDuty and AWS Security Hub means that your organization can benefit from enriched security +alerts from Lacework and AWS. This leads to higher fidelity alerts and quicker time to resolution due to additional +context provided by AWS Security Hub and Amazon GuardDuty. + +![AWS Built-in Overview](https://lacework-alliances.s3.us-west-2.amazonaws.com/collateral/aws-built-in-overview.png) + + +## Prerequisites + +* **Enable AWS Control Tower** - Follow these instructions to [enable AWS Control Tower](https://docs.aws.amazon.com/controltower/latest/userguide/getting-started-with-control-tower.html) for your organization. +* Administrator privileges in the AWS Control Tower management account. +* A Lacework Cloud Security Platform SaaS account. + +## Lacework AWS Built-in Package Architecture + +CloudFormation is used to deploy the Lacework AWS Built-in Package. The CloudFormation template will create the following resources: +* A cross-account IAM role that will allow Lacework to query AWS APIs. +* An EventBridge rule for AWS Control Tower account creation events that will trigger a Lambda function. +* Lambda functions that perform initial setup and add accounts to Lacework. +* An SQS queue that will receive the AWS Control Tower centralized CloudTrail S3 bucket notifications. +* A cross-account IAM role that will allow Lacework to access the SQS queue in order to receive centralized CloudTrail S3 bucket updates. +* An EventBridge rule that will forward AWS Security Hub findings to an SQS queue. +* An SQS queue that will receive the AWS Security Hub findings. +* A cross-account IAM role that will allow Lacework to access the SQS queue in order to receive the AWS Security Hub findings. + +![AWS Built-in Architecture](https://lacework-alliances.s3.us-west-2.amazonaws.com/collateral/aws-built-in-aws-arch.png) + +## Deployment Scenarios + +### 1. Without Lacework Organization +If the [Lacework Organization](https://docs.lacework.com/console/organization-overview) feature is not enabled, all AWS accounts go under the main Lacework account by default. Leave the **Single Sub-Account Configuration** and **Organization Configuration** sections blank in the CloudFormation stack parameters. + +### 2. Single Lacework Sub-Account with Lacework Organization + +If the [Lacework Organization](https://docs.lacework.com/console/organization-overview) feature is enabled, you can specify a Lacework Sub-Account for which all AWS accounts are added. This is specified in the **Single Sub-Account Configuration** section in the **Lacework Sub-Account Name** field (see below) in the CloudFormation stack parameters. + +### 3. AWS Organizational Units (OUs) to Lacework Sub-Account Mapping with Lacework Organization + +- You must have the Lacework Organization feature enabled. +- When naming the OUs, ensure to not include spaces in the names (hyphens are allowed).
+ - Dev Infra :x:
+ - Dev-Infra :white_check_mark: + +## Configure the Lacework AWS Built-in Package + +### 1. Generate a Lacework API Access Key + +1. In your console, go to **Settings > Configuration > API keys**. +2. Click on the **+ Add New** button in the upper right to create a new API key. +3. Provide a **name** and **description** and click Save. +4. Click the download button to download the API keys file. +5. Copy the **keyId** and **secret** from this file. + +### 2. Log in to your AWS Control Tower Management Account + +1. Log in to AWS Control Tower management account. +2. Select the AWS region where your AWS Control Tower is deployed. + +### 3. Deploy the Lacework AWS Built-in Package with CloudFormation + +1. Click the following **Launch Stack** button to go to your CloudFormation console and launch the AWS Control Integration template. + + [![Launch](https://user-images.githubusercontent.com/6440106/153987820-e1f32423-1e69-416d-8bca-2ee3a1e85df1.png)](https://console.aws.amazon.com/cloudformation/home?#/stacks/create/review?templateURL=https://lacework-alliances.s3.us-west-2.amazonaws.com/lacework-control-tower-cfn/templates/control-tower-integration.template.yml) + + For most deployments, you need only Basic Configuration parameters. +2. Specify the following Basic Configuration parameters: + * Enter a **Stack name** for the stack. + * Enter **Your Lacework URL**. + * Enter your **Lacework Access Key ID** and **Secret Key** that you copied from your previous API keys file. + * For **Capability Type**, the recommendation is to use **CloudTrail+Config** for the best capabilities. + * Choose whether you want to **Monitor Existing Accounts**. This sets up monitoring of ACTIVE existing AWS accounts. + * Enter the name of your **Existing AWS Control Tower CloudTrail Name**. + * If your CloudTrail S3 logs are encrypted, specify the **KMS Key Identifier ARN**. Ensure that you update the KMS key policy to allow access to the Log account cross-account role used by Lacework. Add the following to the key policy. + + ```text + "Sid": "Allow Lacework to decrypt logs", + "Effect": "Allow", + "Principal": { + "AWS": [ + "arn:aws:iam:::role/-laceworkcwssarole" + ] + }, + "Action": [ + "kms:Decrypt" + ], + "Resource": "*" + ``` + + * Update the Control Tower **Log Account Name** and **Audit Account Name** if necessary. + * If using AWS organization units to Lacework Sub-Account mapping, specify a comma-separated lists of organization names in the **Organization Configuration** section in the **AWS Organizations to Lacework Sub-Account Names** field. AWS accounts are added to the appropriate Lacework Sub-Accounts based on this AWS OU-to-Lacework Sub-Account name mapping. AWS OU names and Lacework Sub-Account names must match. AWS accounts not in the specified organization units are not added to Lacework. + * If using a single Lacework sub-account for all AWS accounts, specify a Lacework Sub-Account for which all AWS accounts will be added. This is specified in the **Single Sub-Account Configuration** section in the **Lacework Sub-Account Name** field. +3. Click **Next** through to your stack **Review**. +4. Accept the AWS CloudFormation terms and click **Create stack**. + +### 4. CloudFormation Progress + +1. Monitor the progress of the CloudFormation deployment. It takes several minutes for the stack to create the resources that enable the Lacework AWS Built-in Package. +2. When successfully completed, the stack shows `CREATE_COMPLETE`. + +### 5. Validate the Solution + +1. Log in to your Lacework Cloud Security Platform console. +2. Go to **Settings > Integration > Cloud Accounts**. +3. You should see a list of AWS accounts that are now being monitored by Lacework. The **Cloud Account** column values correspond to the AWS Account IDs. + +Once the Control Tower CloudFormation deployment is competed, you need to setup an Setup of Organization AWS CloudTrail Integration and upload a mapping file. Any AWS accounts that are not included in the mapping will have your CloudTrail logs sent to the default Lacework Sub-Account. + +## Remove the Lacework AWS Built-in Package + +To remove the Lacework's AWS Built-in Pacakge, simply delete the main stack. All CloudFormation stacksets, stack instances, and Lambda functions will be deleted. + +Lacework will no longer monitor your AWS cloud environment. + +## Permissions + +The following IAM permissions are required to allow Lacework to query AWS APIs, read CloudTrail events and receive AWS Security Hub findings. These are provisioned +as part of the CloudFormation deployment. + +### Member Account SecurityAudit Cross-Account IAM Role + +```yaml + LaceworkCrossAccountAccessRole: + Type: 'AWS::IAM::Role' + Properties: + RoleName: !Join + - '-' + - - !Ref ResourceNamePrefix + - laceworkcwsrole-sa + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Action: 'sts:AssumeRole' + Effect: Allow + Principal: + AWS: !Join + - '' + - - 'arn:aws:iam::' + - !Ref LaceworkAWSAccountId + - ':root' + Condition: + StringEquals: + 'sts:ExternalId': !Ref ExternalID + ManagedPolicyArns: + - 'arn:aws:iam::aws:policy/SecurityAudit' +``` + +### Centralized CloudTrail Cross-Account IAM Role + +```yaml + LaceworkCWSSACrossAccountAccessRole: + Type: 'AWS::IAM::Role' + Properties: + RoleName: !Join + - '' + - - !Ref ResourceNamePrefix + - '-laceworkcwssarole' + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Action: 'sts:AssumeRole' + Effect: Allow + Principal: + AWS: !Join + - '' + - - 'arn:aws:iam::' + - !Ref LaceworkAWSAccountId + - ':root' + Condition: + StringEquals: + 'sts:ExternalId': !Ref ExternalID + ManagedPolicyArns: + - 'arn:aws:iam::aws:policy/SecurityAudit' + LaceworkCWSPolicy: + Type: 'AWS::IAM::Policy' + Properties: + PolicyName: LaceworkCWSPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Sid: ConsumeNotifications + Action: + - 'sqs:GetQueueAttributes' + - 'sqs:GetQueueUrl' + - 'sqs:DeleteMessage' + - 'sqs:ReceiveMessage' + Effect: Allow + Resource: !Ref SqsQueueArn + - Sid: ListLogFiles + Action: + - 's3:ListBucket' + Effect: Allow + Resource: !Join ['',["arn:aws:s3:::", !Ref ExistingTrailBucketName, "/*AWSLogs/*" ]] + Condition: + StringLike: + 's3:prefix': + - '*AWSLogs/' + - Sid: ReadLogFiles + Action: + - 's3:Get*' + Effect: Allow + Resource: !Join ['',["arn:aws:s3:::", !Ref ExistingTrailBucketName, "/*AWSLogs/*" ]] + - Sid: GetAccountAlias + Action: + - 'iam:ListAccountAliases' + Effect: Allow + Resource: '*' + - Sid: Debug + Action: + - 'cloudtrail:DescribeTrails' + - 'cloudtrail:GetTrailTopics' + - 'cloudtrail:GetTrailStatus' + - 'cloudtrail:ListPublicKeys' + - 's3:GetBucketAcl' + - 's3:GetBucketPolicy' + - 's3:ListAllMyBuckets' + - 's3:GetBucketLocation' + - 's3:GetBucketLogging' + - 'sns:GetSubscriptionAttributes' + - 'sns:GetTopicAttributes' + - 'sns:ListSubscriptions' + - 'sns:ListSubscriptionsByTopic' + - 'sns:ListTopics' + Effect: Allow + Resource: '*' + Roles: + - !Ref LaceworkCWSSACrossAccountAccessRole +``` + +### Security Hub Cross-Account IAM Role + +```yaml + LaceworkSecHubCrossAccountAccessRole: + Type: AWS::IAM::Role + Properties: + RoleName: !Sub "${ResourceNamePrefix}-Lacework-Sec-Hub-Role" + AssumeRolePolicyDocument: + Version: "2012-10-17" + Statement: + - Effect: Allow + Action: + - sts:AssumeRole + Principal: + AWS: !Join + - '' + - - 'arn:aws:iam::' + - !Ref LaceworkAWSAccountId + - ':root' + Condition: + StringEquals: + sts:ExternalId: + !Ref ExternalID + Path: "/" + Policies: + - PolicyName: LaceworkSecHubCrossAccountAccessRolePolicy + PolicyDocument: + Version: "2012-10-17" + Statement: + - Effect: Allow + Action: + - sqs:ListQueues + - sqs:GetQueueAttributes + - sqs:GetQueueUrl + - sqs:DeleteMessage + - sqs:ReceiveMessage + Resource: + - !GetAtt LaceworkSecHubQueue.Arn +``` + +## Troubleshooting + +The following sections provide guidance for resolving issues with deploying the Lacework AWS Built-in Package. + +### Common Issues + +* Ensure the **Existing AWS Control Tower CloudTrail Name** is correct. You can verify this on your AWS CloudTrail Dashboard. +* Ensure that your **Log Archive** and **Audit** account names are correct and these accounts are `ACTIVE`. +* If you are using the Lacework Organization feature to manage your accounts, specify the correct Sub-Account name, API key ID, and secret key. +* If Lacework returns an S3 access error for the CloudTrail account and a KMS key is used, ensure you update the KMS key policy to allow access to the Log account cross-account role used by Lacework. + + ```text + "Sid": "Allow Lacework to decrypt logs", + "Effect": "Allow", + "Principal": { + "AWS": [ + "arn:aws:iam:::role/-laceworkcwssarole" + ] + }, + "Action": [ + "kms:Decrypt" + ], + "Resource": "*" + ``` + +### Events and Logs + +#### CloudFormation Events + +You can monitor the CloudFormation events for the Lacework's AWS Built-in stack. Events may reveal issues with resource creation. The Lacework's AWS Built-in stack launches a main stack and three stacksets: + +**Main Deployment Stack:** +* **control-tower-integration.template.yml** - Main stack that deploys all resources: IAM roles, access token credentials, IAM roles, SQS queues, Lambda functions and the stacksets below. + +**Centralized CloudTrail Cloud Account in Lacework:** (Applied once during initial deployment) +* **lacework-aws-ct-audit.template.yml** -> **Lacework-Control-Tower-CloudTrail-Audit-Account-**_Lacework account_ - Creates a stack instance in the Audit account. +* **lacework-aws-ct-log.template.yml** -> **Lacework-Control-Tower-CloudTrail-Log-Account-**_Lacework account_ - Creates a stack instance in the Log account. + +**Config Cloud Account in Lacework:** (Applied for each AWS account) +* **lacework-aws-cfg-member.template.yml** -> **Lacework-Control-Tower-Config-Member-**_Lacework account_ - Creates a stack instance in each AWS account. + +Examining these stacksets for operation results, stack instance results and parameters may also provide debug information. + +#### Lambda Function CloudWatch Logs + +Two main Lambda functions are used to manage accounts. LaceworkSetupFunction manages the initial deployment of the integration. LaceworkAccountFunction manages setting up existing and new accounts. Both Lambda functions provide extensive debug messages that can be seen in their respective CloudWatch log streams. + +## FAQs + +
+Can I individually choose which accounts are added to Lacework within AWS Control Tower?Yes, our solution supports mapping of AWS organization names (aka AWS OU names) to Lacework Sub-Accounts. AWS accounts for our Config type will be added to Lacework Suub-Accounts based on the provided comma separated list of AWS organization names. These AWS organization names must match the Sub-Account names on our side. Any AWS accounts that are not included in the mapping will have your CloudTrail logs sent to the default Lacework Sub-Account. + +
+ +
+How does Lacework integrate with AWS Control Tower's CloudTrail?Our solution simply adds the centralized CloudTrail in the Log Archive account to Lacework. It does not do any mapping. Separately and manually, the customer may use the CloudTrail JSON mapping. Once the Control Tower CloudFormation deployment is competed, you need to setup an Setup of Organization AWS CloudTrail Integration and upload a mapping file. Any AWS accounts that are not included in the mapping will have your CloudTrail logs sent to the default Lacework Sub-Account. +
diff --git a/lambda.zip b/lambda.zip new file mode 100644 index 0000000..b61cdeb Binary files /dev/null and b/lambda.zip differ diff --git a/scripts/cleanup_config.json b/scripts/cleanup_config.json index add0957..6b44eab 100644 --- a/scripts/cleanup_config.json +++ b/scripts/cleanup_config.json @@ -1,23 +1,52 @@ [ + { + "Type" : "S3_BUCKET", + "Filter" : "sra-guardduty-org-delivery-", + "Account" : "log_account" + }, + { + "Type" : "S3_BUCKET", + "Filter" : "cfn-abi-amazon-guardduty-" + }, + { + "Type" : "SSM_PARAMETER", + "Filter" : "/sra/gd/" + }, { "Type": "STACK", - "Filter" : "replace-with-stack-name-prefix-to-be-cleaned" + "Filter" : "tCaT-enable-securityhub-ssm-" + }, + { + "Type" : "STACK", + "Filter": "tCaT-stage-sh-content-local-" + }, + { + "Type" : "STACK", + "Filter": "tCaT-enable-securityhub-in-org-ssm-" + }, + { + "Type" : "S3_BUCKET", + "Filter": "tcat-cfn-abi-aws-securityhub-" }, { "Type" : "S3_BUCKET", - "Filter": "replace-with-s3-bucket-prefix-to-be-cleaned" + "Filter": "sra-gd-staging-" }, { "Type" : "S3_BUCKET", - "Filter": "replace-with-s3-bucket-prefix-to-be-cleaned", - "Account": "provide-your-account-name" + "Filter" : "sra-sh-stage-" + }, + { + "Type" : "S3_BUCKET", + "Filter" : "sra-sh-staging-" }, { "Type" : "SSM_PARAMETER", - "Filter" : "/path/to/parameter-prefix-to-delete" + "Filter" : "/sra/sh/" }, { - "Type" : "LOG_GROUP", - "Filter" : "path/to/log-group-prefix-to-delete" + "Type" : "S3_BUCKET", + "Filter" : "cfn-abi-lacework-polygraph" } ] + diff --git a/submodules/cfn-abi-amazon-guardduty b/submodules/cfn-abi-amazon-guardduty new file mode 160000 index 0000000..82a444d --- /dev/null +++ b/submodules/cfn-abi-amazon-guardduty @@ -0,0 +1 @@ +Subproject commit 82a444dc98e3cf254fdd26001ed0ab17d291d86a diff --git a/submodules/cfn-abi-aws-securityhub b/submodules/cfn-abi-aws-securityhub new file mode 160000 index 0000000..0f698a7 --- /dev/null +++ b/submodules/cfn-abi-aws-securityhub @@ -0,0 +1 @@ +Subproject commit 0f698a7211c560841df6bca36093d8a6b5d4f242 diff --git a/submodules/lacework-control-tower-cfn b/submodules/lacework-control-tower-cfn new file mode 160000 index 0000000..f3c4cc6 --- /dev/null +++ b/submodules/lacework-control-tower-cfn @@ -0,0 +1 @@ +Subproject commit f3c4cc6e62406d41f8d4addb752515ff96417254 diff --git a/templates/cfn-abi-lacework-polygraph.template.yaml b/templates/cfn-abi-lacework-polygraph.template.yaml new file mode 100644 index 0000000..3b319de --- /dev/null +++ b/templates/cfn-abi-lacework-polygraph.template.yaml @@ -0,0 +1,398 @@ +AWSTemplateFormatVersion: 2010-09-09 +Description: "AWS Built-in package with Lacework. Bundled AWS Control Tower, Amazon GuardDuty, AWS Security Hub and Lacework." +Metadata: + AWS::CloudFormation::Interface: + ParameterGroups: + - Label: + default: General Properties + Parameters: + - pSRASolutionVersion + - pSRASourceS3BucketName + - pSRAStagingS3KeyPrefix + - pSRAS3BucketRegion + - pSRAAlarmEmail + - Label: + default: "Lacework Configuration Properties" + Parameters: + - LaceworkURL + - LaceworkAccessKeyID + - LaceworkSecretKey + - CapabilityType + - ExistingAccounts + - ExistingCloudTrail + - KMSKeyIdentifierARN + - LogAccountName + - AuditAccountName + - Label: + default: "Organization Configuration (Optional)" + Parameters: + - LaceworkOrgSubAccountNames + - Label: + default: "Single Sub-Account Configuration (Optional)" + Parameters: + - LaceworkSubAccountName + - Label: + default: Security Hub Configuration Properties + Parameters: + - pDisableSecurityHub + - pEnableSecurityBestPracticesStandard + - pEnableCISStandard + - pCISStandardVersion + - pEnablePCIStandard + - pRegionLinkingMode + - pControlTowerRegionsOnly + - pEnabledRegions + - Label: + default: GuardDuty Configuration Properties + Parameters: + - pAutoEnableS3Logs + - pAutoEnableK8sLogs + - pAutoEnableMalwareProtection + - Label: + default: General Lambda Function Properties + Parameters: + - pCreateLambdaLogGroup + - pLambdaLogGroupRetention + - pLambdaLogGroupKmsKey + - pLambdaLogLevel + + - Label: + default: EventBridge Rule Properties + Parameters: + - pComplianceFrequency + + ParameterLabels: + # General Properties + pSRASolutionVersion: + default: SRA Solution Version + pSRASourceS3BucketName: + default: SRA Source S3 Location + pSRAStagingS3KeyPrefix: + default: SRA Source Key + pSRAS3BucketRegion: + default: SRA Bucket Region + pSRAAlarmEmail: + default: (Optional) SRA Alarm Email + # Lacework Configuration Properties + LaceworkURL: + default: Your Lacework URL + LaceworkOrgSubAccountNames: + default: AWS Organizations to Lacework Sub-Account Names + LaceworkSubAccountName: + default: Lacework Sub-Account Name + LaceworkAccessKeyID: + default: Lacework Access Key ID + LaceworkSecretKey: + default: Lacework Secret Key + CapabilityType: + default: Capability Type + ExistingAccounts: + default: Monitor Existing Accounts + ExistingCloudTrail: + default: Existing AWS Control Tower CloudTrail Name + LogAccountName: + default: Log Account Name + AuditAccountName: + default: Audit Account Name + KMSKeyIdentifierARN: + default: KMS Key Identifier ARN for CloudTrail S3 Logs Decrypt + # Security Hub Configuration Properties + pDisableSecurityHub: + default: Disable Security Hub + pEnableSecurityBestPracticesStandard: + default: Enable AWS Foundational Security Best Practices Standard + pEnableCISStandard: + default: Enable CIS Standard + pCISStandardVersion: + default: CIS Standard Version + pEnablePCIStandard: + default: Enable PCI Standard + pRegionLinkingMode: + default: Region Linking Mode + pControlTowerRegionsOnly: + default: Control Tower Regions Only + pEnabledRegions: + default: (Optional) Enabled Regions + # GuardDuty Configuration Properties + pAutoEnableS3Logs: + default: Auto Enable S3 Logs + pAutoEnableK8sLogs: + default: Auto Enable kubernetes Logs + pAutoEnableMalwareProtection: + default: Auto Enable malware protection + # General Lambda Function Properties + pCreateLambdaLogGroup: + default: Create Lambda Log Group + pLambdaLogGroupRetention: + default: Lambda Log Group Retention + pLambdaLogGroupKmsKey: + default: (Optional) Lambda Logs KMS Key + pLambdaLogLevel: + default: Lambda Log Level + # EventBridge Rule Properties + pComplianceFrequency: + default: Frequency to Check for Organizational Compliance +Parameters: + # General Properties + pSRASolutionVersion: + AllowedValues: [ v1.5 ] + Default: v1.5 + Description: The SRA solution version. Used to trigger updates on the nested StackSets. + Type: String + pSRASourceS3BucketName: + AllowedPattern: ^[0-9a-zA-Z]+([0-9a-zA-Z-]*[0-9a-zA-Z])*$ + Type: String + Default: aws-abi-pilot + pSRAStagingS3KeyPrefix: + AllowedPattern: ^[0-9a-zA-Z]+([0-9a-zA-Z-]*[0-9a-zA-Z])*$ + Type: String + Default: cfn-abi-lacework-polygraph + pSRAS3BucketRegion: + AllowedPattern: ^[a-z][a-z]-[a-z]*-[0-9]*$ + Type: String + Default: us-east-1 + pSRAAlarmEmail: + AllowedPattern: '^$|^([a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+)$' + ConstraintDescription: Must be a valid email address. + Default: '' + Description: (Optional) Email address for receiving SRA alarms + Type: String + # lacework parameters + LaceworkURL: + Type: String + Description: "Enter your Lacework URL. ie. account.lacework.net." + MinLength: '1' + AllowedPattern: '(.+?)\.lacework\.net' + ConstraintDescription: "Invalid Lacework URL." + LaceworkOrgSubAccountNames: + Type: String + Description: "Use for AWS organizations to Lacework sub-accounts mapping. Provide a commas-separated list. Leave blank otherwise. If used, ensure that the Lacework credentials are for the Organization Admin." + AllowedPattern: '^$|^[a-zA-Z0-9.,]+(?:-[a-zA-Z0-9.,]+)*$' + ConstraintDescription: "Invalid list entered. The sub-account name may contain alphanumeric characters and dashes only." + Default: '' + LaceworkSubAccountName: + Type: String + Description: "Use for a single sub-account use only. Leave blank otherwise. If used, ensure that the Lacework credentials are for the Sub-Account." + AllowedPattern: '^$|^[a-zA-Z0-9.]+(?:-[a-zA-Z0-9.]+)*$' + ConstraintDescription: "Invalid Lacework account name entered. The account name may contain alphanumeric characters and dashes only." + Default: '' + LaceworkAccessKeyID: + Type: String + MinLength: '1' + AllowedPattern: '^[-a-zA-Z0-9_]*$' + ConstraintDescription: "The Lacework API Access Key ID contains alphanumeric characters and symbols only." + Description: "Enter the Lacework API Secret Key ID. See https://support.lacework.com/hc/en-us/articles/360011403853-Generate-API-Access-Keys-and-Tokens." + LaceworkSecretKey: + Type: String + NoEcho: true + MinLength: '1' + AllowedPattern: '^[a-zA-Z0-9_]*$' + ConstraintDescription: "The Lacework API Secret Key contains alphanumeric characters and symbols only." + Description: "Enter the Lacework API Secret Key. See https://support.lacework.com/hc/en-us/articles/360011403853-Generate-API-Access-Keys-and-Tokens." + CapabilityType: + AllowedValues: + - 'CloudTrail+Config' + - 'Config' + Type: String + Default: CloudTrail+Config + Description: "Enter the Lacework Control Tower StackSet type to use." + ExistingAccounts: + Description: "Choose to monitor any existing accounts. SUSPENDED accounts are skipped." + Type: String + AllowedValues: + - 'Yes' + - 'No' + Default: 'Yes' + ExistingCloudTrail: + Type: String + MinLength: '1' + AllowedPattern: '^[-a-zA-Z0-9_]*$' + ConstraintDescription: "Invalid CloudTrail name." + Description: "Enter your existing AWS Control Tower CloudTrail name." + Default: 'aws-controltower-BaselineCloudTrail' + LogAccountName: + Type: String + Description: "Enter your AWS Control Tower log account name." + MinLength: '1' + AllowedPattern: '^[-a-zA-Z0-9\s]*$' + ConstraintDescription: "The account name contains alphanumeric characters only." + Default: "Log Archive" + AuditAccountName: + Type: String + Description: "Enter your AWS Control Tower audit account name." + MinLength: '1' + AllowedPattern: '^[-a-zA-Z0-9\s]*$' + ConstraintDescription: "The account name contains alphanumeric characters only." + Default: "Audit" + KMSKeyIdentifierARN: + Description: "Provide the ARN of the KMS key for decrypting S3 log files decryption if necessary. Ensure that the Lacework account or role has kms:decrypt access within the Key Policy. Won't use KMS decrypt if no key provided." + Default: '' + Type: String + MaxLength: '256' + # SecurityHub Configuration Properties + pDisableSecurityHub: + AllowedValues: [ 'true', 'false' ] + Default: 'false' + Description: Update to 'true' to disable Security Hub in all accounts and regions before deleting the stack. + Type: String + pEnableSecurityBestPracticesStandard: + AllowedValues: [ 'true', 'false' ] + Default: 'true' + Description: Indicates whether to enable the AWS Foundational Security Best Practices Standard. + Type: String + pEnableCISStandard: + AllowedValues: [ 'true', 'false' ] + Default: 'false' + Description: Indicates whether to enable the CIS AWS Foundations Benchmark Standard. + Type: String + pCISStandardVersion: + AllowedValues: [ 1.2.0, 1.4.0 ] + Default: 1.4.0 + Description: CIS Standard Version + Type: String + pEnablePCIStandard: + AllowedValues: [ 'true', 'false' ] + Default: 'false' + Description: Indicates whether to enable the Payment Card Industry Data Security Standard (PCI DSS). + Type: String + pRegionLinkingMode: + AllowedValues: [ SPECIFIED_REGIONS, ALL_REGIONS ] + Default: SPECIFIED_REGIONS + Description: + Indicates whether to aggregate findings from all of the available Regions in the current partition. Also determines whether to automatically + aggregate findings from new Regions as Security Hub supports them and you opt into them. + Type: String + pControlTowerRegionsOnly: + AllowedValues: [ 'true', 'false' ] + Default: 'true' + Description: Only enable in the Control Tower governed regions + Type: String + pEnabledRegions: + AllowedPattern: '^$|^([a-z0-9-]{1,64})$|^(([a-z0-9-]{1,64},)*[a-z0-9-]{1,64})$' + ConstraintDescription: + Only lowercase letters, numbers, and hyphens ('-') allowed. (e.g. us-east-1) Additional AWS regions can be provided, separated by commas. (e.g. + us-east-1,ap-southeast-2) + Default: '' + Description: (Optional) Enabled regions (AWS regions, separated by commas). Leave blank to enable all regions. + Type: String + # GuardDuty Configuration Properties + pAutoEnableS3Logs: + AllowedValues: [ 'true', 'false' ] + Default: 'true' + Description: Auto enable S3 logs + Type: String + pAutoEnableK8sLogs: + AllowedValues: [ 'true', 'false' ] + Default: 'false' + Description: Auto Enable kubernetes Logs + Type: String + pAutoEnableMalwareProtection: + AllowedValues: [ 'true', 'false' ] + Default: 'false' + Description: Auto Enable malware protection + Type: String + # General Lambda Function Properties + pCreateLambdaLogGroup: + AllowedValues: [ 'true', 'false' ] + Default: 'false' + Description: + Indicates whether a CloudWatch Log Group should be explicitly created for the Lambda function, to allow for setting a Log Retention and/or KMS + Key for encryption. + Type: String + pLambdaLogGroupRetention: + AllowedValues: [ 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, 3653 ] + Default: 14 + Description: Specifies the number of days you want to retain log events + Type: String + pLambdaLogGroupKmsKey: + AllowedPattern: '^$|^arn:(aws[a-zA-Z-]*){1}:kms:[a-z0-9-]+:\d{12}:key\/[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$' + ConstraintDescription: 'Key ARN example: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab' + Default: '' + Description: + (Optional) KMS Key ARN to use for encrypting the Lambda logs data. If empty, encryption is enabled with CloudWatch Logs managing the server-side + encryption keys. + Type: String + pLambdaLogLevel: + AllowedValues: [ INFO, ERROR, DEBUG ] + Default: INFO + Description: Lambda Function Logging Level + Type: String + # EventBridge Rule Properties + pComplianceFrequency: + ConstraintDescription: Compliance Frequency must be a number between 1 and 30, inclusive. + Default: 7 + Description: Frequency (in days between 1 and 30, default is 7) to check organizational compliance by invoking the Lambda Function. + MinValue: 1 + MaxValue: 30 + Type: Number +Resources: + LaceworkControlTowerCfn: + Type: AWS::CloudFormation::Stack + Properties: + TemplateURL: !Sub "https://${pSRASourceS3BucketName}.s3.${pSRAS3BucketRegion}.${AWS::URLSuffix}/${pSRAStagingS3KeyPrefix}/submodules/lacework-control-tower-cfn/templates/cfn-abi-control-tower-integration.template.yaml" + Parameters: + S3BucketName: !Ref pSRASourceS3BucketName + S3KeyPrefix: !Ref pSRAStagingS3KeyPrefix + LaceworkURL: !Ref LaceworkURL + LaceworkOrgSubAccountNames: !Ref LaceworkOrgSubAccountNames + LaceworkSubAccountName: !Ref LaceworkSubAccountName + LaceworkAccessKeyID: !Ref LaceworkAccessKeyID + LaceworkSecretKey: !Ref LaceworkSecretKey + CapabilityType: !Ref CapabilityType + ExistingAccounts: !Ref ExistingAccounts + ExistingCloudTrail: !Ref ExistingCloudTrail + LogAccountName: !Ref LogAccountName + AuditAccountName: !Ref AuditAccountName + KMSKeyIdentifierARN: !Ref KMSKeyIdentifierARN + CfnAbiAwsSecurityHub: + Type: AWS::CloudFormation::Stack + Properties: + TemplateURL: !Sub "https://${pSRASourceS3BucketName}.s3.${pSRAS3BucketRegion}.${AWS::URLSuffix}/${pSRAStagingS3KeyPrefix}/submodules/cfn-abi-aws-securityhub/templates/sra-securityhub-enable-in-org-ssm.yaml" + Parameters: + pSRASourceS3BucketName: aws-abi-pilot + pSRAS3BucketRegion: !Sub ${AWS::Region} + pSRAStagingS3KeyPrefix: cfn-abi-aws-securityhub + pCISStandardVersion: !Ref pCISStandardVersion + pComplianceFrequency: !Ref pComplianceFrequency + pControlTowerRegionsOnly: !Ref pControlTowerRegionsOnly + pCreateLambdaLogGroup: !Ref pCreateLambdaLogGroup + pDisableSecurityHub: !Ref pDisableSecurityHub + pEnableCISStandard: !Ref pEnableCISStandard + pEnabledRegions: !Ref pEnabledRegions + pEnablePCIStandard: !Ref pEnablePCIStandard + pEnableSecurityBestPracticesStandard: !Ref pEnableSecurityBestPracticesStandard + pLambdaLogGroupKmsKey: !Ref pLambdaLogGroupKmsKey + pLambdaLogGroupRetention: !Ref pLambdaLogGroupRetention + pLambdaLogLevel: !Ref pLambdaLogLevel + pRegionLinkingMode: !Ref pRegionLinkingMode + pSRAAlarmEmail: !Ref pSRAAlarmEmail + pSRASolutionVersion: !Ref pSRASolutionVersion + Tags: + - Key: sra-solution + Value: !Ref pSRAStagingS3KeyPrefix + CfnAbiAmazonGuardDuty: + Type: AWS::CloudFormation::Stack + Properties: + TemplateURL: !Sub "https://${pSRASourceS3BucketName}.s3.${pSRAS3BucketRegion}.${AWS::URLSuffix}/${pSRAStagingS3KeyPrefix}/submodules/cfn-abi-amazon-guardduty/templates/sra-guardduty-enable-in-org-ssm.yaml" + Parameters: + pSRASourceS3BucketName: aws-abi-pilot + pSRAS3BucketRegion: !Sub ${AWS::Region} + pSRAStagingS3KeyPrefix: cfn-abi-amazon-guardduty + pAutoEnableS3Logs: !Ref pAutoEnableS3Logs + pAutoEnableK8sLogs: !Ref pAutoEnableK8sLogs + pAutoEnableMalwareProtection: !Ref pAutoEnableMalwareProtection + Tags: + - Key: sra-solution + Value: !Ref pSRAStagingS3KeyPrefix + LaceworkSecurityHubCfn: + Type: AWS::CloudFormation::Stack + DependsOn: + - LaceworkControlTowerCfn + - CfnAbiAwsSecurityHub + - CfnAbiAmazonGuardDuty + Properties: + TemplateURL: !Sub "https://${pSRASourceS3BucketName}.s3.${pSRAS3BucketRegion}.${AWS::URLSuffix}/${pSRAStagingS3KeyPrefix}/templates/cfn-abi-lacework-sec-hub-ingest.template.yaml" + Parameters: + LaceworkAccount: !Select [ 0, !Split [ '.', !Ref LaceworkURL ] ] + ExternalID: !Select [ 4, !Split [ '-', !Select [ 2, !Split [ '/', !Ref AWS::StackId ] ] ] ] + ApiToken: "{{resolve:secretsmanager:LaceworkApiCredentials:SecretString:AccessToken}}" \ No newline at end of file diff --git a/templates/cfn-abi-lacework-sec-hub-ingest.template.yaml b/templates/cfn-abi-lacework-sec-hub-ingest.template.yaml new file mode 100644 index 0000000..e6fd931 --- /dev/null +++ b/templates/cfn-abi-lacework-sec-hub-ingest.template.yaml @@ -0,0 +1,166 @@ +--- +AWSTemplateFormatVersion: "2010-09-09" +Description: Lacework AWS Security Hub Ingestion Integration +Metadata: + AWS::CloudFormation::Interface: + ParameterGroups: + - Parameters: + - LaceworkAccount + - ExternalID + - ApiToken + ParameterLabels: + LaceworkAccount: + default: Lacework Account, ie. .lacework.net + ExternalID: + default: ExternalID + ApiToken: + default: API Token + +Parameters: + LaceworkAccount: + Description: Your Lacework Account, ie. .lacework.net + Type: String + Default: MyAccount + MinLength: "1" + MaxLength: "45" + AllowedPattern: "^[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*$" + ConstraintDescription: Invalid resource name prefix value. Must match pattern + ^[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*$ + ExternalID: + Description: The cross-account access role created by the stack will use this + value for its ExternalID. + Type: String + Default: "1" + MaxLength: "1224" + ConstraintDescription: Invalid ExternalID value. Must be equal to "%extid" + ApiToken: + Description: The token required for making API requests with Lacework. + Type: String + Default: "1" + MinLength: "1" + ConstraintDescription: A valid API Token is required + +Resources: + LaceworkSecHubQueue: + Type: AWS::SQS::Queue + Properties: + QueueName: !Sub "${LaceworkAccount}-Lacework-Sec-Hub-Queue" + + LaceworkSecHubQueuePolicy: + Type: AWS::SQS::QueuePolicy + Properties: + PolicyDocument: + Version: "2012-10-17" + Statement: + - Sid: EventsRuleAccess + Effect: Allow + Principal: + Service: events.amazonaws.com + Action: + - sqs:SendMessage + Resource: !GetAtt LaceworkSecHubQueue.Arn + Condition: + ArnEquals: + aws:SourceArn: + - !GetAtt LaceworkSecHubEventsRule.Arn + Queues: + - !Ref LaceworkSecHubQueue + + LaceworkSecHubCrossAccountAccessRole: + Type: AWS::IAM::Role + Properties: + RoleName: !Sub "${LaceworkAccount}-Lacework-Sec-Hub-Role" + AssumeRolePolicyDocument: + Version: "2012-10-17" + Statement: + - Effect: Allow + Action: + - sts:AssumeRole + Principal: + AWS: ["434813966438"] + Condition: + StringEquals: + sts:ExternalId: + !Ref ExternalID + Path: "/" + Policies: + - PolicyName: LaceworkSecHubCrossAccountAccessRolePolicy + PolicyDocument: + Version: "2012-10-17" + Statement: + - Effect: Allow + Action: + - sqs:ListQueues + - sqs:GetQueueAttributes + - sqs:GetQueueUrl + - sqs:DeleteMessage + - sqs:ReceiveMessage + Resource: + - !GetAtt LaceworkSecHubQueue.Arn + + LaceworkSecHubEventsRule: + Type: "AWS::Events::Rule" + Properties: + Description: "Captures Findings from AWS Security Hub" + EventBusName: "default" + EventPattern: + source: ["aws.securityhub"] + detail-type: ["Security Hub Findings - Imported"] + Name: !Sub "${LaceworkAccount}-Lacework-Sec-Hub-Events-Rule" + State: ENABLED + Targets: + - Arn: !GetAtt LaceworkSecHubQueue.Arn + Id: lacework-aws-sec-hub-to-sqs-queue + + EventBridgeToToSqsPolicy: + Type: AWS::SQS::QueuePolicy + Properties: + PolicyDocument: + Statement: + - Effect: Allow + Principal: + Service: events.amazonaws.com + Action: SQS:SendMessage + Resource: !GetAtt LaceworkSecHubQueue.Arn + Queues: + - !Ref LaceworkSecHubQueue + + LaceworkSnsCustomResource: + Type: Custom::LaceworkSnsCustomResource + DependsOn: + - LaceworkSecHubQueuePolicy + Properties: + Type: AWS_SECURITY_HUB + ServiceToken: !Sub "arn:aws:sns:${AWS::Region}:434813966438:prodn-customer-cloudformation" + IntegrationName: + !Ref AWS::StackName + RoleArn: + !GetAtt LaceworkSecHubCrossAccountAccessRole.Arn + ExternalId: + !Ref ExternalID + SqsQueueUrl: + !Ref LaceworkSecHubQueue + ApiToken: + !Ref ApiToken + Account: + !Ref LaceworkAccount + TemplateVersion: "0.1" + AWSAccountId: + !Ref AWS::AccountId +Outputs: + RoleARN: + Description: Cross-account access role ARN to share with Lacework + integration + Value: + !GetAtt LaceworkSecHubCrossAccountAccessRole.Arn + ExternalID: + Description: ExternalID to share with Lacework + Value: + !Ref ExternalID + SQSQueueURL: + Description: SQS queue URL to share with Lacework + Value: + !Ref LaceworkSecHubQueue + TemplateVersion: + Description: Template version + Value: "0.1" diff --git a/templates/sample-workload.template.yaml b/templates/sample-workload.template.yaml deleted file mode 100644 index 989e996..0000000 --- a/templates/sample-workload.template.yaml +++ /dev/null @@ -1,97 +0,0 @@ ---- -AWSTemplateFormatVersion: '2010-09-09' -Description: Sample Stack -Parameters: - Param1: - Description: Param1 - Type: String -Resources: - LambdaExecutionRole: - 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_policy - PolicyDocument: - Version: '2012-10-17' - Statement: - - Effect: Allow - Action: - - logs:CreateLogGroup - - logs:CreateLogStream - - logs:PutLogEvents - Resource: arn:aws:logs:*:*:* - - Effect: Allow - Action: - - cloudformation:DescribeStacks - Resource: "*" - GenID: - Type: AWS::Lambda::Function - Properties: - Code: - ZipFile: - Fn::Join: - - "\n" - - - import random - - import json - - import cfnresponse - - from cfnresponse import send, SUCCESS - - 'def handler(event, context):' - - " if event['RequestType'] == 'Delete':" - - " send(event, context, 'SUCCESS', {})" - - " return" - - " if event['RequestType'] == 'Create':" - - ' token= "%0x.%0x" % (random.SystemRandom().getrandbits(3*8), - random.SystemRandom().getrandbits(8*8))' - - " responseData = {}" - - " responseData['Data'] = token" - - " send(event, context, 'SUCCESS', responseData)" - - " return token" - Handler: index.handler - Runtime: python3.7 - Timeout: 5 - Role: - Fn::GetAtt: - - LambdaExecutionRole - - Arn - GetID: - Type: Custom::GenerateID - Version: '1.0' - Properties: - ServiceToken: - Fn::GetAtt: - - GenID - - Arn - ResponseURL: - Fn::Join: - - '' - - - http://ResponseURL - - Ref: AWS::StackId - - RequestId - StackId: - Ref: AWS::StackId - ResourceProperties: - RequestType: Create - RequestId: - Fn::Join: - - '' - - - Ref: AWS::StackId - - RequestId - LogicalResourceId: GenIDLogicalResourceId -Outputs: - ClusterID: - Value: - Fn::GetAtt: - - GetID - - Data - Param1Output: - Value: !Ref Param1