AWSTemplateFormatVersion: '2010-09-09' Description: This template creates a virtual private cloud (VPC) infrastructure for a multi-Availability Zone vSensor deployment on the Amazon Web Services (AWS) Cloud. It deploys a VPC, bastion hosts, and scalable cluster of Darktrace vSensors behind a Network Load Balancer. **WARNING** You will be billed for AWS resources you use if you create a stack from this template. (qs-1ths1l3in) Metadata: QuickStartDocumentation: EntrypointName: Parameters for deploying into a new VPC Order: 1 AWS::CloudFormation::Interface: ParameterGroups: - Label: default: Network configuration Parameters: - AvailabilityZones - VPCCIDR - PrivateSubnet1CIDR - PrivateSubnet2CIDR - PublicSubnet1CIDR - PublicSubnet2CIDR - RemoteAccessCIDR - Label: default: Bastion configuration Parameters: - BastionEnable - BastionInstanceType - BastionKeyPairName - BastionAMIOS - Label: default: Darktrace appliance configuration Parameters: - VSensorApplianceHostname - VSensorAppliancePort - VSensorAppliancePushtoken - Label: default: Darktrace vSensor configuration Parameters: - VSensorInstanceType - VSensorKeyPairName - VSensorUpdatekey - VSensorDesiredCapacityASG - VSensorMinSizeASG - VSensorMaxSizeASG - VSensorOsSensorHMAC - Label: default: VPC Traffic Mirror configuration Parameters: - VSensorTrafficMirrorRuleNumber - VSensorTrafficMirrorSourceCIDR - VSensorTrafficMirrorDestCIDR - Label: default: Logs and captured packet retention Parameters: - VSensorLogGroupRetention - VSensorLifecycleS3BucketDays - Label: default: AWS Quick Start configuration Parameters: - QSS3BucketName - QSS3BucketRegion - QSS3KeyPrefix - ShortID ParameterLabels: # Network Config AvailabilityZones: default: Availability Zones VPCCIDR: default: VPC CIDR PrivateSubnet1CIDR: default: Private subnet 1 CIDR PrivateSubnet2CIDR: default: Private subnet 2 CIDR PublicSubnet1CIDR: default: Public subnet 1 CIDR PublicSubnet2CIDR: default: Public subnet 2 CIDR RemoteAccessCIDR: default: Bastion host CIDR # Bastion Config BastionEnable: default: Deploy with Bastion host? BastionInstanceType: default: Bastion host instance type BastionKeyPairName: default: Key pair name BastionAMIOS: default: Bastion host AMI operating system # Appliance Config VSensorApplianceHostname: default: Appliance host name VSensorAppliancePort: default: Appliance port VSensorAppliancePushtoken: default: Appliance push token # vSensor Config VSensorInstanceType: default: EC2 instance type VSensorKeyPairName: default: EC2 key pair name VSensorUpdatekey: default: Update key VSensorDesiredCapacityASG: default: Desired vSensor instance capacity VSensorMinSizeASG: default: Minimum vSensor instance capacity VSensorMaxSizeASG: default: Maximum vSensor instance capacity VSensorOsSensorHMAC: default: osSensor HMAC Token # Logs and PCAPs Config VSensorLogGroupRetention: default: CloudWatch logs retention (days) VSensorLifecycleS3BucketDays: default: Captured packets storage retention (days) # Traffic Mirror Config VSensorTrafficMirrorRuleNumber: default: Traffic Mirror rule number VSensorTrafficMirrorSourceCIDR: default: Source traffic CIDR to filter (0.0.0.0/0 for all traffic) VSensorTrafficMirrorDestCIDR: default: Destination traffic CIDR to filter (0.0.0.0/0 for all traffic) # QuickStart Config QSS3BucketName: default: Quick Start S3 bucket name QSS3BucketRegion: default: Quick Start S3 bucket Region QSS3KeyPrefix: default: Quick Start S3 key prefix ShortID: default: Quick Start unique run ID (12 characters or less) Parameters: # Appliance Config VSensorApplianceHostname: Type: String Description: Host name of the Darktrace appliance. VSensorAppliancePort: Type: Number Description: Connection port between vSensor and the Darktrace appliance. Default: 443 VSensorAppliancePushtoken: AllowedPattern: ^[a-zA-Z0-9-]{4,64}:[a-zA-Z0-9]{5,63}$ Type: String Description: Push token to authenticate with the appliance. For more information, see the https://customerportal.darktrace.com/login[Darktrace Customer Portal]. NoEcho: true # VSensor Config VSensorInstanceType: Default: t3.medium Type: String Description: EC2 instance type. Default is `t3.medium`. AllowedValues: - t3.medium - m5.large - m5.2xlarge - m5.4xlarge VSensorKeyPairName: Type: 'AWS::EC2::KeyPair::KeyName' Description: EC2 key pair to use to connect to vSensor. VSensorUpdatekey: AllowedPattern: ^[a-zA-Z0-9%\.]+:[a-zA-Z0-9]+$ Type: String Description: Darktrace update key. If you don't have one, contact your Darktrace representative. Default: 'XXXXXX:XXXX' NoEcho: true VSensorDesiredCapacityASG: Type: Number Description: Desired number of vSensor instances in the Auto-Scaling group. Default: 1 VSensorMinSizeASG: Type: String Description: Minimum number of vSensor instances in the Auto-Scaling group. Default: 1 VSensorMaxSizeASG: Type: Number Description: Maximum number of vSensor instances in the Auto-Scaling group. Default: 5 VSensorOsSensorHMAC: Type: String Description: Hash-based message authentication code (HMAC) token to authenticate osSensors with vSensor. Default: "" NoEcho: true # Network Config AvailabilityZones: Type: 'List' Description: Availability Zones to use for the subnets in the VPC. Two Availability Zones are used for this deployment. VPCCIDR: AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28. Default: 10.0.0.0/16 Description: CIDR block for the VPC. Type: String PrivateSubnet1CIDR: AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28. Default: 10.0.0.0/19 Description: CIDR block for private subnet 1, located in Availability Zone 1. Type: String PrivateSubnet2CIDR: AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28. Default: 10.0.32.0/19 Description: CIDR block for private subnet 2, located in Availability Zone 2. Type: String PublicSubnet1CIDR: AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28. Default: 10.0.128.0/20 Description: CIDR block for the public (DMZ) subnet 1, located in Availability Zone 1. Type: String PublicSubnet2CIDR: AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28. Default: 10.0.144.0/20 Description: CIDR block for the public (DMZ) subnet 2, located in Availability Zone 2. Type: String RemoteAccessCIDR: AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$ ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/x. Description: CIDR IP range that is permitted to access the bastion hosts. We recommend that you set this value to a trusted IP range. Type: String # Bastion Config BastionEnable: Default: 'Yes' Description: Use the AWS Quickstart Bastion template to deploy a public Bastion host to access your vSensor deployment. If 'No' is selected, configure your ssh access manually after deployment. Type: String AllowedValues: - 'Yes' - 'No' BastionInstanceType: # Limit to Nitro instances, compatible with Traffic Mirroring. AllowedValues: - t3.micro - t3.small - t3.medium - t3.large - t3.xlarge - t3.2xlarge Default: t3.micro Description: Amazon EC2 instance type for the bastion hosts. Type: String BastionKeyPairName: Description: Name of an existing public/private key pair, which allows you to securely connect to your instance after it launches. Type: AWS::EC2::KeyPair::KeyName BastionAMIOS: AllowedValues: - Amazon-Linux2-HVM - CentOS-7-HVM - Ubuntu-Server-20.04-LTS-HVM - SUSE-SLES-15-HVM Default: Amazon-Linux2-HVM Description: Linux distribution for the Amazon Machine Image (AMI) used for the bastion host instances. Type: String # Traffic Mirroring Config VSensorTrafficMirrorRuleNumber: Type: Number Description: Enter a priority to assign to the rule. Default: 100 VSensorTrafficMirrorSourceCIDR: Type: String Default: '0.0.0.0/0' Description: Source CIDR for the Traffic Mirror filter. Enter `0.0.0.0/0` for all traffic. VSensorTrafficMirrorDestCIDR: Type: String Default: '0.0.0.0/0' Description: Destination CIDR for the Traffic Mirror filter. Enter `0.0.0.0/0` for all traffic. # Logs & PCAPs Config VSensorLogGroupRetention: Type: Number AllowedValues: - 1 - 3 - 5 - 7 - 14 - 30 - 60 - 90 - 120 - 150 - 180 - 365 - 400 - 545 - 731 - 1827 - 3653 Description: Number of days to retain Cloudwatch logs. Default: 30 VSensorLifecycleS3BucketDays: Type: Number Description: Number of days to retain captured packets in Amazon S3. Default: 7 # QuickStart Config QSS3BucketName: AllowedPattern: '^[0-9a-zA-Z]+([0-9a-zA-Z-]*[0-9a-zA-Z])*$' ConstraintDescription: The Quick Start bucket name can include numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen (-). Default: aws-quickstart Description: Name of the S3 bucket for your copy of the Quick Start assets. Keep the default name unless you are customizing the template. Changing the name updates code references to point to a new Quick Start location. This name can include numbers, lowercase letters, uppercase letters, and hyphens, but do not start or end with a hyphen (-). See https://aws-quickstart.github.io/option1.html. Type: String QSS3BucketRegion: Default: 'us-east-1' Description: 'AWS Region where the Quick Start S3 bucket (QSS3BucketName) is hosted. Keep the default Region unless you are customizing the template. Changing this Region updates code references to point to a new Quick Start location. When using your own bucket, specify the Region. See https://aws-quickstart.github.io/option1.html.' Type: String QSS3KeyPrefix: AllowedPattern: '^[0-9a-zA-Z-/]*$' ConstraintDescription: The Quick Start S3 key prefix can include numbers, lowercase letters, uppercase letters, hyphens (-), and forward slashes (/). The prefix should end with a forward slash (/). Default: quickstart-darktrace-vsensor/ Description: S3 key prefix that is used to simulate a directory for your copy of the Quick Start assets. Keep the default prefix unless you are customizing the template. Changing this prefix updates code references to point to a new Quick Start location. This prefix can include numbers, lowercase letters, uppercase letters, hyphens (-), and forward slashes (/). End with a forward slash. See https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html and https://aws-quickstart.github.io/option1.html. Type: String ShortID: AllowedPattern: ^[0-9a-z-]{0,12}$ ConstraintDescription: Unique ID prefix can include up to 12 characters, including numbers, lowercase letters, hyphens (-). Description: Quick Start short unique ID used to identify resources from other installations of this Quick Start. If left empty, a random string is generated. Default: "" Type: String Conditions: UsingDefaultBucket: !Equals - !Ref QSS3BucketName - "aws-quickstart" CreateBastion: !Equals - !Ref BastionEnable - "Yes" Resources: ## Generate a short ID if the user does not define one. # This involves running a Lambda function. # From https://www.itonaut.com/2018/01/03/generate-passwords-in-aws-cloudformation-template/ # Modified to take a user submitted ShortID and return this if provided, else generate the random value. LambdaExecutionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole RandomStringLambdaFunction: Type: AWS::Lambda::Function Properties: Code: ZipFile: > const response = require("cfn-response"); const randomString = (length, chars) => { var result = ''; for (var i = length; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)]; return result; }; exports.handler = (event, context) =>{ let str = ""; let length = 12; let shortID = ""; if ("ResourceProperties" in event) { if ("ShortID" in event['ResourceProperties'] && event['ResourceProperties']['ShortID'] != "") { str = event['ResourceProperties']['ShortID']; } else if ("Length" in event['ResourceProperties']) { length = Number(event['ResourceProperties']['Length']); } } if (str == "") { str = randomString(length, '0123456789abcdefghijklmnopqrstuvwxyz'); } const responseData = {IDString: str}; response.send(event, context, response.SUCCESS, responseData); }; Handler: index.handler Runtime: nodejs16.x Role: !GetAtt LambdaExecutionRole.Arn MemorySize: 128 Timeout: 20 Tags: - Key: darktrace-vsensor-quickstart Value: !Ref ShortID TracingConfig: Mode: Active RandomStringLambdaLogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Sub "/aws/lambda/${RandomStringLambdaFunction}" RetentionInDays: !Ref VSensorLogGroupRetention RandomStringLambdaLogPermissions: Type: AWS::IAM::Policy Properties: Roles: - !Ref LambdaExecutionRole PolicyName: !Sub "${RandomStringLambdaFunction}-LogGroup" PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:CreateLogStream - logs:PutLogEvents Resource: - !Sub "arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${RandomStringLambdaFunction}" - !Sub "arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${RandomStringLambdaFunction}:*" - !Sub "arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${RandomStringLambdaFunction}:*:*" ShortIDRand: Type: AWS::CloudFormation::CustomResource DependsOn: RandomStringLambdaLogPermissions Properties: Length: 12 ShortID: !Ref ShortID ServiceToken: !GetAtt RandomStringLambdaFunction.Arn VPCStack: Type: AWS::CloudFormation::Stack DeletionPolicy: Delete # Ignore Notification ARN in customer env. # kics-scan ignore-line Properties: TemplateURL: !Sub - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}submodules/quickstart-aws-vpc/templates/aws-vpc.template.yaml' - S3Bucket: !If - UsingDefaultBucket - !Sub "aws-quickstart-${AWS::Region}" - !Ref "QSS3BucketName" S3Region: !If - UsingDefaultBucket - !Ref "AWS::Region" - !Ref "QSS3BucketRegion" Parameters: AvailabilityZones: !Join - ',' - Ref: AvailabilityZones NumberOfAZs: '2' PrivateSubnet1ACIDR: Ref: PrivateSubnet1CIDR PrivateSubnet2ACIDR: Ref: PrivateSubnet2CIDR PublicSubnet1CIDR: Ref: PublicSubnet1CIDR PublicSubnet2CIDR: Ref: PublicSubnet2CIDR VPCCIDR: Ref: VPCCIDR Tags: - Key: "Name" Value: !Sub - "${ShortID}-vSensor-VPC-Stack" - ShortID: !GetAtt ShortIDRand.IDString BastionStack: Type: AWS::CloudFormation::Stack Condition: CreateBastion DeletionPolicy: Delete # Ignore Notification ARN in customer env. # kics-scan ignore-line Properties: TemplateURL: !Sub - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}submodules/quickstart-linux-bastion/templates/linux-bastion.template' - S3Bucket: !If - UsingDefaultBucket - !Sub "aws-quickstart-${AWS::Region}" - !Ref "QSS3BucketName" S3Region: !If - UsingDefaultBucket - !Ref "AWS::Region" - !Ref "QSS3BucketRegion" Parameters: BastionHostName: !Sub - "${ShortID}-vSensor-Bastion" - ShortID: !GetAtt ShortIDRand.IDString BastionAMIOS: Ref: BastionAMIOS BastionInstanceType: Ref: BastionInstanceType EnableTCPForwarding: true KeyPairName: Ref: BastionKeyPairName PublicSubnet1ID: !GetAtt - VPCStack - Outputs.PublicSubnet1ID PublicSubnet2ID: !GetAtt - VPCStack - Outputs.PublicSubnet2ID RemoteAccessCIDR: Ref: RemoteAccessCIDR VPCID: !GetAtt - VPCStack - Outputs.VPCID Tags: - Key: "Name" Value: !Sub - "${ShortID}-vSensor-Bastion-Stack" - ShortID: !GetAtt ShortIDRand.IDString VSensorStack: Type: AWS::CloudFormation::Stack DeletionPolicy: Delete # Ignore Notification ARN in customer env. # kics-scan ignore-line Properties: TemplateURL: !Sub - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}templates/darktrace-vsensor-workload.template.yaml' - S3Bucket: !If - UsingDefaultBucket - !Sub "aws-quickstart-${AWS::Region}" - !Ref "QSS3BucketName" S3Region: !If - UsingDefaultBucket - !Ref "AWS::Region" - !Ref "QSS3BucketRegion" Parameters: ApplianceHostname: !Ref VSensorApplianceHostname AppliancePort: !Ref VSensorAppliancePort AppliancePushtoken: !Ref VSensorAppliancePushtoken VsensorUpdatekey: !Ref VSensorUpdatekey osSensorHMAC: !Ref VSensorOsSensorHMAC Subnets: !Join - "," - - Fn::GetAtt: - VPCStack - Outputs.PrivateSubnet1AID - Fn::GetAtt: - VPCStack - Outputs.PrivateSubnet2AID DeploymentVPC: !GetAtt - VPCStack - Outputs.VPCID InstanceType: !Ref VSensorInstanceType # If customer uses bastion, allow bastion NSG access to vSensors. InstanceSecurityGroups: Fn::If: - CreateBastion - Fn::GetAtt: - BastionStack - Outputs.BastionSecurityGroupID - "" LifecycleS3BucketDays: !Ref VSensorLifecycleS3BucketDays DesiredCapacityASG: !Ref VSensorDesiredCapacityASG MinSizeASG: !Ref VSensorMinSizeASG MaxSizeASG: !Ref VSensorMaxSizeASG LogGroupRetention: !Ref VSensorLogGroupRetention TrafficMirrorRuleNumber: !Ref VSensorTrafficMirrorRuleNumber TrafficMirrorSourceCIDR: !Ref VSensorTrafficMirrorSourceCIDR TrafficMirrorDestCIDR: !Ref VSensorTrafficMirrorDestCIDR VpcCIDRBlock: !Ref VPCCIDR SshCIDRBlock: !Ref VPCCIDR KeyPairName: !Ref VSensorKeyPairName QSS3BucketName: !Ref QSS3BucketName QSS3BucketRegion: !Ref QSS3BucketRegion QSS3KeyPrefix: !Ref QSS3KeyPrefix ShortID: !GetAtt ShortIDRand.IDString Tags: - Key: "Name" Value: !Sub - "${ShortID}-vSensor-Stack" - ShortID: !GetAtt ShortIDRand.IDString Outputs: DeploymentVPC: Description: ID of the deployed VPC. Value: !GetAtt - VPCStack - Outputs.VPCID PrivateSubnets: Description: Subnet IDs of the private subnets. Value: !Join - "," - - Fn::GetAtt: - VPCStack - Outputs.PrivateSubnet1AID - Fn::GetAtt: - VPCStack - Outputs.PrivateSubnet2AID PublicSubnets: Description: Subnet IDs of the public subnets. Value: !Join - "," - - Fn::GetAtt: - VPCStack - Outputs.PublicSubnet1ID - Fn::GetAtt: - VPCStack - Outputs.PublicSubnet2ID NatGatewayEIPs: Description: Elastic IPs allocated to subnets, allow these access to your Appliance. Value: !Join - "," - - Fn::GetAtt: - VPCStack - Outputs.NAT1EIP - Fn::GetAtt: - VPCStack - Outputs.NAT2EIP LoadBalancer: Description: Network Load Balancer, required for osSensor clients. Value: Fn::GetAtt: - VSensorStack - Outputs.LoadBalancer LoadBalancerDNS: Description: DNS name of the Network Load Balancer, required for osSensor clients. Value: Fn::GetAtt: - VSensorStack - Outputs.LoadBalancerDNS TrafficMirrorFilterId: Description: ID of the Traffic Mirror filter generated for Traffic Mirror sessions. Value: Fn::GetAtt: - VSensorStack - Outputs.TrafficMirrorFilterId TrafficMirrorTargetId: Description: ID of the Traffic Mirror target generated for Traffic Mirror sessions. Value: Fn::GetAtt: - VSensorStack - Outputs.TrafficMirrorTargetId BucketName: Description: Name of the PCAP S3 bucket. Value: Fn::GetAtt: - VSensorStack - Outputs.BucketName Postdeployment: Description: See the deployment guide for post-deployment steps. Value: https://aws.amazon.com/quickstart/?quickstart-all.sort-by=item.additionalFields.sortDate&quickstart-all.sort-order=desc&awsm.page-quickstart-all=5