In this lab, we will learn how to block traffic through WAF.
- API Gateway – REST API
- Route: GET /greet
- Lambda – Function
- Return the greeting message
- Python
- WAF
- Set up the rate-based rule
- Link to the API
1. Lambda – Create a Function
- Function Name: “SayHello“
- Runtime: Python 3.9
2. Lambda Function Code – Python
- Type the following code
- Click “Deploy“
import json
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def lambda_handler(event, context):
response = {
'message': 'Hello from Lambda!'
}
return response
3. API Gateway – Create a REST API
- REST API -> Click “Build”
- Protocol: “REST“
- Name: “Greeting“
- Endpoint Type: “Regional“
- Click “Create API“
- Resources
- Actions -> “Create Resource“
- Proxy: unchecked
- Resource Name: “Hello“
- Resource Path: “/greet“
- CORS: unchecked
- Click “Create Resource“
- Method
- Click “/greet“
- Actions -> “Create Method“
- Select “GET”
- Integration type: “Lambda Function“
- Lambda Proxy: unchecked
- Lambda Function: “SayHello“
- Use Default Timeout: checked
- Click “Save“
- Click “OK” for the “Add Permission to Lambda” confirmation dialog
4. Lambda – Check the Resource-based policy
- Click the “Functions” menu on the left pane
- Click the “SayHello” function
- Check Configuration -> Permissions -> Resource-based policy statements -> View policy
- Confirm that the API can call the Lambda
{
"Version": "2012-10-17",
"Id": "default",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "apigateway.amazonaws.com"
},
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:{region}:{account}:function:{function-name}",
"Condition": {
"ArnLike": {
"AWS:SourceArn": "arn:aws:execute-api:{region}:{account}:{api-id}/*/*/{route-name}"
}
}
}
]
}
5. API – Deploy the API with a Stage
- On the “Greeting” API page, click “Resources” on the left pane
- Actions -> “Deploy API”
- Deployment stage: “[New Stage]“
- Stage name: “dev“
- Click “Deploy“
- Click “Stages”
- Click “dev“
- Click “GET” under “/greet“
- Copy the Invoke URL and try it.
- The URL looks like “https://xewulp14m4.execute-api.us-east-1.amazonaws.com/dev/greet“
The URL should return a message without failing.
6. WAF – Set up the Rate-based rule
- Click “Web ACLs” on the left pane
- Click “Create web ACL”
- Name: “WebAclRate100“
- CloudWatch metric name: “WebAclRate100“
- Resource type: “Regional resources“
- Add rules
- “Add rules” -> “Add my own rules and rule groups“
- Rule Name: “Rate100“
- Type: “Rate-based rule“
- Rate limit: 100
- IP address to use: Check “Source IP address“
- Criteria: Check “Consider all requests“
- Action: “Block“
- Click “Add rule“
- Click “Next” several times to finish
7. API – Add the WAF rule to API
- On the “Greeting” API page, click “Stages” on the left pane
- Click “dev”
- Under the “Settings” tab, find the “WAF” section
- Select “WebAclRate100“
- Click “Save Changes“
- You might encounter an error. If so, remove the error and click “Save Changes” until it works.
8. Cloud9 – Test the WAF
- Click “Create environment”
- Name: “AWS Env“
- Check “New EC2 instance“
- Instance type: “t2.micro“
- Platform: “Amazon Linux 2“
- Connection: “AWS Systems Manager“
- Click “Create“
- Click “Open” in the “Cloud9 Env” column
- On the terminal, enter the following command – replace the url – to verify the AWS CLI setup.
- The script will send requests 200 times quickly.
- Wait for up to 5 minutes.
- Send the curl command
- You will get an error.
# it works
curl {api-url}
# send 200 requests
for i in {1..200}
do
curl -s -o /dev/null {api-url}
done
# wait a little bit
# "Forbidden" Error
curl {api-url}
9. WAF/API – Check the blocked IPs.
You can check the blocked IP of the API using the following steps.
- Click “Web ACLs” on the left pane of the WAF page
- From the list, copy the WebACL name and Web ACL Id
- Click “WebAclRate100”
- On the “Rules” tab, copy the rule name
- Move on to the “Cloud9” console, type the following command.
# pattern
aws wafv2 get-rate-based-statement-managed-keys \
--scope=REGIONAL \
--region=region \
--web-acl-name=WebACLName \
--web-acl-id=WebACLId \
--rule-name=RuleName
# example
aws wafv2 get-rate-based-statement-managed-keys \
--scope=REGIONAL \
--region=us-east-1 \
--web-acl-name=WebAclRate100 \
--web-acl-id=0bb563a5-c453-46d7-a00f-f0045329d51b \
--rule-name=Rate100