Skip to main content

SSL connections with RDS

RDS instances are configured to allow SSL connections by default, and the latest versions of the postgres client (psql), and programming language libraries (e.g. the pg ruby gem which builds on libpq), will establish an SSL connection by default.

$ psql "$url"
psql (9.6.13, server 10.6)
WARNING: psql major version 9.6, server major version 10.
         Some psql features might not work.
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

dba02192a049ed7ce8=> 

Where $url is of the form postgres://user:pass@host:port/db.

Additionally, AWS offer strong assurances that a malicious actor cannot spoof their traffic or sniff another tenant’s traffic, even if they operate inside the same VPC.

However, best practice is to be explicit about insisting on an SSL connection when you communicate with your database.

PostgreSQL implements various modes of operation, each one offering a different level of security. Without any additional setup, we can establish an encrypted connection by specifying sslmode=require, which forces an SSL connection but does not verify the server certificate.

Full verification of certificates

In order to establish a connection with sslmode=verify-full, which offers MITM protection, we have to provide the client with the root CA certificate before it is able to verify the chain of trust. AWS offers detailed instructions on how to do that.

As you can see below, unless provided with the root CA certificate, the client cannot fully verify the endpoint:

$ psql "$url?sslmode=verify-full"
psql: could not get home directory to locate root certificate file
Either provide the file or change sslmode to disable server certificate verification.
$ psql "$url?sslmode=verify-full&sslrootcert=/tmp/rds-combined-ca-bundle.pem"
psql (9.6.13, server 10.6)
WARNING: psql major version 9.6, server major version 10.
         Some psql features might not work.
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

dba02192a049ed7ce8=> 

This CA bundle can be added into your application’s docker image. You can simply add the following directive in your Dockerfile:

ADD https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem /path/to/rds-combined-ca-bundle.pem

If you’re developing a Ruby on Rails application, you can configure this by adding the following two options in your config/database.yml:

  sslmode: verify-full
  sslrootcert: /path/to/rds-combined-ca-bundle.pem

For other frameworks, you should consult their documentation on how to configure the database client to use SSL connections.

Force SSL connections

By default, RDS created on the Cloud Platform have SSL enabled.

This is done by having the field force_ssl: true, which completely disables unencrypted connections.

It is possible to confirm the above by running a psql command, using sslmode=disable:

$ psql "$url?sslmode=disable"
psql: FATAL:  no pg_hba.conf entry for host "172.20.32.241", user "fDsQgBlavX", database "dba02192a049ed7ce8", SSL off

The parameter force_ssl can be overriden by changing the db_parameter when calling the module.

This page was last reviewed on 11 May 2021. It needs to be reviewed again on 11 August 2021 .
This page was set to be reviewed before 11 August 2021. This might mean the content is out of date.