Skip to main content

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

  1. Open the RDS Console

  2. 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
  3. Enable SSL enforcement

    • Click on your parameter group name
    • Click Edit parameters
    • Search for the appropriate parameter:
      • PostgreSQL or SQL Server: Find rds.force_ssl and set it to 1
      • MySQL or MariaDB: Find require_secure_transport and set it to ON
    • Click Save changes
  4. 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)
  5. 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:

  1. In the AWS Console:

    • Go to RDS > Parameter groups
    • Click on your parameter group
    • Search for rds.force_ssl (PostgreSQL/SQL Server) or require_secure_transport (MySQL/MariaDB)
    • Confirm the value is 1 or ON
  2. 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

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.