Securing Lambda to ELB Connections with HTTPS using AWS Certificate Manager (ACM)
Tags: aws, security, webdev, beginners
Published: 2023-07-01 12:44:43

I'm working as an AI engineer at a startup in Tokyo. As we only have two engineers including myself, I find myself handling not just frontend (React) and backend (NestJS) development, but also infrastructure (AWS) development.

While conducting research prior to an architectural retrofit of the application, we discovered a security risk in that the connection from Lambda to the ELB of another VPC was HTTP, and we decided to make the retrofit immediately.

Since we had no experience working with HTTPS before, we have summarized our investigation and implementation as a reminder. If there are any inadequacies in the contents, I would appreciate it if you could point them out in the comments section.

## The Flow of HTTPS Connection Between Lambda and ELB
Before diving into the implementation, let's get a clear understanding of the flow when a Lambda function connects to an ELB using HTTPS:

1. Initiating the Connection: The Lambda function initiates a connection to the ELB's HTTPS endpoint.
2. Certificate Presentation: The ELB presents its certificate (along with the public key) to the Lambda function. This certificate is issued by ACM or another certificate manager and is configured on the ELB.
3. Certificate Verification: The Lambda function (more accurately, the HTTP client library such as Axios in the code within the Lambda function) verifies the certificate. It confirms that the certificate is issued by a trusted Certificate Authority (CA), that it is still valid, and that it indeed belongs to the server (ELB) to which the connection is being attempted.
4. Creation and Sharing of Encryption Key: Once the certificate is verified, the Lambda function generates a session key (shared secret key). This session key is encrypted with the ELB's public key and sent to the ELB. The ELB then decrypts the encrypted session key using its own private key.
5. Initiation of Secure Communication: All communication between the ELB and the Lambda function is encrypted using the shared session key. This ensures that even if a third party intercepts this communication, they would be unable to read the information without the private key.

## Implementation
Having understood the flow of HTTPS connections, the following steps are required for the implementation:

1. Issuance of SSL/TLS Certificate
2. Creating a new listener on ELB

Since the basic task is to upgrade an HTTP connection to HTTPS, configurations on Route53, AWS Certificate Manager (ACM), and ELB will be required.

### 1. Issuance of SSL/TLS Certificate
Issue the SSL/TLS certificate that will be attached to the ELB using AWS Certificate Manager (ACM).

#### Creation of a Custom Domain for ELB
When issuing a certificate in ACM, you need to associate the ELB domain. However, you can't issue a certificate for a domain that AWS already owns, such as `.elb.amazonaws.com`. Therefore, you will need to create a new custom domain (e.g., `mywebsite.com`).

Since we have an existing domain (e.g., `mywebsite.com`), we create a new record (e.g., `service.mywebsite.com`) in the Route53 hosted zone and map it to the ELB URL.

1. In the Route 53 dashboard, click on "DNS management".
2. Click on "Hosted zones".
3. Click on the row of the relevant hosted zone (e.g., `mywebsite.com`).
4. In the right-side pane, click on "Create Record".
5. In the new record configuration screen, do the following:

 a. In "Record name", enter the subdomain you want to configure (e.g., `service`).
 b. For "Record type", select A - IPv4 address.
 c. For "Value/Route traffic to", select Alias to Elastic Load Balancer.
 d. In "Choose Region", select the region where the ELB is located (e.g., `ap-northeast-1`).
 e. In "Choose ELB", select the target ELB (e.g., `alb-12345678`).
 f. Click on "Create records".

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oyyne1y0hjtsmifbmv7c.png)

#### Requesting the Certificate
Using the custom domain created, you can now request a certificate from ACM. Set as follows and click "Request".

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2vxsx2sky9jwklbjdvip.png)

#### DNS Validation
If you chose DNS validation in the previous step, you'll need to add the CNAME record provided by ACM to Route53 to verify domain ownership.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7zqs2yf6pz1e402k9pdj.png)

After requesting the certificate, open the details page and copy the CNAME name and CNAME value.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y91w7b5i0dvpv2nylfvk.png)

This completes the setup for Route53 to use the CNAME record provided by ACM to verify domain ownership. After some time, return to the ACM management console and confirm that the status of the certificate has changed to [Issued].

### 2. Creating a new listener on ELB
Register the issued certificate to ELB from the listener settings of ELB.

Navigate to the ELB settings screen, select the target Load Balancer, and then move to the "Listeners" tab. Here, click on "Edit" and select "Add listener" to add an HTTPS listener.

For the Target Group, select an existing one. The display of HTTP means that the connection from ELB to the backend service is HTTP. Although this should also be converted to HTTPS, it remains as it is for the sake of explanation (ELB will be the SSL termination point).

Also, in the Security Policy, you define the SSL/TLS protocol and cipher used in communication between Lambda and ELB. This time, we have chosen the one that is marked as `(recommended)`.

In the part of Default SSL/TLS certificate, select the certificate issued this time.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/25ai1cxggv1uzmim17jy.png)

Once the listener is created, the conversion to HTTPS for connections to ELB is complete.