Serverless architectures are becoming more and more popular, and Amazon’s API Gateway service is a key factor in many serverless deployments on AWS. Currently API Gateway only supports a public CloudFront endpoint, and securing the API Gateway with high-end WAF protection may seem like a difficult task. In this blog post we’ll explain how to protect a sample API Gateway application with SecureSphere WAF.
While the focus here is on AWS, keep in mind the below can be applied for protecting other public endpoints or API gateway vendors as well.
A Sample API Gateway Application – Getting Started
A common Amazon API Gateway deployment may look something like this (Figure 1):
Figure 1: A typical application deployment pattern using AWS API Gateway
This sample application is completely serverless and uses AWS services for scaling, automatic provisioning, authorization, logging and so on. There are good tutorials online that can teach you how to deploy such applications (with readymade CloudFormation templates).
After you deploy your API, the API Gateway creates a stage which has a public facing URL (see Figure 2):
Figure 2: AWS API Gateway Console showing the public endpoint created after running “Deploy API”
This stage is actually a hidden CloudFront distribution. Next, you need to create a proper CloudFront distribution so that Imperva SecureSphere may communicate with it without client-side SNI (Figure 3):
Figure 3: AWS CloudFront Console with a new distribution forwarding to our API Gateway endpoint
You don’t want the client application or users to access this endpoint directly without protection, so the next step is to set up the SecureSphere stack on AWS.
Setting Up the SecureSphere AWS Public Endpoint Stack
The goal is to achieve the following architecture with SecureSphere WAF and AWS (Figure 4):
Figure 4: SecureSphere WAF deployment architecture to protect AWS API Gateway traffic
In most cases SecureSphere deployments on AWS will protect web endpoints that are in the same VPC as the SecureSphere stack or in peered VPCs. Because SecureSphere supports a reverse proxy architecture, it can protect public endpoints as well. To learn more about how to deploy SecureSphere in AWS refer to this blog post.
In the end, the deployed stack should look like below (Figure 5):
Figure 5: Detailed architecture diagram of SecureSphere WAF deployment on AWS protecting a public endpoint
- The public endpoint becomes the external load balancer DNS name (need to add DNS attachment from our external hostname to the ELB hostname).
- The WAF gateways re-write the external hostname (e.g. www.mycompany.com) to the AWS API Gateway endpoint (fznty25z54.execute-api.us-east-1.amazonaws.com).
- The WAF gateways process the request and route them to the CloudFront domain name (d2we3m806cjgh0.cloudfront.net).
- The VPC exit point is done through the NAT gateway elastic IPs (can also use proxy or NAT instances). These are static IPs that can be used to limit access to the AWS API Gateway.
- If the SecureSphere Management Server is in a public subnet and accessible from the internet, it should have a strict security group limiting the IP addresses that can access it.
- It is recommended that the SecureSphere stack and AWS API Gateway be in the same region for the best latency performance.
In SecureSphere, you should have a URL rewrite rule that looks like the below (Figure 6):
Figure 6: SecureSphere URL Rewrite Rule
The API Gateway knows the application by its generated hostname (fznty25z54.execute-api.us-east-1.amazonaws.com). This URL rewrite rule converts the external hostname (www.company.com) to the API Gateway hostname.
The SecureSphere reverse proxy configuration should look like the below (Figure 7):
Figure 7: SecureSphere Reverse Proxy rules. Click to enlarge image.
First the URL rewrite rule (apig) takes effect, then the API Gateway traffic (Host = fznty25z54.execute-api.us-east-1.amazonaws.com) is routed to the CloudFront endpoint (Internal Hostname = d2we3m806cjgh0.cloudfront.net).
Limiting Access to the API Gateway
At this point, you have your public domain name (www.company.com) going through SecureSphere WAF. However, you still have a public API Gateway endpoint that can bypass the SecureSphere WAF. AWS API Gateway doesn’t support security groups to limit IP access, but you can do a workaround using its authorization feature.
The traffic going through SecureSphere will always originate from the public NAT gateway EIPs in the SecureSphere stack. You need to create a “Custom Authorizer” in the API Gateway that will only allow access to these IP addresses (Figure 8):
Figure 8: Custom Lambda Authorizer that limits access to the SecureSphere stack public IP (18.104.22.168)
The authorization needs to be set for each method in the application, but if you are already using IAM authorization, the IP condition can easily be added.
AWS outbound traffic (from the VPC) can get costly. If you have heavy static content, consider providing direct access to S3 (or wherever the content is stored) and bypassing the WAF to reduce the double hop and charges.
If your API Gateway acts as a proxy for HTTP communications, it is possible to place the WAF between the API Gateway and the HTTP endpoints. More commonly, the API Gateway fronts Lambda functions or other AWS services, so the WAF needs to be placed before the API Gateway.
There are AWS API Gateway alternatives (e.g., Apigee) that support VPC integration thus allowing a more traditional perimeter security architecture. It’s likely that AWS API Gateway will introduce support for a similar architecture in the future.
Finally, remember that creating a “public SecureSphere stack” gives you the security control of SecureSphere with the flexibility of decoupling your WAF and application endpoints. You are creating your own SaaS WAF solution that can provide protection for any web endpoint – no matter where or what it is.