Apply WAF Web ACL to API Gateway
AWS WAF can be applied to the following four types of resources
- ALB
- CloudFront
- API Gateway
- AppSync
In this article, we will check how to apply WAF to API Gateway.
For details on how to apply WAF to ALB, please refer to the following page.
For information on how to apply WAF to CloudFront, please refer to the following page.
For information on how to apply WAF to AppSync, please see the following page.
Environment
Restrict geography.
Specifically, create your own rule group and set a rule to block access from Japan (JP) in it.
Apply the created Web ACL to the API Gateway.
Create an API Gateway and deploy Lambda on the backend.
When an HTTP request is received from a user, the API Gateway acts as an endpoint and invokes a Lambda function instead, returning the result of the function’s invocation to the user.
The API Gateway is created as a REST API type.
The runtime environment for the Lambda function is Python 3.8.
The action of the function is simply to return the string “Hello form Awstut ! when executed.
CloudFormation template files
The above configuration is built using CloudFormation.
The CloudFormation templates are located at the following URL
https://github.com/awstut-an-r/awstut-fa/tree/main/053
Explanation of key points of the template files
This page focuses on how to apply WAF to CloudFront.
For basic information on WAF, please refer to the following page
For information on how to restrict geography with WAF, please refer to the following page
For basic information on REST API type API Gateway, please refer to the following page
(Reference) REST API type API Gateway resources
As mentioned in the following AWS official website, the type of API Gateway to which WAF can be applied is the REST API type.
https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-vs-rest.html
Resources:
RestApi:
Type: AWS::ApiGateway::RestApi
Properties:
EndpointConfiguration:
Types:
- EDGE
Name: !Ref Prefix
Deployment:
Type: AWS::ApiGateway::Deployment
DependsOn:
- Method
Properties:
RestApiId: !Ref RestApi
Resource:
Type: AWS::ApiGateway::Resource
Properties:
ParentId: !GetAtt RestApi.RootResourceId
PathPart: !Sub "${Prefix}-resource"
RestApiId: !Ref RestApi
Stage:
Type: AWS::ApiGateway::Stage
Properties:
DeploymentId: !Ref Deployment
RestApiId: !Ref RestApi
StageName: !Sub "${Prefix}-stage"
Method:
Type: AWS::ApiGateway::Method
Properties:
AuthorizationType: NONE
HttpMethod: GET
Integration:
ConnectionType: INTERNET
Credentials: !GetAtt ApiGatewayRole.Arn
IntegrationHttpMethod: POST
Type: AWS_PROXY
Uri: !Sub "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${FunctionArn}/invocations"
ResourceId: !Ref Resource
RestApiId: !Ref RestApi
Code language: YAML (yaml)
No special configuration is required.
In the resource definition, set part of the URL PATH to “fa-053-resource”.
In the stage definition, set the stage name to “fa-053-stage”.
Web ACL
Resources:
WebACL:
Type: AWS::WAFv2::WebACL
Properties:
DefaultAction:
Allow: {}
Name: !Sub "${Prefix}-WebACL"
Rules:
- Name: !Sub "${Prefix}-WebACL-GeoRestriction"
OverrideAction:
None: {}
Priority: 0
Statement:
RuleGroupReferenceStatement:
Arn: !GetAtt RuleGroup.Arn
VisibilityConfig:
CloudWatchMetricsEnabled: true
MetricName: !Sub "${Prefix}-WebACL-GeoRestriction"
SampledRequestsEnabled: true
Scope: REGIONAL
VisibilityConfig:
CloudWatchMetricsEnabled: true
MetricName: !Ref Prefix
SampledRequestsEnabled: true
Code language: YAML (yaml)
The Scope property is the key.
If the Web ACL is applied to CloudFront, it is “CLOUDFRONT”; for other resources, it is “REGIONAL”.
In this case, since this is an API Gateway, the latter is used.
Resources:
WebACLAssociation:
Type: AWS::WAFv2::WebACLAssociation
Properties:
ResourceArn: !Sub "arn:aws:apigateway:${AWS::Region}::/restapis/${RestApi}/stages/${StageName}"
WebACLArn: !GetAtt WebACL.Arn
Code language: YAML (yaml)
Resource for applying WAF to API Gateway.
In the ResourceArn property, specify the API Gateway to which WAF is to be applied.
The following is a description of how to specify the WAF
For an Amazon API Gateway REST API: arn:aws:apigateway:region::/restapis/api-id/stages/stage-name
AWS::WAFv2::WebACLAssociation
So to meet the above requirements, we use the built-in function Fn::Sub to embed and configure the API’s ID and stage name.
Architecting
Use CloudFormation to build this environment and check the actual behavior.
Create CloudFormation stacks and check resources in stacks
Create a CloudFormation stacks.
For information on how to create stacks and check each stack, please refer to the following page
After checking the resources in each stack, information on the main resources created this time is as follows
- API Gateway name: fa-053
- API Gateway endpoint: https://dv68zdrmge.execute-api.ap-northeast-1.amazonaws.com/
- API Gateway stage name: fa-053-stage
- API Gateway resource name: fa-053-resource
- WAF name: fa-053-WebACL
We will also check the resource from the AWS Management Console.
First, check the API Gateway.
If you see the stage page, you will see that WAF is applied.
Next, check the Web ACL.
From the Web ACL side, you can also see that this ACL is applied to API Gateway.
Checking Action
Now that everything is ready, access CloudFront from Japan.
The URL to be accessed this time is determined by a combination of resource and stage information.
Specifically, the URL is as follows
https://dv68zdrmge.execute-api.ap-northeast-1.amazonaws.com/fa-053-stage/fa-053-resource/
Access denied.
Because you accessed it from Japan, it means that it was blocked by the WAF Web ACL before reaching the API Gateway.
To confirm, change the action of the geo-restriction.
We changed the rule action from blocking to counting, i.e., keeping the rule alive but only counting the number of traffic that corresponds to the rule.
Access the API Gateway again.
The API Gateway is now accessible.
This is because the rule action has been changed from blocking to counting only, and access is now possible.
Summary
We have confirmed how to apply WAF ACLs to API Gateway.