Monday, March 22, 2021

Create AWS WebACL for CloudFront


 



NOTICE:
New AWS SDK was published.
You better use it instead of the one specified in the post.
For more details, see here.




In this post we will use AWS Go API to create a WebACL, and then we will associate it with a CloudFront distribution.

Before starting, make sure to setup credentials and region as specified in this post.


We will start by creating an example of WebACL rule to block any request with query string that have a specific suffix.


awsSession, err := session.NewSession(&aws.Config{
Region: aws.String("us-east-1"),
})
wafClient := wafv2.New(awsSession)
if err != nil {
panic(err)
}

statement := wafv2.Statement{
ByteMatchStatement: &wafv2.ByteMatchStatement{
FieldToMatch: &wafv2.FieldToMatch{
QueryString: &wafv2.QueryString{},
},
PositionalConstraint: aws.String("ENDS_WITH"),
SearchString: []byte("/3"),
TextTransformations: []*wafv2.TextTransformation{
{
Priority: aws.Int64(1),
Type: aws.String("NONE"),
},
},
},
}

rule := wafv2.Rule{
Name: aws.String("rule-1"),
Priority: aws.Int64(1),
Action: &wafv2.RuleAction{
Block: &wafv2.BlockAction{},
},
Statement: &statement,
VisibilityConfig: &wafv2.VisibilityConfig{
CloudWatchMetricsEnabled: aws.Bool(false),
SampledRequestsEnabled: aws.Bool(false),
MetricName: aws.String("my-rule-metric"),
},
}

aclInput := wafv2.CreateWebACLInput{
DefaultAction: &wafv2.DefaultAction{
Block: &wafv2.BlockAction{},
},
Name: aws.String("my-webacl"),
Rules: []*wafv2.Rule{&rule},
Scope: aws.String("CLOUDFRONT"),
VisibilityConfig: &wafv2.VisibilityConfig{
CloudWatchMetricsEnabled: aws.Bool(false),
SampledRequestsEnabled: aws.Bool(false),
MetricName: aws.String("my-rule-metric"),
},
}

acl, err := wafClient.CreateWebACL(&aclInput)
if err != nil {
panic(err)
}


Next we can update the CloudFront distribution to use this WebACL.

Notice that you cannot use the WebACL API to associate the WebACL to the CloudFront distribution (why? ask AWS team. I guess they did not want to make it easy).


getConfigInput := cloudfront.GetDistributionConfigInput{
Id: aws.String("E1Y55CUPVONMHF"),
}
cloudFrontClient := cloudfront.New(awsSession)

distributionConfigOutput, err := cloudFrontClient.GetDistributionConfig(&getConfigInput)
if err != nil {
panic(err)
}

distributionInput := cloudfront.UpdateDistributionInput{
DistributionConfig: distributionConfigOutput.DistributionConfig,
Id: aws.String("E1Y55CUPVONMHF"),
IfMatch: distributionConfigOutput.ETag,
}
distributionInput.DistributionConfig.WebACLId = acl.Summary.Id

_, err = cloudFrontClient.UpdateDistribution(&distributionInput)
if err != nil {
panic(err)
}



That's it, we have a WebACL assigned to our CloudFront distribution.



Final Notes


I've added this post, since there are just no good examples of how to do this.

I hope you will find this useful.






No comments:

Post a Comment