Migrating from on-premise infrastructure to AWS can be challenging. Many web services often need to be migrated, and companies usually want to avoid downtime on their services.
Amazon API Gateway is a fully managed AWS service that allows developers to create, deploy, and maintain APIs at any scale. API Gateway can be used as a proxy between customers and web services to ensure that an on-premise network stays private.
This article will show readers how to use API Gateway as a secure “front door” for their on-premise services with certificate-based mutual Transport Layer Security (TLS) authentication.
- Solution Overview
- Step #1: Enable VPC to communicate with On-prem resources
- Step #2: Test the Site-to-Site VPN connection
- Step #3: Setup API Gateway
- Step #4: Create Method
- Step #5: Create Integration
- Sub-Step 5.1: Set up a Network Load Balancer for API Gateway Private Integrations
- Step #6: Invoke the API Endpoint
- Step #7: Mutual TLS Authentication
- Sub-Step 7.1: Create a Private Certificate Authority (CA)
- Sub-Step 7.2: Request a SSL/TLS certificate
- Sub-Step 7.3: Create a trust store file and a container
- Sub-Step 7.4: Set Up a Regional Custom Domain Name
- Sub-Step 7.5: API Mappings
- Sub-Step 7.6: Disable the Default Endpoint
- Step #8: Test the API Gateway Endpoint
- About TrackIt
Step #1: Enable VPC to communicate with On-prem resources
The first step is to set up a discovery plan of the existing on-premise network infrastructure. The goal is to list resource ipv4 CIDR blocks along with the required ports to set up the correct VPC settings and security groups.
To connect your on-premise data center to your AWS VPC, there are two primary options:
- AWS Direct Connect: A solution used to link your on-premise network to AWS without using the public internet. It reduces the chances of bottlenecks and unexpected latency.
- AWS Site-to-Site VPN: A solution that enables access to your remote network from your VPC.
For usage as a proxy for on-prem web services, a Site-to-Site VPN is a perfect fit. Once the on-premise network has been connected to a VPC, it becomes an extension of the VPC. The next step is to configure routing to pass traffic through the connection. In AWS Site-to-Site VPN terms, a VPN connection is a secure connection between your on-premises equipment and your VPCs.
Step #2: Test the Site-to-Site VPN connection
Now that the AWS resources have access to the (remote) network, users can try to reach some resources within their on-prem data center. Here, we have a dev and production server running REST WebServices.
Rather than immediately adding an API Gateway, it’s best to check if the network is correctly configured. To ensure this, a good strategy is to set up a basic EC2 instance with the corresponding security group to ping the dev and production servers. If a response is obtained, this means that the network is working and has been correctly configured!
Step #3: Setup API Gateway
Once confirming that the Site-to-Site VPN is working, the next step is to begin the implementation of the API Gateway.
API Gateway offers two types of APIs, HTTP and REST APIs. For example, if in the future users would want to set up a Web Application Firewall (WAF) in front of their API Gateway, in addition to the mutual TLS authentication, they would need to use the REST API since REST APIs support WAF.
To read more about how to choose between HTTP APIs and REST APIs, readers can visit the following link: https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-vs-rest.html
Step #4: Create Method
In API Gateway, an API method embodies a method request and a method response. You set up an API method to define what a client should (or must) do to submit a request to access the service at the backend and also to define the responses that the client receives in return.
Let’s assume that the on-premise Web Service offers an API method request of GET /rest-service/inventory and we want to simplify this route for our customer using API Gateway to a method request of GET /inventory. For this, we implement the following:
Step #5: Create Integration
After setting up an API method, users must integrate it with an endpoint in the backend. A backend endpoint is also referred to as an integration endpoint and can be a Lambda function, an HTTP webpage, or an AWS service action.
The goal here is to create what we call a private integration. Private integration makes it simple to expose HTTP/HTTPS resources within an Amazon VPC for access by clients outside of the VPC.
To create a private integration, users must first create a Network Load Balancer (NLB). The NLB must have a listener that routes requests to resources in the VPC. To improve the availability of the API, ensure that the NLB routes traffic to resources in more than one Availability Zone (AZ) in the AWS Region. Then, users have to create a VPC link that will connect to the API and to the NLB. Once the VPC link is created, users can create private integrations to route traffic from the API to resources in the VPC through the VPC link and Network Load Balancer.
Sub-Step 5.1: Set up a Network Load Balancer for API Gateway Private Integrations
For each VPC, users only need to configure one NLB and one VPCLink. The NLB supports multiple listeners and target groups per NLB. Users can hence configure each service as a specific listener on the NLB and use a single VPCLink to connect to the NLB. When creating the private integration in API Gateway, each service is then defined using the specific port that is assigned to the service.
Sub-Step 5.2: VPC Link creation
Once the VPC Link is set up, users can finish the integration by going back to the /inventory GET — Setup pane and initializing the API method integration in the following manner:
- Choose VPC Link for Integration type
- Choose Use Proxy Integration
- From the Method drop-down list, choose GET as the integration method
- From the VPC Link drop-down list, choose the VPC Link. Note that “Stage variables” can be used as well but for the demonstration, we will use the dropdown value directly
- For Endpoint URL, type the Network Load Balancer DNS address with the port and the route to the web service (i.e.: https://your-nlb-dns:8001/rest-service/inventory).
Step #6: Invoke the API Endpoint
Simply creating and developing an API Gateway API doesn’t automatically make it callable. To make it callable, users must deploy the API to a stage.
A stage is a logical reference to a lifecycle state of the API (for example, dev, prod, beta, v2, etc.). API stages are identified by the API ID and stage name. They’re included in the URL that is used to invoke the API. Each stage is a named reference to a deployment of the API and is made available for client applications to call.
Every time an API is updated, it must be redeployed to an existing stage or to a new stage. Updating an API includes modifying routes, methods, integrations, authorizers, and anything else other than stage settings.
Now that we have deployed our API changes to a stage we should be able to request our API endpoint. Our API endpoint looks like this:
In this example, if we want to GET our /rest-service/inventory route, we should request the following endpoint:
This endpoint is going to retrieve the /inventory resource using a GET method which implements a private integration using a VPC Link.
The final request endpoint will be https://your-nlb-dns:8001/rest-service/inventory, as configured within the integration.
Before setting up a custom domain name for an API, users must have an SSL/TLS certificate ready in AWS Certificate Manager. The next section of this article covers the process of configuring a private certificate authority (CA).
Step #7: Mutual TLS Authentication
To configure mutual TLS, users should first create the private certificate authority and client certificates. For this, the public keys of the root certificate authority and any intermediate certificate authorities are needed. These must be uploaded to the API Gateway to authenticate certificates using mutual TLS.
Sub-Step 7.1: Create a Private Certificate Authority (CA)
With AWS Certificate Manager (ACM) Private CA, users can create a hierarchy of certificate authorities with up to five levels. The root CA, at the top of a hierarchy tree, can have any number of branches. The root CA can have as many as four levels of subordinate CAs on each branch. Users can also create multiple hierarchies, each with its own root.
A well-designed CA hierarchy offers the following benefits:
- Granular security controls appropriate to each CA
- Division of administrative tasks for better load balancing and security
- Use of CAs with limited, revocable trust for daily operations
- Validity periods and certificate path limits
The following diagram illustrates a simple, three-level CA hierarchy:
Read more about CA hierarchies here. (The CA hierarchy usually depends on a company’s specific requirements.)
Once the Root CA and Subordinate CA are created, users can request a private certificate for their custom domain. However, before issuing a new certificate for your customers, users have to set up the custom domain for their API Gateway and enable Mutual TLS Authentication.
Sub-Step 7.2: Request a SSL/TLS certificate
Before setting up a custom domain name for an API, users must have an SSL/TLS certificate ready in AWS Certificate Manager. The following steps describe how to get this done. For more information, see the AWS Certificate Manager User Guide.
To request a certificate provided by ACM for a domain name
- Sign in to the AWS Certificate Manager console
- Choose Request a public certificate
- Enter a custom domain name for your API, for example, api.example.com, in Domain name
- Choose Review and request
- Choose Confirm and request
- For a valid request, a registered owner of the internet domain must consent to the request before ACM issues the certificate
Sub-Step 7.3: Create a trust store file and a container
For the custom domain in this example, we will use a public certificate issued by ACM and we will use the Private CA to generate the customer certificates (private certificates). We are going to configure our trust store file within an Amazon S3 bucket. The Amazon S3 bucket will contain a .pem file extension. This .pem file is a trusted list of certificates from Certificate Authorities.
First, we create an Amazon S3 bucket. This bucket will be used as a container for the trust store file. A PEM-encoded trust store file is then prepared for all certificate authority public keys to be used with mutual TLS:
- For a single root CA (with no intermediary CAs), only the RootCA.pem file is required. Copy the existing root CA public key to a new truststore.pem file name for further clarity on which file is being used by API Gateway as the trust store.
Note: RootCA.pem is a generic name, it depends on how you named your files, RootCA.pem is just your RootCA public key.
2. For one or more intermediary CAs to sign certificates with a root of trust to the root CA previously created, the respective PEM files of each CA must be bundled into a single trust store PEM file. Use the cat command to build the bundle file:https://medium.com/media/20068c6ecc39e479388f6734a6313715
Note: The trust store CA bundle can contain up to 1,000 certificates authority PEM-encoded public key certificates; up to 1 MB total object size.
3. Upload the trust store file to your previously created Amazon S3 bucket in the same AWS account as our API Gateway API. It is also recommended to enable object versioning for the bucket you choose. You can perform these actions using the AWS Management Console, SDKs, or AWS CLI.
Sub-Step 7.4: Set Up a Regional Custom Domain Name
To create a custom domain name, users must provide a Region-specific ACM certificate. In this example, we use the certificate issued in the previous steps.
To set up a regional custom domain name using the API Gateway console
- Sign in to the API Gateway console at https://console.aws.amazon.com/apigateway.
- Choose Custom domain names from the main navigation pane
- Choose Create
- For Domain name, enter a domain name
- Choose a minimum TLS version.
- Specify the Truststore UI by providing your Amazon S3 bucket name prefixed by ‘s3://’ and suffixed by your truststore filename, in this case ‘truststore.pem’
- Under Endpoint configuration, choose Regional
- For the certificate type use the public certificate you issued in ACM at the “Request a SSL/TLS certificate. The certificate must be in the same Region as the API
- Choose create
Sub-Step 7.5: API Mappings
API mappings are used to connect API stages to a custom domain name. Once a domain name is created and its DNS records configured, API mappings are used to send traffic to the APIs through the chosen custom domain name.
An API mapping specifies an API, a stage, and optionally a path to use for the mapping. For example, you can map the production stage of an API to https://api.example.com/orders
and you can map HTTP and REST API stages to the same custom domain name.
Sub-Step 7.6: Disable the Default Endpoint
Mutual TLS is successfully enabled on the custom domain name but the default API endpoint URL is still active. This default endpoint has the following format:
Since the default endpoint does not require mutual TLS, users should disable it. This helps to ensure that mutual TLS authentication is enforced for all traffic to the API.
To disable the endpoint:
- Browse to the HTTP API in the API Gateway console
- Choose the API name in the menu
- Click settings and click Disabled in the Default Endpoint configuration
Step #8: Test the API Gateway Endpoint
Now that everything has been configured, users should be able to test the API Gateway endpoint.
To validate the setup, first export the client certificate created earlier. This can be done using the AWS Management Console or AWS CLI. This example uses the AWS CLI to export the certificate. To learn how to do this via the console, see exporting a private certificate using the console.
- Export the base64 PEM-encoded certificate to a local file, client.pem.
2. Export the encrypted private key associated with the public key in the certificate and save it to a local file client.encrypted.key. You must provide a passphrase to associate with the encrypted private key. This is used to decrypt the exported private keyhttps://medium.com/media/a39bb5ea20f70eb45072590c099a31ad
3. Decrypt the exported private key using passphrase and OpenSSL:https://medium.com/media/16b40b5ffb37a4dc41758b3c646e18af
4. Access the API using mutual TLS:https://medium.com/media/94046b04ce1a0a529b686cb3604f9055
This article serves as a detailed guide that walks readers through the entire process of setting up an API Gateway with certificate-based mutual TLS authentication. Once implemented, the API Gateway serves as a secure “front door” for their on-premise services.
TrackIt is an Amazon Web Services Advanced Consulting Partner specializing in cloud management, consulting, and software development solutions based in Venice, CA.
TrackIt specializes in Modern Software Development, DevOps, Infrastructure-As-Code, Serverless, CI/CD, and Containerization with specialized expertise in Media & Entertainment workflows, High-Performance Computing environments, and data storage.
TrackIt’s forté is cutting-edge software design with deep expertise in containerization, serverless architectures, and innovative pipeline development. The TrackIt team can help you architect, design, build and deploy a customized solution tailored to your exact requirements.
In addition to providing cloud management, consulting, and modern software development services, TrackIt also provides an open-source AWS cost management tool that allows users to optimize their costs and resources on AWS.