Postgresql – Force SSL on AWS RDS Postgres

amazon-rdsamazon-web-servicespostgresql

I've got a brand new Postgres 11 RDS instance that I can connect to with or without an SSL cert. However, I would like to ensure that we never connect to this database without SSL. So I have taken the following steps to attempt to enforce this:

  1. Create a new parameter group because the default ones are not editable.
  2. Change the value of rds.force_ssl to 1.
  3. Change my database parameter group to the new one, selecting "Apply immediately"
  4. Wait for the parameter group to apply, once the status changes from "(applying)" to "(pending-reboot)"
  5. Once this group has been applied, I reboot the instance.
  6. Then when I connect using the cli: psql -h aws_hostname -p 5432 "dbname=mydbname user=dbuser" I would expect the connection to fail because I have not specified the SSL certificate.

The output is:

Password for user postgres:
psql (11.5)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

mydbname=>

So I can see that the connection is over TLSv1.2. However, I don't understand why AWS appears to allow you to enforce SSL, and provides a way to download a certificate to do this, but does not use it. I was expecting to be forced to provide the certificate when connecting like this:

psql -h aws_hostname -p 5432 "dbname=mydbname user=dbuser sslrootcert=rds-combined-ca-bundle.pem sslmode=verify-full"

Best Answer

However, I don't understand why AWS appears to allow you to enforce SSL, and provides a way to download a certificate to do this, but does not use it. I was expecting to be forced to provide the certificate when connecting like this

The server can force the client to use ssl to establish the connection, but it cannot force the client to verify the server's certificate.

If your client is libpq based, then it will verify the certificate if and only if it can find the root certificate file (generally at ~/.postgresql/root.crt, if not specified as something else). If you specify PGSSLMODE=verify-ca or above on the client, then the client will throw an error if can't find the root cert file. If the sslmode is below that level and the client can't find the root cert file, then it will use the server's certificate to negotiate encryption, but will not use it to verify the identity of the server. So you get protection from passive eavesdropping, but not from active MITM attacks.