npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@enfo/cdk-webacl

v0.0.3

Published

Opinionated wrapper around CDK L1 Construct WebAcl

Downloads

4

Readme

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' } }
})