AWSTemplateFormatVersion: "2010-09-09"
Description: Deploys Nubeva SKI & Open Source Tools (qs-1qg4tqp9n)
Metadata:
  QuickStartDocumentation:
    EntrypointName: "Parameters for launching into an existing VPC"
  AWS::CloudFormation::Interface:
    ParameterGroups:
    - Label:
        default: VPC network configuration
      Parameters:
      - VPCID
      - VPCCIDR
      - PrivateSubnet1ID
      - PrivateSubnet2ID
      - RemoteAccessCIDR
    - Label:
        default: Nubeva configuration
      Parameters:
      - APIKey
      - ArkimeInstall
      - WiresharkInstall
      - SuricataInstall
      - ZeekInstall
      - ClientInstall
      - ToolAdmin
      - ToolPassword
      - AddESRole
    - Label:
        default: Auto Scaling group configuration
      Parameters:
      - KeyPairName
      - NodeInstanceType
      - NumberOfNodes
      - MaximumNodes
    - Label:
        default: AWS Quick Start configuration
      Parameters:
      - QSS3BucketName
      - QSS3BucketRegion
      - QSS3KeyPrefix
    ParameterLabels:
      ArkimeInstall:
        default: Install Arkime ASG
      WiresharkInstall:
        default: Install Wireshark ASG
      SuricataInstall:
        default: Install Suricata ASG
      ZeekInstall:
        default: Install Zeek ASG
      ClientInstall:
        default: Install TLS generation clients
      AddESRole:
        default: Install Elasticsearch service-linked role
      ToolAdmin:
        default: Administrator name
      ToolPassword:
        default: Administrator password
      KeyPairName:
        default: SSH key name
      QSS3BucketName:
        default: Quick Start S3 bucket name
      QSS3BucketRegion:
        default: Quick Start S3 bucket Region
      QSS3KeyPrefix:
        default: Quick Start S3 key prefix
      RemoteAccessCIDR:
        default: Allowed external access CIDR
      NodeInstanceType:
        default: Node instance type
      NumberOfNodes:
        default: Number of nodes
      MaximumNodes:
        default: Maximum nodes per tool
      PrivateSubnet1ID:
        default: Private subnet 1 ID
      PrivateSubnet2ID:
        default: Private subnet 2 ID
      VPCID:
        default: VPC ID
      VPCCIDR:
        default: VPC CIDR
      APIKey:
        default: Nubeva token

Parameters:
  ArkimeInstall:
    Default: true
    AllowedValues:
    - true
    - false
    Description: Choose to install Arkime.
    Type: String
  WiresharkInstall:
    Default: true
    AllowedValues:
    - true
    - false
    Description: Choose to install Wireshark.
    Type: String
  SuricataInstall:
    Default: true
    AllowedValues:
    - true
    - false
    Description: Choose to install Suricata.
    Type: String
  ZeekInstall:
    Default: true
    AllowedValues:
    - true
    - false
    Description: Choose to install Zeek.
    Type: String
  ClientInstall:
    Default: true
    AllowedValues:
    - true
    - false
    Description: Choose to install TLS generation clients.
    Type: String
  AddESRole:
    Default: false
    AllowedValues:
    - true
    - false
    Description: Choose to install Elasticsearch Service linked role.
    Type: String
  KeyPairName:
    Description: Name of an existing key pair, which allows you
      to securely connect to your instance after it launches.
    Type: AWS::EC2::KeyPair::KeyName
  ToolAdmin:
    Description: User name associated with the administrator account for the created tools.
    Type: String
    Default: tooladmin
    MinLength: 4
    MaxLength: 16
    AllowedPattern: "[a-zA-Z][a-zA-Z0-9]*"
    ConstraintDescription: Name must begin with a letter and contain 4-16 alphanumeric characters.
  ToolPassword:
    Description: Password must contain 8-32 alphanumeric characters.
    NoEcho: true
    Type: String
    MinLength: 8
    MaxLength: 32
    AllowedPattern: "[a-zA-Z0-9]*"
    ConstraintDescription: Password must contain between 8 and 32 alphanumeric characters.
  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-nubeva-tlsdecrypt/
    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
  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 permitted to access the instances. Set this value to a trusted IP range.
    Type: String
  NodeInstanceType:
    Default: m5.large
    AllowedValues:
    - m5.large
    - m5.xlarge
    - m5.2xlarge
    - m5.4xlarge
    - m5.12xlarge
    - m5.24xlarge
    - c5.large
    - c5.xlarge
    - c5.2xlarge
    - c5.4xlarge
    - c5.9xlarge
    - c5.18xlarge
    - i3.large
    - i3.xlarge
    - i3.2xlarge
    - i3.4xlarge
    - i3.8xlarge
    - i3.16xlarge
    - r5.large
    - r5.xlarge
    - r5.2xlarge
    - r5.4xlarge
    - r5.12xlarge
    - r5.24xlarge
    ConstraintDescription: Value must be a valid EC2 instance type.
    Description: Type of EC2 instance for the node instances.
    Type: String
  NumberOfNodes:
    Default: 1
    Description: Number of tool node instances. The default is one for each of the two Availability Zones.
    Type: Number
  MaximumNodes:
    Default: 6
    Description: Maximum number of EC2 instance nodes in the tool Auto Scaling group.
    Type: String
  APIKey:
    Description: Token for your Nubeva account.
    Type: String
  VPCID:
    Type: "AWS::EC2::VPC::Id"
    Description: ID of your existing VPC (for example, vpc-0343606e).
  PrivateSubnet1ID:
    Type: "AWS::EC2::Subnet::Id"
    Description: ID of the private subnet in Availability Zone 1 in your existing VPC (for example, subnet-fe9a8b32).
  PrivateSubnet2ID:
    Type: "AWS::EC2::Subnet::Id"
    Description: ID of the private subnet in Availability Zone 2 in your existing VPC (for example, subnet-be8b01ea).
  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


Conditions:
  UsingDefaultBucket: !Equals [!Ref QSS3BucketName, 'aws-quickstart']
  ArkimeInstallTrue: !Equals
    - !Ref ArkimeInstall
    - 'true'
  WiresharkInstallTrue: !Equals
    - !Ref WiresharkInstall
    - 'true'
  SuricataInstallTrue: !Equals
    - !Ref SuricataInstall
    - 'true'
  ZeekInstallTrue: !Equals
    - !Ref ZeekInstall
    - 'true'
  ESRoleInstallTrue: !Equals
    - !Ref AddESRole
    - 'true'

Resources:
  BaseESSLR:
    Condition: ESRoleInstallTrue
    Type: AWS::IAM::ServiceLinkedRole
    Properties:
      AWSServiceName: es.amazonaws.com
      Description: Default Amazon ES linked IAM role
  ArkimeStack:
    Condition: ArkimeInstallTrue
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL:
        !Sub
          - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}templates/nubeva-arkime.template.yaml'
          - S3Region: !If [UsingDefaultBucket, !Ref 'AWS::Region', !Ref QSS3BucketRegion]
            S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName]
      Parameters:
        KeyPairName: !Ref KeyPairName
        PrivateSubnet1ID: !Ref PrivateSubnet1ID
        PrivateSubnet2ID: !Ref PrivateSubnet2ID
        NumberOfNodes: !Ref NumberOfNodes
        MaximumNodes: !Ref MaximumNodes
        NodeInstanceType: !Ref NodeInstanceType
        RemoteAccessCIDR: !Ref RemoteAccessCIDR
        VPCID: !Ref VPCID
        VPCCIDR: !Ref VPCCIDR
        APIKey: !Ref APIKey
        ToolAdmin: !Ref ToolAdmin
        ToolPassword: !Ref ToolPassword
        ClientInstall: !Ref ClientInstall
        QSS3BucketName: !Ref QSS3BucketName
        QSS3BucketRegion: !Ref QSS3BucketRegion
        QSS3KeyPrefix:  !Ref QSS3KeyPrefix
        SSLdbReadAuth: !Join
          - ''
          - - Fn::Base64: !Sub
                - '{"type":"ddb","domain":"${Domain}","region":"${Region}","ak":"${AccessKey}","sk":"${SecretKey}"}'
                - Domain: !Ref NubevaDDBTable
                  Region: !Ref AWS::Region
                  AccessKey: !Ref NubevaDecryptorAccessKey
                  SecretKey: !GetAtt NubevaDecryptorAccessKey.SecretAccessKey
        SSLdbWriteAuth: !Join
          - ''
          - - Fn::Base64: !Sub
                - '{"type":"ddb","domain":"${Domain}","region":"${Region}","ak":"${AccessKey}","sk":"${SecretKey}"}'
                - Domain: !Ref NubevaDDBTable
                  Region: !Ref AWS::Region
                  AccessKey: !Ref NubevaSensorAccessKey
                  SecretKey: !GetAtt NubevaSensorAccessKey.SecretAccessKey
  WiresharkStack:
    Condition: WiresharkInstallTrue
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL:
        !Sub
          - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}templates/nubeva-wireshark.template.yaml'
          - S3Region: !If [UsingDefaultBucket, !Ref 'AWS::Region', !Ref QSS3BucketRegion]
            S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName]
      Parameters:
        KeyPairName: !Ref KeyPairName
        PrivateSubnet1ID: !Ref PrivateSubnet1ID
        PrivateSubnet2ID: !Ref PrivateSubnet2ID
        NumberOfNodes: !Ref NumberOfNodes
        MaximumNodes: !Ref MaximumNodes
        NodeInstanceType: !Ref NodeInstanceType
        RemoteAccessCIDR: !Ref RemoteAccessCIDR
        VPCID: !Ref VPCID
        APIKey: !Ref APIKey
#        ToolAdmin: !Ref ToolAdmin
#        ToolPassword: !Ref ToolPassword
        VPCCIDR: !Ref VPCCIDR
        ClientInstall: !Ref ClientInstall
        QSS3BucketName: !Ref QSS3BucketName
        QSS3BucketRegion: !Ref QSS3BucketRegion
        QSS3KeyPrefix:  !Ref QSS3KeyPrefix
        SSLdbReadAuth: !Join
          - ''
          - - Fn::Base64: !Sub
                - '{"type":"ddb","domain":"${Domain}","region":"${Region}","ak":"${AccessKey}","sk":"${SecretKey}"}'
                - Domain: !Ref NubevaDDBTable
                  Region: !Ref AWS::Region
                  AccessKey: !Ref NubevaDecryptorAccessKey
                  SecretKey: !GetAtt NubevaDecryptorAccessKey.SecretAccessKey
        SSLdbWriteAuth: !Join
          - ''
          - - Fn::Base64: !Sub
                - '{"type":"ddb","domain":"${Domain}","region":"${Region}","ak":"${AccessKey}","sk":"${SecretKey}"}'
                - Domain: !Ref NubevaDDBTable
                  Region: !Ref AWS::Region
                  AccessKey: !Ref NubevaSensorAccessKey
                  SecretKey: !GetAtt NubevaSensorAccessKey.SecretAccessKey

  SuricataStack:
    Condition: SuricataInstallTrue
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL:
        !Sub
          - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}templates/nubeva-suricata.template.yaml'
          - S3Region: !If [UsingDefaultBucket, !Ref 'AWS::Region', !Ref QSS3BucketRegion]
            S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName]
      Parameters:
        KeyPairName: !Ref KeyPairName
        PrivateSubnet1ID: !Ref PrivateSubnet1ID
        PrivateSubnet2ID: !Ref PrivateSubnet2ID
        NumberOfNodes: !Ref NumberOfNodes
        MaximumNodes: !Ref MaximumNodes
        NodeInstanceType: !Ref NodeInstanceType
        RemoteAccessCIDR: !Ref RemoteAccessCIDR
        VPCID: !Ref VPCID
        VPCCIDR: !Ref VPCCIDR
        APIKey: !Ref APIKey
        ClientInstall: !Ref ClientInstall
        QSS3BucketName: !Ref QSS3BucketName
        QSS3BucketRegion: !Ref QSS3BucketRegion
        QSS3KeyPrefix:  !Ref QSS3KeyPrefix
        SSLdbReadAuth: !Join
          - ''
          - - Fn::Base64: !Sub
                - '{"type":"ddb","domain":"${Domain}","region":"${Region}","ak":"${AccessKey}","sk":"${SecretKey}"}'
                - Domain: !Ref NubevaDDBTable
                  Region: !Ref AWS::Region
                  AccessKey: !Ref NubevaDecryptorAccessKey
                  SecretKey: !GetAtt NubevaDecryptorAccessKey.SecretAccessKey
        SSLdbWriteAuth: !Join
          - ''
          - - Fn::Base64: !Sub
                - '{"type":"ddb","domain":"${Domain}","region":"${Region}","ak":"${AccessKey}","sk":"${SecretKey}"}'
                - Domain: !Ref NubevaDDBTable
                  Region: !Ref AWS::Region
                  AccessKey: !Ref NubevaSensorAccessKey
                  SecretKey: !GetAtt NubevaSensorAccessKey.SecretAccessKey
  ZeekStack:
    Condition: ZeekInstallTrue
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL:
        !Sub
          - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}templates/nubeva-zeek.template.yaml'
          - S3Region: !If [UsingDefaultBucket, !Ref 'AWS::Region', !Ref QSS3BucketRegion]
            S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName]
      Parameters:
        KeyPairName: !Ref KeyPairName
        PrivateSubnet1ID: !Ref PrivateSubnet1ID
        PrivateSubnet2ID: !Ref PrivateSubnet2ID
        NumberOfNodes: !Ref NumberOfNodes
        MaximumNodes: !Ref MaximumNodes
        NodeInstanceType: !Ref NodeInstanceType
        RemoteAccessCIDR: !Ref RemoteAccessCIDR
        VPCID: !Ref VPCID
        VPCCIDR: !Ref VPCCIDR
        APIKey: !Ref APIKey
        ClientInstall: !Ref ClientInstall
        QSS3BucketName: !Ref QSS3BucketName
        QSS3BucketRegion: !Ref QSS3BucketRegion
        QSS3KeyPrefix:  !Ref QSS3KeyPrefix
        SSLdbReadAuth: !Join
          - ''
          - - Fn::Base64: !Sub
                - '{"type":"ddb","domain":"${Domain}","region":"${Region}","ak":"${AccessKey}","sk":"${SecretKey}"}'
                - Domain: !Ref NubevaDDBTable
                  Region: !Ref AWS::Region
                  AccessKey: !Ref NubevaDecryptorAccessKey
                  SecretKey: !GetAtt NubevaDecryptorAccessKey.SecretAccessKey
        SSLdbWriteAuth: !Join
          - ''
          - - Fn::Base64: !Sub
                - '{"type":"ddb","domain":"${Domain}","region":"${Region}","ak":"${AccessKey}","sk":"${SecretKey}"}'
                - Domain: !Ref NubevaDDBTable
                  Region: !Ref AWS::Region
                  AccessKey: !Ref NubevaSensorAccessKey
                  SecretKey: !GetAtt NubevaSensorAccessKey.SecretAccessKey
  NubevaDDBTable:
    Type: AWS::DynamoDB::Table
    Properties:
      AttributeDefinitions:
        - AttributeName: "clientrandom"
          AttributeType: "S"
      KeySchema:
        - AttributeName: "clientrandom"
          KeyType: "HASH"
      BillingMode: PAY_PER_REQUEST
  NubevaSKIAdministrator:
    Type: AWS::IAM::Group
    Properties :
      GroupName: !Join
        - '-'
        - - 'NubevaSKIAdmin'
          - !Ref AWS::StackName
  NubevaSKISensorUser:
    Type: AWS::IAM::User
    Properties:
      UserName: !Join
        - '-'
        - - 'NuAgent'
          - !Ref AWS::StackName
      Path: "/"
  NubevaSKIDecryptorUser:
    Type: AWS::IAM::User
    Properties:
      UserName: !Join
        - '-'
        - - 'NuRx'
          - !Ref AWS::StackName
      Path: "/"
  NubevaSensorAccessKey:
    Type: AWS::IAM::AccessKey
    Properties:
      UserName:
        !Ref NubevaSKISensorUser
  NubevaDecryptorAccessKey:
    Type: AWS::IAM::AccessKey
    Properties:
      UserName:
        !Ref NubevaSKIDecryptorUser
  NubevaKeyWriter:
    Type: AWS::IAM::Policy
    Properties:
      Users:
        - !Ref NubevaSKISensorUser
      PolicyName: !Join
        - '-'
        - - 'NuKeyWriter'
          - !Ref AWS::StackName
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          -
            Effect: "Allow"
            Action:
              - "dynamodb:PutItem"
              - "dynamodb:BatchWriteItem"
            Resource: !GetAtt NubevaDDBTable.Arn
  NubevaKeyReader:
    Type: AWS::IAM::Policy
    Properties:
      Users:
        - !Ref NubevaSKIDecryptorUser
      PolicyName: !Join
        - '-'
        - - 'NuKeyReader'
          - !Ref AWS::StackName
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          -
            Effect: "Allow"
            Action:
              - "dynamodb:GetItem"
              - "dynamodb:BatchGetItem"
            Resource: !GetAtt NubevaDDBTable.Arn
  NubevaKeyAdmin:
    Type: AWS::IAM::Policy
    Properties:
      Groups:
        - !Ref NubevaSKIAdministrator
#      PolicyName: "NuKeyAdmin"
      PolicyName: !Join
        - '-'
        - - 'NuKeyAdmin'
          - !Ref AWS::StackName
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Action:
              - dynamodb:BatchGetItem
              - dynamodb:BatchWriteItem
              - dynamodb:ConditionCheckItem
              - dynamodb:CreateBackup
              - dynamodb:CreateGlobalTable
              - dynamodb:CreateTable
              - dynamodb:CreateTableReplica
              - dynamodb:DeleteBackup
              - dynamodb:DeleteItem
              - dynamodb:DeleteTable
              - dynamodb:DeleteTableReplica
              - dynamodb:DescribeBackup
              - dynamodb:DescribeContinuousBackups
              - dynamodb:DescribeContributorInsights
              - dynamodb:DescribeExport
              - dynamodb:DescribeGlobalTable
              - dynamodb:DescribeGlobalTableSettings
              - dynamodb:DescribeKinesisStreamingDestination
              - dynamodb:DescribeLimits
              - dynamodb:DescribeReservedCapacity
              - dynamodb:DescribeReservedCapacityOfferings
              - dynamodb:DescribeStream
              - dynamodb:DescribeTable
              - dynamodb:DescribeTableReplicaAutoScaling
              - dynamodb:DescribeTimeToLive
              - dynamodb:DisableKinesisStreamingDestination
              - dynamodb:EnableKinesisStreamingDestination
              - dynamodb:ExportTableToPointInTime
              - dynamodb:GetItem
              - dynamodb:GetRecords
              - dynamodb:GetShardIterator
              - dynamodb:ListBackups
              - dynamodb:ListContributorInsights
              - dynamodb:ListExports
              - dynamodb:ListGlobalTables
              - dynamodb:ListStreams
              - dynamodb:ListTables
              - dynamodb:ListTagsOfResource
              - dynamodb:PartiQLDelete
              - dynamodb:PartiQLInsert
              - dynamodb:PartiQLSelect
              - dynamodb:PartiQLUpdate
              - dynamodb:PurchaseReservedCapacityOfferings
              - dynamodb:PutItem
              - dynamodb:Query
              - dynamodb:RestoreTableFromBackup
              - dynamodb:RestoreTableToPointInTime
              - dynamodb:Scan
              - dynamodb:TagResource
              - dynamodb:UntagResource
              - dynamodb:UpdateContinuousBackups
              - dynamodb:UpdateContributorInsights
              - dynamodb:UpdateGlobalTable
              - dynamodb:UpdateGlobalTableSettings
              - dynamodb:UpdateItem
              - dynamodb:UpdateTable
              - dynamodb:UpdateTableReplicaAutoScaling
              - dynamodb:UpdateTimeToLive
            Resource: !GetAtt NubevaDDBTable.Arn