Secure Connection between Lambda and RDS: Choosing and Implementing SSL/TLS Certificates
Atsushi Suzuki
Posted on November 23, 2023
Recently, while integrating an RDS Read Replica into our architecture, we encountered the following error message when setting up an SSL/TLS connection from Lambda (NestJS) to the RDS (Read Replica):
Error: self-signed certificate in certificate chain
This article documents the cause of this problem and how it was resolved.
Cause
The issue was simply due to the use of an inappropriate certificate.
Certificate for RDS Proxy
Originally, our setup involved connecting from Lambda (NestJS) through RDS Proxy to the primary RDS. In this case, we used the AmazonRootCA1.pem certificate.
When using RDS Proxy, AWS's AmazonRootCA1.pem
root certificate is crucial. This certificate is employed to verify the identity of RDS Proxy and ensure the encryption of communications.
Lambda(NestJS) → RDS Proxy → RDS (Primary)
https://repost.aws/knowledge-center/rds-aurora-mysql-connect-proxy
Direct Connection to RDS (Read Replica)
For the newly added RDS (Read Replica) connection, it was necessary to connect directly from Lambda without going through the RDS Proxy. (As RDS Proxy is primarily used for load reduction in write operations and efficient connection management, it was not needed for the read-only Read Replica, so a direct connection was chosen.)
For this direct connection, a region-specific ap-northeast-1-bundle.pem(~-bundle.pem)
certificate was required.
Lambda(NestJS) → RDS (Read Replica)
Solution
To resolve this issue, we used the appropriate SSL/TLS certificate for the connection to the RDS (Read Replica).
We referred to the official AWS page for the certificate bundle ap-northeast-1-bundle.pem
, which resolved the error.
https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.SSL.html
Supplement: Method for Loading Certificates (NestJS)
For loading the SSL/TLS certificates in the application (NestJS), we implemented a method to retrieve the certificates from AWS S3.
Certificate Retrieval Process from S3
We defined a S3CertificatesService
class and accessed S3 using the AWS SDK. This class provides a getCertificateFromS3
method to retrieve certificates from a specified bucket and key.
import { Injectable } from '@nestjs/common';
import * as AWS from 'aws-sdk';
@Injectable()
export class S3CertificatesService {
private s3: AWS.S3;
constructor() {
this.s3 = new AWS.S3();
}
async getCertificateFromS3(bucket: string, key: string): Promise<string> {
const params = {
Bucket: bucket,
Key: key
};
const data = await this.s3.getObject(params).promise();
if (data.Body) {
return data.Body.toString();
}
throw new Error('Failed to retrieve certificate from S3. Body is undefined.');
}
}
DB Connection Configuration
For the DB connection settings, we used the above service to retrieve the certificate from S3 and applied it to our DB connection configuration. Here, we obtained the ap-northeast-1-bundle.pem
certificate and used it for the SSL connection to the DB (MySQL).
const certificate = await s3CertificatesService.getCertificateFromS3('rds-certificates', 'ap-northeast-1-bundle.pem');
const dbConfig = {
type: 'mysql',
host: '',
port: 3306,
username: '',
database: '',
password: '',
ssl: {
ca: certificate,
rejectUnauthorized: true
}
};
Posted on November 23, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 23, 2023