RDS Instance Transport Encryption
Overview
This check verifies that your Amazon RDS database instances enforce SSL/TLS encryption for all client connections. When enabled, the database rejects any unencrypted connection attempts, ensuring all data in transit is protected.
Risk
If SSL/TLS is not enforced, database connections can occur over plaintext. This exposes your data to several threats:
- Credential theft: Database usernames and passwords can be intercepted
- Data exposure: Queries and results travel unencrypted across the network
- Man-in-the-middle attacks: Attackers can intercept and modify traffic
- Compliance violations: Many regulations (PCI-DSS, HIPAA, SOC 2) require encryption in transit
Remediation Steps
Prerequisites
You need:
- Access to the AWS Console with permissions to modify RDS parameter groups, OR
- AWS CLI configured with appropriate credentials
- Knowledge of which database engine your RDS instance uses (PostgreSQL, MySQL, MariaDB, or SQL Server)
Setting up AWS CLI (if needed)
Install the AWS CLI and configure credentials:
# Install AWS CLI (macOS)
brew install awscli
# Configure credentials
aws configure
You will need the rds:ModifyDBParameterGroup and rds:DescribeDBParameters permissions.
AWS Console Method
-
Open the RDS Console
- Go to Amazon RDS Console
- Click Parameter groups in the left navigation
-
Create or select a parameter group
- If your database uses the default parameter group, you must create a new one (default groups cannot be modified)
- Click Create parameter group
- Select the appropriate family for your database engine (e.g.,
postgres15,mysql8.0) - Give it a descriptive name like
ssl-enforced-params - Click Create
-
Enable SSL enforcement
- Click on your parameter group name
- Click Edit parameters
- Search for the appropriate parameter:
- PostgreSQL or SQL Server: Find
rds.force_ssland set it to1 - MySQL or MariaDB: Find
require_secure_transportand set it toON
- PostgreSQL or SQL Server: Find
- Click Save changes
-
Apply the parameter group to your database
- Go to Databases in the left navigation
- Select your database instance
- Click Modify
- Under Additional configuration, change the DB parameter group to your new group
- Click Continue, then Apply immediately (or schedule for maintenance window)
-
Reboot the instance (if required)
- Some parameter changes require a reboot
- Select the instance and choose Actions > Reboot
AWS CLI (optional)
For PostgreSQL or SQL Server
# Create a new parameter group (if needed)
aws rds create-db-parameter-group \
--db-parameter-group-name ssl-enforced-params \
--db-parameter-group-family postgres15 \
--description "Parameter group with SSL enforcement" \
--region us-east-1
# Enable SSL enforcement
aws rds modify-db-parameter-group \
--db-parameter-group-name ssl-enforced-params \
--parameters "ParameterName=rds.force_ssl,ParameterValue=1,ApplyMethod=pending-reboot" \
--region us-east-1
# Associate with your database instance
aws rds modify-db-instance \
--db-instance-identifier <your-db-instance-id> \
--db-parameter-group-name ssl-enforced-params \
--apply-immediately \
--region us-east-1
# Reboot to apply changes
aws rds reboot-db-instance \
--db-instance-identifier <your-db-instance-id> \
--region us-east-1
For MySQL or MariaDB
# Create a new parameter group (if needed)
aws rds create-db-parameter-group \
--db-parameter-group-name ssl-enforced-params \
--db-parameter-group-family mysql8.0 \
--description "Parameter group with SSL enforcement" \
--region us-east-1
# Enable SSL enforcement
aws rds modify-db-parameter-group \
--db-parameter-group-name ssl-enforced-params \
--parameters "ParameterName=require_secure_transport,ParameterValue=ON,ApplyMethod=pending-reboot" \
--region us-east-1
# Associate with your database instance
aws rds modify-db-instance \
--db-instance-identifier <your-db-instance-id> \
--db-parameter-group-name ssl-enforced-params \
--apply-immediately \
--region us-east-1
# Reboot to apply changes
aws rds reboot-db-instance \
--db-instance-identifier <your-db-instance-id> \
--region us-east-1
CloudFormation (optional)
AWSTemplateFormatVersion: '2010-09-09'
Description: RDS Parameter Group with SSL/TLS enforcement
Parameters:
DBEngine:
Type: String
Description: Database engine type
AllowedValues:
- postgres
- mysql
- mariadb
- sqlserver-ex
- sqlserver-web
- sqlserver-se
- sqlserver-ee
Default: postgres
DBEngineVersion:
Type: String
Description: Database engine version
Default: '15'
ParameterGroupName:
Type: String
Description: Name for the parameter group
Default: ssl-enforced-params
Conditions:
IsPostgresOrSQLServer: !Or
- !Equals [!Ref DBEngine, 'postgres']
- !Equals [!Ref DBEngine, 'sqlserver-ex']
- !Equals [!Ref DBEngine, 'sqlserver-web']
- !Equals [!Ref DBEngine, 'sqlserver-se']
- !Equals [!Ref DBEngine, 'sqlserver-ee']
IsMySQLFamily: !Or
- !Equals [!Ref DBEngine, 'mysql']
- !Equals [!Ref DBEngine, 'mariadb']
Resources:
PostgresSQLServerParameterGroup:
Type: AWS::RDS::DBParameterGroup
Condition: IsPostgresOrSQLServer
Properties:
DBParameterGroupName: !Sub '${ParameterGroupName}-postgres-sqlserver'
Description: Parameter group with SSL enforcement for PostgreSQL or SQL Server
Family: !Sub '${DBEngine}${DBEngineVersion}'
Parameters:
rds.force_ssl: '1'
Tags:
- Key: Name
Value: !Sub '${ParameterGroupName}-postgres-sqlserver'
MySQLMariaDBParameterGroup:
Type: AWS::RDS::DBParameterGroup
Condition: IsMySQLFamily
Properties:
DBParameterGroupName: !Sub '${ParameterGroupName}-mysql-mariadb'
Description: Parameter group with SSL enforcement for MySQL or MariaDB
Family: !Sub '${DBEngine}${DBEngineVersion}'
Parameters:
require_secure_transport: 'ON'
Tags:
- Key: Name
Value: !Sub '${ParameterGroupName}-mysql-mariadb'
Outputs:
ParameterGroupId:
Description: The ID of the created parameter group
Value: !If
- IsPostgresOrSQLServer
- !Ref PostgresSQLServerParameterGroup
- !Ref MySQLMariaDBParameterGroup
Deploy with:
aws cloudformation deploy \
--template-file template.yaml \
--stack-name rds-ssl-enforcement \
--parameter-overrides DBEngine=postgres DBEngineVersion=15 \
--region us-east-1
Terraform (optional)
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
variable "db_engine" {
description = "Database engine type (postgres, mysql, mariadb, sqlserver-ex, etc.)"
type = string
default = "postgres"
}
variable "db_engine_version" {
description = "Database engine version"
type = string
default = "15"
}
variable "parameter_group_name" {
description = "Name for the parameter group"
type = string
default = "ssl-enforced-params"
}
locals {
is_postgres_or_sqlserver = contains(["postgres", "sqlserver-ex", "sqlserver-web", "sqlserver-se", "sqlserver-ee"], var.db_engine)
is_mysql_family = contains(["mysql", "mariadb"], var.db_engine)
ssl_parameters = local.is_postgres_or_sqlserver ? [
{
name = "rds.force_ssl"
value = "1"
apply_method = "pending-reboot"
}
] : local.is_mysql_family ? [
{
name = "require_secure_transport"
value = "ON"
apply_method = "pending-reboot"
}
] : []
}
resource "aws_db_parameter_group" "ssl_enforced" {
name = var.parameter_group_name
family = "${var.db_engine}${var.db_engine_version}"
description = "Parameter group with SSL/TLS enforcement"
dynamic "parameter" {
for_each = local.ssl_parameters
content {
name = parameter.value.name
value = parameter.value.value
apply_method = parameter.value.apply_method
}
}
tags = {
Name = var.parameter_group_name
}
}
output "parameter_group_id" {
description = "The ID of the created parameter group"
value = aws_db_parameter_group.ssl_enforced.id
}
output "parameter_group_arn" {
description = "The ARN of the created parameter group"
value = aws_db_parameter_group.ssl_enforced.arn
}
Apply with:
terraform init
terraform apply -var="db_engine=postgres" -var="db_engine_version=15"
Verification
After making changes, verify SSL enforcement is active:
-
In the AWS Console:
- Go to RDS > Parameter groups
- Click on your parameter group
- Search for
rds.force_ssl(PostgreSQL/SQL Server) orrequire_secure_transport(MySQL/MariaDB) - Confirm the value is
1orON
-
Test a connection (optional):
- Try connecting without SSL - it should be rejected
- Connect with SSL - it should succeed
CLI verification commands
# Check parameter group settings (PostgreSQL/SQL Server)
aws rds describe-db-parameters \
--db-parameter-group-name ssl-enforced-params \
--query "Parameters[?ParameterName=='rds.force_ssl']" \
--region us-east-1
# Check parameter group settings (MySQL/MariaDB)
aws rds describe-db-parameters \
--db-parameter-group-name ssl-enforced-params \
--query "Parameters[?ParameterName=='require_secure_transport']" \
--region us-east-1
# Verify which parameter group is attached to your instance
aws rds describe-db-instances \
--db-instance-identifier <your-db-instance-id> \
--query "DBInstances[0].DBParameterGroups" \
--region us-east-1
Additional Resources
- Using SSL/TLS to Encrypt a Connection to a DB Instance
- Working with DB Parameter Groups
- Downloading SSL/TLS Certificates for RDS
- Prowler Check Documentation
Notes
- Reboot required: Enabling SSL enforcement typically requires a database reboot. Plan for a brief outage or use a maintenance window.
- Client configuration: After enabling enforcement, all clients must connect using SSL. Update connection strings to include SSL parameters.
- Certificate management: RDS uses certificates from the Amazon RDS Certificate Authority. Download the appropriate CA bundle for your clients.
- Aurora clusters: For Aurora, you may need to modify cluster parameter groups instead of instance parameter groups.
- Performance impact: SSL/TLS adds minimal overhead (typically less than 5%) and is strongly recommended for all production workloads.