@enfo/cdk-webacl
TypeScript icon, indicating that this package has built-in type declarations

0.0.3 • Public • Published

Introduction

This package exposes an opinionated Construct for setting up an AWS WebAcl using the CDK. Five custom rules are ready to be enabled. If you are not using the custom rules this package will not bring you much value.

Installation

Install the package by running

npm install @enfo/cdk-webacl

Getting started

Quick start

This is example is the least amount of configuration you have to do in order for the WebAcl to be created

import { WebAcl, Scope } from '@enfo/cdk-webacl'
import { Stack } from 'aws-cdk-lib'
import { RestApi } from 'aws-cdk-lib/aws-apigateway'
import { CfnWebACLAssociation } from 'aws-cdk-lib/aws-wafv2'
import { Distribution } from 'aws-cdk-lib/aws-cloudfront'

const stack = new Stack()
const webacl = new WebAcl(stack, 'MyWebAcl', {
  scope: Scope.REGIONAL,
  metricName: 'my-metric',
  defaultAction: {
    allow: {}
  }
})
  .enableIpBlockRule()
  .enableRateLimitRule()
  .enableIpReputationRule()
  .enableManagedCoreRule()
  .enableBadInputsRule()

// associating it with an API
const api = new RestApi(stack, 'Api')
api.root.addMethod('GET')
new CfnWebACLAssociation(this, 'ApiAssociation', {
  webAclArn: webacl.attrArn,
  resourceArn: `arn:aws:apigateway:${Stack.of(stack).region}::/restapis/${api.deploymentStage.restApi.restApiId}/stages/${api.deploymentStage.stageName}`
});

// associating it with a CloudFront Distribution
new Distribution(stack, 'Distribution', {
  webAclId: webacl.attrArn,
  // more properties
})

Configuration options

The WebAcl and all rules can be configured.

WebAcl configuration

The WebAcl Construct takes an object with the interface WebAclProps which supports all properties from CfnWebAclProps except:

  • scope, this has been replaced with an enum instead of a string
  • visibilityConfig, this has been removed and its properties flattened into WebAclProps. Only metricName is mandatory

Example of unique configuration options unique to WebAcl:

new WebAcl(stack, 'MyWebAcl', {
  scope: Scope.CLOUDFRONT,
  metricName: 'my-metric',
  cloudWatchMetricsEnabled: true,
  sampledRequestsEnabled: true,
  defaultAction: { // not unique but must be included
    allow: {}
  }
})

Rules configurations

You can only enable a rule ONCE. Attempting to enable a rule twice will result in an Error being thrown.

All rules share the same base interface. The following properties have been modified from CfnWebACL.RuleProperty:

  • name, no longer mandatory, has a rule specific default
  • priority, no longer mandatory, has a rule specific default
  • statement, removed and some properties flattered into rule properties for rules using AWS Managed Rule Groups ( IP Reputation, Managed Core and Bad Inputs)
  • visibilityConfig, removed and properties flatted into rule properties
  • action, removed from all rules but IP Block
  • overrideAction, set to { none: {} } on all rules but IP Block

enableIpBlockRule configuration

You can read about IP set rules here. The IP Block rule supports more properties than other rules. These have been grabbed from CfnIPSetProps, some have been replaced, others removed:

  • ipSetName, name you want for the IP Set
  • ipSetDescription, description you want for the IP Set
  • addresses, no longer mandatory
  • ipAddressVersion, replaced with enum instead of a string
  • ipSetTags

Example of enableIpBlockRule options:

new WebAcl(...)
.enableIpBlockRule({
  name: 'cool-name', // default 'ip-block'
  priority: 1, // default 10
  metricName: 'something', // default 'ip-block'
  cloudWatchMetricsEnabled: true,
  sampledRequestsEnabled: true,
  action: {
    allow: {}
  }
})

Customizing the IP Set:

new WebAcl(stack, 'WebAcl', {
  scope: Scope.REGIONAL,
  metricName: 'something',
  defaultAction: {
    allow: {}
  }
})
  .enableIpBlockRule({
    ipSetName: 'my-set',
    ipSetDescription: 'desc',
    addresses: ['2001:0db8:85a3:0000:0000:8a2e:0370:7334'],
    ipAddressVersion: IpAddressVersion.IPV6,
    ipSetTags: [
      {
        key: 'key!',
        value: 'value!'
      }
    ]
  })

You can also supply your own IP Set:

const ipSet = new CfnIPSet(stack, 'MySet', {
  scope: 'REGIONAL',
  name: 'my-set',
  addresses: [],
  ipAddressVersion: 'IPV4'
})

new WebAcl(stack, 'WebAcl', {
  scope: Scope.REGIONAL,
  metricName: 'something',
  defaultAction: {
    allow: {}
  }
})
  .enableIpBlockRule({
    ipSet
  })

If an IP Set is supplied WebAcl will not create one

enableRateLimitRule configuration

You can read about rate limit rules here. The Rate Limit rule supports one property extra than the other rules:

  • rateLimit, defaults to 1000

Example of options:

new WebAcl(...)
.enableRateLimitRule({
  name: 'cool-name', // default 'rate-limit'
  priority: 1, // default 20
  metricName: 'something', // default 'rate-limit'
  rateLimit: 1337,
  cloudWatchMetricsEnabled: true,
  sampledRequestsEnabled: true
})

enableIpReputationRule configuration

You can read about IP reputation rules here. Example of enableIpReputationRule options:

new WebAcl(...)
.enableIpReputationRule({
  name: 'cool-name', // default 'ip-reputation'
  priority: 1, // default 30
  metricName: 'something', // default 'ip-reputation'
  cloudWatchMetricsEnabled: true,
  sampledRequestsEnabled: true,
  excludedRules: [{ name: 'wow' }],
  managedRuleGroupConfigs: [{ loginPath: 'login!' }],
  scopeDownStatement: { managedRuleGroupStatement: { vendorName: 'Enfo', name: 'NotReals' } }
})

enableManagedCoreRule configuration

You can read about the AWS core rules here. Example of enableManagedCoreRule options:

new WebAcl(...)
.enableManagedCoreRule({
  name: 'cool-name', // default 'managed-core'
  priority: 1, // default 40
  metricName: 'something', // default 'managed-core'
  cloudWatchMetricsEnabled: true,
  sampledRequestsEnabled: true,
  excludedRules: [{ name: 'wow' }],
  managedRuleGroupConfigs: [{ loginPath: 'login!' }],
  scopeDownStatement: { managedRuleGroupStatement: { vendorName: 'Enfo', name: 'NotReals' } }
})

enableBadInputsRule configuration

You can read about the AWS bad inputs rules here. Example of enableBadInputsRule options:

new WebAcl(...)
.enableBadInputsRule({
  name: 'cool-name', // default 'bad-inputs'
  priority: 1, // default 50
  metricName: 'something', // default 'bad-inputs'
  cloudWatchMetricsEnabled: true,
  sampledRequestsEnabled: true,
  excludedRules: [{ name: 'wow' }],
  managedRuleGroupConfigs: [{ loginPath: 'login!' }],
  scopeDownStatement: { managedRuleGroupStatement: { vendorName: 'Enfo', name: 'NotReals' } }
})

Readme

Keywords

Package Sidebar

Install

npm i @enfo/cdk-webacl

Weekly Downloads

6

Version

0.0.3

License

MIT

Unpacked Size

253 kB

Total Files

13

Last publish

Collaborators

  • castodius
  • enfogroup