AWS API Gateway with Nginx behind WAF

AWS API Gateway with Nginx and WAF

Let’s review one architecture using AWS API Gateway, and Nginx protected with a WAF.

  • Goal:
    • Explain and present a solution using WAF and how you can organize your architecture to save money and time managing multiple Web Applications.
    • Configure Nginx as a reverse proxy to forward traffic from AWS API Gateway. Where behind the API Gateway is running some EC2 instances with the APIs.

Why use Nginx as reverse with AWS API Gateway

Simplify Network Configuration: Build a single entry point to access all private resources instead of creating and managing multiple security layers for several servers and their configuration individually.

Security: If you have sensitive data, you should be careful about exposing your Web Application to the internet. In our scenario, the AWS API Gateway is a private resource where only requests from inside the same VPC are allowed.

Save Money

Companies must always protect your Web Site and APIs, but that comes with a cost. Integrating and putting your API in front of a WAF (Web Application Firewall) is pretty expensive today. Why is it expensive? Most of the companies that provide the service to protect your Web Application also provide CDN (Content Delivery Network), which has a price model to charge you by each application (DNS).

For scenarios where you have many APIs spread across different servers, it may be worth centralizing the access through a single entry point. The entry point is known as Front Proxy or Reverse Proxy and is responsible for forwarding all requests to each API using rules based on DNS.

Diagram from API Gateway with Nginx behind WAF
Diagram from API Gateway with Nginx behind WAF

Hold on. But, you may be thinking. Why use AWS API Gateway?

Looking at the diagram above, it doesn’t make sense because we could call the “App Server” directly through the Load Balance, skipping the API Gateway.

Let me explain some key features of AWS API Gateway:

1 – Usage Plan:

  • We can save time by using the existing feature for throttling API in case the Client calls more than the quota limit.

2 – Security

  • The AWS API Gateway provides the mechanism of API credentials like API keys and integration with Cognito to authentication, so it’s not necessary to develop our own solution for it.

Ngnix Configuration

To call API directly would be some like:

https://app.bitslovers.com/api/find/username

The equivalent URL on API Gateway will be:

The AWS API Gateway endpoint

https://6ax1c8mg2a.execute-api.us-east-1.amazonaws.com/prod/find/username

Let’s see the proxy configuration file:

Alternative 1:

server {
  listen 80;
  server_name app.bitslovers.com;
  return 301 https://app.bitslovers.com;
}

server {
  listen        443 ssl;
  server_name app.bitslovers.com;

  location /api/ {
    proxy_max_temp_file_size 2048m;
    proxy_read_timeout 3600s;
    proxy_send_timeout 3600s;
    proxy_connect_timeout 3600s;
    client_max_body_size 100G;
    resolver 127.0.0.1 53 valid=5s;    
    
    set $backend_servers 6ax1c8mg2a.execute-api.us-east-1.amazonaws.com;
    
    if ($request_uri ~ "/api/") {
      rewrite  ^  $request_uri;                # get original URI
      rewrite  ^/api(/.*)  /prod$1  break;  # drop /api, put /prod
      proxy_pass https://$backend_servers$uri;
    }
  }
}

Alternative 2

In this second example, there is little difference.

When you deploy a Private API Gateway, AWS provides different ways to call the API. The example above uses the VPC Endpoint to call the API.

How to call the private API using VPC Endpoint:

You need to create the VPC Endpoint on AWS for the API Gateway service (execute-api), and then you will have one unique DNS to use to call your API. But, there is one important step that you must follow: You need to add the Header “Host” with the value (DNS) from your API Endpoint (from AWS).

For example, using curl:


curl -v https://vpce-.execute-api.us-east-1.vpce.amazonaws.com - H “Host: 6ax1c8mg2a.execute-api.us-east-1.amazonaws.com”

The Nginx configuration file with a Private API Gateway using VPC Endpoint will be like this:

server {
  listen 80;
  server_name app.bitslovers.com;
  return 301 https://app.bitslovers.com;
}

server {
  listen        443 ssl;
  server_name app.bitslovers.com;

  location /api/ {
    proxy_max_temp_file_size 2048m;
    proxy_read_timeout 3600s;
    proxy_send_timeout 3600s;
    proxy_connect_timeout 3600s;
    client_max_body_size 100G;
    resolver 127.0.0.1 53 valid=5s;    
    proxy_set_header Host 6ax1c8mg2a.execute-api.us-east-1.amazonaws.com;

		set $backend_servers vpce-<id>.execute-api.us-east-1.vpce.amazonaws.com;
    
    if ($request_uri ~ "/api/") {
      rewrite  ^  $request_uri;                # get original URI
      rewrite  ^/api(/.*)  /prod$1  break;  # drop /api, put /prod
      proxy_pass https://$backend_servers$uri;
    }
  }
}

WAF

If you decide to use WAF for your Web Application, you likely will see a lot of companies that provide that service, but the big players in that area are Cloudflare and Impervia. But they work differently.

Cloudflare vs. Impervia?

Cloudflare requires that you move your DNS nameserver (NS) to the Cloudflare servers. And then, you can choose which DNS record will go through the Cloudflare Proxy to use WAF.

To use Impervia, you don’t need to move your DNS nameserver. But you have to configure the final DNS from your application to point to Imperva DNS.

Each application will have a different Imperva DNS.

So, for example, www.bitslovers —> xxx73hd.impervia.net —> server.bitslovers.com

To make the solution above work properly, you must guarantee that your server.bitslovers.com firewall or Security Group allows only IPs from Impervia.

Leave a Comment

Your email address will not be published. Required fields are marked *

Free PDF with a useful Mind Map that illustrates everything you should know about AWS VPC in a single view.