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.