1.3.3 • Published 1 month ago

cdk-aws-wafv2-geofence-lib v1.3.3

Weekly downloads
-
License
Apache-2.0
Repository
github
Last release
1 month ago

npm GitHub last commit (branch) GitHub issues

AWS WAFv2 cdk construct for Cloud Development Kit (AWS CDK)

The WAFv2 construct is free for everyone to use and it leverages the massive improvements made by AWS compared to V1.

Add an extra layer of security to protect your services from common attacks

It offers a high-level abstraction and integrates neatly with your existing AWS CDK project. It brings AWS best practices into your infrastructure and hides boilerplate logic in your project.

Features

Experimental

  • ChatGPT IP blocking engine. IP Block list is maintained by ChatGPT evaluation.
  • Support for Slack notifications

Notifications If ChatGPT functionality is enabled, you can also pass a sns_topic to the construct. This will enable ChatGPT block notifications to Slack. Use our integration example to get going from: https://github.com/ZDF-OSS/aws-slack-notifications after you have deployed the stack, you get the sns topic and pass it to the construct (snsNotificationArn).

dashboard

The Construct is available in the following languages:

Third-party Language Deprecation: language version is only supported until its EOL (End Of Life) shared by the vendor or community and is subject to change with prior notice.

architecture

Dashbord

dashboard

AWS Managed Rules AWS Managed Rules for AWS WAF is a managed service that provides protection against common application vulnerabilities or other unwanted traffic. You have the option of selecting one or more rule groups from AWS Managed Rules for each web ACL, up to the maximum web ACL capacity unit (WCU) limit.

\ Jump To: Getting Started Getting Help Contributing Roadmap More Resources


Logging

Enabled logging sends all information to the CloudWatch LogGroup.


TL;TR;

Use our construct by installing the module and using our construct in your code:

npm install -g aws-cdk
npm install aws-cdk-lib 
npm install cdk-aws-wafv2-geofence-lib

allowedCountiesToAccessService expects an array of two-character country codes that you want to match against, for example, "US", "CN" , from the alpha-2 country ISO codes of the ISO 3166 international standard.

When you use a geo match statement just for the region and country labels that it adds to requests, you still have to supply a country code for the rule to evaluate. In this case, you configure the rule to only count matching requests, but it will still generate logging and count metrics for any matches. You can reduce the logging and metrics that the rule produces by specifying a country that's unlikely to be a source of traffic to your site. (https://docs.aws.amazon.com/waf/latest/APIReference/API_GeoMatchStatement.html)

  import { CdkWafGeoLib } from 'cdk-aws-wafv2-geofence-lib'
   // AWS WAFv2 GeoBlocking CDK Component
    const allowedCountiesToAccessService = ["DE"]
    new CdkWafGeoLib(this, 'Cdk-Waf-Geo-Lib', {
      // Geo blocking
      allowedCountiesToAccessService: ['DE'],
      enableGeoBlocking: false,

      resourceArn: lb.loadBalancerArn,
      priority: 233,

      // Cloud watch logs need to be enabled, if you want Dashboards and if you want to try the ChatGPT exp feature.
      enableCloudWatchLogs: true,

      // AWS Default WAF Rules
      enableAWSManagedRulesBlocking: true,
      // There are more AWS Managed rules to enable availible...
      enableAWSManagedRuleCRS: true,

      //ChatGPT blocking switch - dont forget to set the API Key in Secrets Manager after provisioning.// Get your API key from https://platform.openai.com/account/api-keys
      enableChatGPTBlocking: true,
      //Deploys the ChatGPT looging infrastructure. Dont toggle it of, if you want to keep your data.
      deployChatGPTBlocking: true,

      //If using ChatGPT - you can also enable notifications too. Feel free to use our cdk example on how to implement Slack Notifications. https://github.com/ZDF-OSS/aws-slack-notifications
      snsNotificationArn: 'arn:aws:sns:eu-central-1:326941568664:notifications-to-channel',
    });

Properties

NameTypeDescription
allowedCountiesToAccessServicestring[]Allowed countries to access the backend - for example DE, EN, DK.
deployChatGPTBlockingbooleanSwitch to control if the rule should let ChatGPT block or count incomming requests.
enableAWSManagedRulesBlockingbooleanSwitch to control if the rule should block or count incomming requests hitting the AWS Manged Rules.
enableChatGPTBlockingbooleanDeploy ChatGPT blocking infrastructure e.g. DynamoDB, Lambdas, CW Rules.
enableGeoBlockingbooleanSwitch to control if the rule should block or count incomming requests.
prioritynumberPriority of the WAFv2 rule.
resourceArnstringArn of the ressource to protect.
blockbooleanDeprecated: - use enableGeoBlocking Switch to control if the rule should block or count incomming requests.
cloudWatchLogGroupNamestringName of the CloudWatch LogGroup where requests are stored.
enableAWSManagedRuleCRSbooleanThe Core rule set (CRS) rule group contains rules that are generally applicable to web applications.
enableAWSMangedRuleAdminProtectbooleanThe Admin protection rule group contains rules that allow you to block external access to exposed administrative pages.
enableAWSMangedRuleAnonIPbooleanThe Anonymous IP list rule group contains rules to block requests from services that permit the obfuscation of viewer identity.
enableAWSMangedRuleIPRepbooleanThe Amazon IP reputation list rule group contains rules that are based on Amazon internal threat intelligence.
enableAWSMangedRuleKBIbooleanThe Known bad inputs rule group contains rules to block request patterns that are known to be invalid and are associated with exploitation or discovery of vulnerabilities.
enableAWSMangedRuleLinuxProtectbooleanThe Linux operating system rule group contains rules that block request patterns associated with the exploitation of vulnerabilities specific to Linux, including Linux-specific Local File Inclusion (LFI) attacks.
enableAWSMangedRulePHPProtectbooleanThe PHP application rule group contains rules that block request patterns associated with the exploitation of vulnerabilities specific to the use of the PHP programming language, including injection of unsafe PHP functions.
enableAWSMangedRuleSQLibooleanThe SQL database rule group contains rules to block request patterns associated with exploitation of SQL databases, like SQL injection attacks.
enableAWSMangedRuleUnixProtectbooleanThe POSIX operating system rule group contains rules that block request patterns associated with the exploitation of vulnerabilities specific to POSIX and POSIX-like operating systems, including Local File Inclusion (LFI) attacks.
enableAWSMangedRuleWindowsProtectbooleanThe Windows operating system rule group contains rules that block request patterns associated with the exploitation of vulnerabilities specific to Windows, like remote execution of PowerShell commands.
enableAWSMangedRuleWorkpressProtectbooleanThe WordPress application rule group contains rules that block request patterns associated with the exploitation of vulnerabilities specific to WordPress sites.
enableCloudWatchLogsbooleanSends logs to a CloudWatch LogGroup with a retention on it.
retentionDaysaws-cdk-lib.aws_logs.RetentionDaysRetention period to keep logs.

Getting Started

Install or update the AWS CDK CLI from npm (requires Node.js ≥ 14.15.0). We recommend using a version in Active LTS and then install the component

npm install -g aws-cdk
npm install aws-cdk-lib   

Initialize a project with our component:

mkdir hello-cdk
cd hello-cdk
cdk init sample-app --language=typescript
npm install cdk-aws-wafv2-geofence-lib

This creates a sample project - replace the sample code with:

import * as path from 'path';
import * as cdk from 'aws-cdk-lib';
import { Platform } from 'aws-cdk-lib/aws-ecr-assets';
import { Construct } from 'constructs';
import { CdkWafGeoLib } from './index';

export class EcsBpMicroserviceWaf extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    const product = 'integ';


    const vpc = new cdk.aws_ec2.Vpc(this, 'integ-vpc', {
      ipAddresses: cdk.aws_ec2.IpAddresses.cidr('10.0.0.0/16'),
      maxAzs: 2,
    });

    const cluster = new cdk.aws_ecs.Cluster(this, 'integ-ecs-cluster', {
      clusterName: 'integ-ecs-cluster',
      vpc: vpc,
    });

    const task = new cdk.aws_ecs.FargateTaskDefinition(this, 'integ-td', {
      memoryLimitMiB: 512,
      cpu: 256,
      runtimePlatform: {
        operatingSystemFamily: cdk.aws_ecs.OperatingSystemFamily.LINUX,
        cpuArchitecture: cdk.aws_ecs.CpuArchitecture.ARM64,
      },
    });

    const imageAsset = new cdk.aws_ecr_assets.DockerImageAsset(
      this,
      'integ-image',
      {
        directory: path.join(__dirname, '../src/backend'),
        platform: Platform.LINUX_ARM64,
      },
    );

    const image = cdk.aws_ecs.ContainerImage.fromDockerImageAsset(imageAsset);
    task.addContainer('integ-container', {
      containerName: `${product}`,
      image,
      portMappings: [{ containerPort: 80 }],
      logging: cdk.aws_ecs.LogDriver.awsLogs({
        streamPrefix: `${product}`,
      }),
    });

    const sg = new cdk.aws_ec2.SecurityGroup(this, 'integ-sg', {
      vpc,
      allowAllOutbound: true,
    });
    sg.addIngressRule(
      cdk.aws_ec2.Peer.anyIpv4(),
      cdk.aws_ec2.Port.tcp(808),
      'Allowing traffic to the backend',
    );

    const service = new cdk.aws_ecs.FargateService(this, 'integ-service', {
      cluster,
      serviceName: `${product}-service`,
      taskDefinition: task,
      securityGroups: [sg],
      desiredCount: 1,
      assignPublicIp: false,
    });

    const lb = new cdk.aws_elasticloadbalancingv2.ApplicationLoadBalancer(
      this,
      'integ-lb',
      {
        vpc,
        internetFacing: true,
        loadBalancerName: 'integ-lb',
      },
    );

    const listener = lb.addListener('integ-listener', {
      port: 808,
      protocol: cdk.aws_elasticloadbalancingv2.ApplicationProtocol.HTTP,
    });

    const tg = listener.addTargets('integ-targets', {
      port: 80,
      protocol: cdk.aws_elasticloadbalancingv2.ApplicationProtocol.HTTP,
      targets: [service],
      deregistrationDelay: cdk.Duration.seconds(1),
      targetGroupName: `${product}-targets`,
    });

    const scaling = service.autoScaleTaskCount({ maxCapacity: 10 });
    scaling.scaleOnRequestCount('RequestScaling', {
      requestsPerTarget: 500,
      targetGroup: tg,
    });
    
    new CdkWafGeoLib(this, 'Cdk-Waf-Geo-Lib', {
      // Geo blocking
      allowedCountiesToAccessService: ['DE'],
      enableGeoBlocking: false,
      resourceArn: lb.loadBalancerArn,
      priority: 100,
      enableCloudWatchLogs: true,
      // AWS Default WAF Rules
      enableAWSManagedRulesBlocking: true,
      enableAWSManagedRuleCRS: true,
      //ChatGPT
      enableChatGPTBlocking: true,
      deployChatGPTBlocking: true,
      //If using ChatGPT - you can also enable notifications too. Feel free to use our cdk example on how to implement Slack Notifications. https://github.com/ZDF-OSS/aws-slack-notifications
      snsNotificationArn: 'arn:aws:sns:eu-central-1:326941568664:notifications-to-channel',
    });
  }
}

Integration Testing

The integrations test deploys the solution with a microservice and a loadbalancer. The microservice runs inside an ecs cluster.

Deploy the solution for testing

cdk --app='./lib/integ.default.js' deploy

Destroy the solution

cdk --app='./lib/integ.default.js' destroy

Getting Help

The best way to interact with our team is through GitHub or mail. You can open an issue and choose from one of our templates for bug reports, feature requests, documentation issues.

Roadmap

The project board lets developers know about our upcoming features and priorities to help them plan how to best leverage our construct Roadmap

Contributing

We welcome community contributions and pull requests.

More Resources

1.3.3

1 month ago

1.3.2

2 months ago

1.3.1

2 months ago

1.3.0

2 months ago

1.2.0

10 months ago

1.2.8

10 months ago

1.2.7

10 months ago

1.2.6

10 months ago

1.2.5

10 months ago

1.2.4

10 months ago

1.2.3

10 months ago

1.2.2

10 months ago

1.2.1

10 months ago

1.2.9

9 months ago

1.2.10

8 months ago

1.1.1

10 months ago

1.0.2

10 months ago

1.1.0

10 months ago

1.0.4

10 months ago

1.1.2

10 months ago

1.0.3

10 months ago

1.0.1

10 months ago

1.0.0

11 months ago

0.0.9

11 months ago

0.0.8

11 months ago

0.0.5

11 months ago

0.0.7

11 months ago

0.0.6

11 months ago

0.0.4

11 months ago

0.0.3

11 months ago

0.0.2

11 months ago

0.0.1

11 months ago

0.0.0

11 months ago