CyberKeeda In Social Media
Showing posts with label AWS WAF. Show all posts
Showing posts with label AWS WAF. Show all posts

AWS WAF : Web Access Firewall to control access to CloudFront Public domain URL using IPset Rules.

 

AWS WAFv2

AWS Web Access Firewall is one the services that can be used to inspect, control and manage web request.
WAF uses one or many rules to allow, limit or block as per request statement provided within rule.
AWS WAF and it's corresponding rule can be attached to multiple AWS services. such as
Official AWS Link
  • Amazon CloudFront distribution, 
  • Amazon API Gateway REST API, 
  • Application Load Balancer,
  • AWS API Gateway
In this blog post,, we will cover, how to restrict our AWS cloudfront distribution URL for limited IP Addresses only.

Lab Setup : So we have a Cloudfront distribution with both http and https access mapped to respective AWS S3 buckets, as we know once we have created a Cloudfront distribution, AWS provide us a publicly accessible Cloudfront domain URL, using which we can access our S3 content, thus url, which looks somehow similar to http://d3ocffr25e-somerandom.cloudfront.ne

We will use AWS WAF to restrict/block access approaching to our Cloudfront domain to all random IP other than the one which we have whitelisted within our IP sets.

CloudFormation Template to create below resources.
  • IP Sets : AWS::WAFv2::IPSet
  • Web ACLv2 : AWS::WAFv2::WebACL
  • Custom Response Body : CustomResponseBodies
  • Rules : IPSetReferenceStatement
  • CloudWatch Metrics
  • Sample Request Dashboard.

Note : After creation of below resources, this has to be associated with cloudformation distribution from cloudfromation section.

Syntax Template

---
AWSTemplateFormatVersion'2010-09-09'
DescriptionThis template will create WAFv2 Ipset, WebAcl with Cloudfront Scope, Web ACLs rules, Cloudwatch metric
              Sample Request Dashbaord with last 3 hour data.

Parameters:
  env:
    DescriptionThe environment name being worked on
    TypeString
    AllowedValues:
      - prod
      - non-prod
  CloudFrontInfo:
    DescriptionCloudfront Name.
    TypeString
  IPSetname:
    DescriptionThe short name to identify ipsets.
    TypeString
  IPSetDescription:
    DescriptionShort description to identify ipsets.
    TypeString

Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      -
        Label:
          defaultEnvironment
        Parameters:
          - env
      - 
        Label:
          defaultIP Set Details
        Parameters:
          - IPSetname
          - IPSetDescription

Resources:
  SampleIPSet:
      Type'AWS::WAFv2::IPSet'
      Properties:
        Description!Sub "${IPSetDescription}"
        Name!Sub "${IPSetname}"
        ScopeCLOUDFRONT
        IPAddressVersionIPV4
        Addresses:  
          - 111.11.11.11/32 # Random-Pub-IP-1
          - 122.12.12.1/32   #  Random-Pub-IP-2
          - 133.225.192.0/18  #  Random-Pub-IP-3

  CDNAccessIPRestrictionWebACL:
    TypeAWS::WAFv2::WebACL
    Properties:
      Name!Sub "myproject-${env}-cdn-${CloudFrontInfo}-WebACL"
      ScopeCLOUDFRONT
      DefaultAction:
        Block: {
      "CustomResponse": {
        "ResponseCode"401,
        "CustomResponseBodyKey""Unauthorized"
      }
    }
      Description!Sub "To limit access of Cloudfront ${CloudFrontInfo}  from known IP ranges only"
      Rules:
        - Name!Sub "myproject-${env}-cdn-${CloudFrontInfo}-WebACL-Rule1"
          Priority0
          Statement:
            IPSetReferenceStatement:
              Arn!GetAtt SampleIPSet.Arn
          Action:
            Allow: {}
          VisibilityConfig:
            SampledRequestsEnabledtrue
            CloudWatchMetricsEnabledtrue
            MetricName!Sub "myproject-${env}-cdn-${CloudFrontInfo}-IpLimitationRule"
      VisibilityConfig:
        SampledRequestsEnabledtrue
        CloudWatchMetricsEnabledtrue
        MetricName!Sub "myproject-${env}-cdn-${CloudFrontInfo}-WebACLMetric"
      Capacity1

      CustomResponseBodies:
        Unauthorized:
          ContentTypeTEXT_PLAIN
          ContentUnauthorized !

We will go through each sections of the CloudFormation template to understand the same.

MetaData and Interface MetaDataFollow the link to know more about it

Going further into the Resource Section, our WAF relevant stuffs are defined.


AWS::WAFv2::IPSet
This part of CFN resource us used to define our custom set of IP Address, which will be later used while defining our WAF rules, Let's know what are those properties.

SampleIPSet:
      Type'AWS::WAFv2::IPSet'
      Properties:
        Description!Sub "${IPSetDescription}"
        Name!Sub "${IPSetname}"
        ScopeCLOUDFRONT
        IPAddressVersionIPV4
        Addresses:  
          - 111.11.11.11/32 # Random-Pub-IP-1
          - 122.12.12.1/32   #  Random-Pub-IP-2
          - 133.225.192.0/18  #  Random-Pub-IP-3

Scope
Scope can be either REGIONAL or CLOUDFRONT
As Cloudfront (CDN) is Global service, it's being treated as a Seperate scope.
Note : Please note, this scope can be created only within us-east-1 region only.


Addresses
Used to define set of IP using the valid CIDR format.

Example :
          - 111.11.11.11/32 # Used to define single IP as /32 - 122.12.12.1/32 - 133.225.192.0/18 # Used to define entire subnet range as /18


Custom Response Body : CustomResponseBodies

This part of CFN resource us used to define our custom response that can support in any type as ( Plain TEXT, HTML, JSON ), here we have used a plain text.


      CustomResponseBodies:
        Unauthorized:
          ContentTypeTEXT_PLAIN
          ContentUnauthorized !



Rules

This part of WAF ACL CFN resource us used to custom rules (Allow, Deny )based upon statements.


  • In our example, we are allowing IP Sets with priority 0 ( Highest Priority ), and it's linked the the ARN of the same IP Set, we have created above.
  • In addition to that, we are creating Cloudwatch Metrics Dashboard for each Allowed Request.
  • And at last we are enabling the Sampled Request, which will show us the Realtime calls/request.

Rules:
        - Name!Sub "myproject-${env}-cdn-${CloudFrontInfo}-WebACL-Rule1"
          Priority0
          Statement:
            IPSetReferenceStatement:
              Arn!GetAtt SampleIPSet.Arn
          Action:
            Allow: {}
          VisibilityConfig:
            SampledRequestsEnabledtrue
            CloudWatchMetricsEnabledtrue
            MetricName!Sub "myproject-${env}-cdn-${CloudFrontInfo}-IpLimitationRule"


Web ACLv2 : AWS::WAFv2::WebACL
This part of CFN resource us used to define the WAFv2 ACl and it defines the below parts.
  • It has scope of CloudFront.
  • Default action is to Block everything and thus in response provide HTTP access code 401 and with the custom response body that we have created above part.
  • It will create a Cloudwatch metric dashboard for all blocked request.
  • It will also create a panel for all realtime blocked request/calls.

 CDNAccessIPRestrictionWebACL:
    TypeAWS::WAFv2::WebACL
    Properties:
      Name!Sub "myproject-${env}-cdn-${CloudFrontInfo}-WebACL"
      ScopeCLOUDFRONT
      DefaultAction:
        Block: {
      "CustomResponse": {
        "ResponseCode"401,
        "CustomResponseBodyKey""Unauthorized"
      }
    }
      Description!Sub "To limit access of Cloudfront ${CloudFrontInfo}  from known IP ranges only"
      Rules:
        - Name!Sub "myproject-${env}-cdn-${CloudFrontInfo}-WebACL-Rule1"
          Priority0
          Statement:
            IPSetReferenceStatement:
              Arn!GetAtt SampleIPSet.Arn
          Action:
            Allow: {}
          VisibilityConfig:
            SampledRequestsEnabledtrue
            CloudWatchMetricsEnabledtrue
            MetricName!Sub "myproject-${env}-cdn-${CloudFrontInfo}-IpLimitationRule"
      VisibilityConfig:
        SampledRequestsEnabledtrue
        CloudWatchMetricsEnabledtrue
        MetricName!Sub "myproject-${env}-cdn-${CloudFrontInfo}-WebACLMetric"
      Capacity1

  • This part creates the AWS WAFv2 w


Read more ...
Designed By Jackuna