Aws_rds_castore - Certificate validation for AWS RDS DBs

aws_rds_castore

Enable verification of server certificates in AWS RDS DB connections, e.g. through EctoSql. Includes the latest private root CA certificate bundle from AWS RDS, along with a helper function to set the connection’s ssl_opts.

Usage: add aws_rds_castore as a dependency and update your DB configuration in runtime.exs as follows:

config :my_app, MyApp.Repo,
  url: database_url,
  ssl: true,
  ssl_opts: AwsRdsCAStore.ssl_opts(database_url)

Also supports Erlang projects, e.g. via pgo.

Credits: Much of the code, in particular the periodic update check in CI, is based on castore | Hex.

Q: Why do I need this?
A: AWS RDS uses privately issued certificates for DB servers, so certificate verification against the standard (OS or Hex package) trust stores would fail; in practice the server certificate is often ignored

Q: Is it not enough to just set ssl: true ?
A: Setting ssl: true will enable TLS, which ensures the DB connection is encrypted and therefore protected from snooping by a passive attacker. However, on OTP versions prior to 26 the server certificate is ignored by default, which means an active attacker could potentially hijack the communication without being detected.

Q: Does this fix the “Server authenticity is not verified…” message logged by OTP 25?
A: Yes, enabling server certificate verification using the ssl_opts from this library will eliminate this warning

Q: Will this work with OTP 26, where certificate verification is enabled by default?
A: I have not yet tried OTP 26 with AWS RDS, but I suspect it will fail to connect to AWS RDS over TLS without ssl_opts, because it will try to verify the server certificate against the OS trust store. Using this package and the ssl_opts it generates should fix that.

Q: Why do I need to pass the server’s URL/hostname to ssl_opts?
A: At least for Postgres-type databases the TLS handshake is started on a previously established TCP connection. In such cases the ssl module needs to be told explicitly which hostname to use when verifying the server certificate.

Q: Does this work with all AWS RDS DB types?
A: For now it has only been tested with Postgres-type DB instances. Please let me know if you use it with other DB types, either successfully or unsuccessfully.

Links:

13 Likes

Did a quick test with Aurora Postgres and seems to work just fine!

Wow I have been killing myself over this for hours today. Thank you! :pray:

thanks for this handy lib! solved my RDS PG15 default params and OTP26 problem.

Due to the increased relevance (thanks to ssl changes in OTP 26) and interest I decided to turn this project into a hybrid Elixir/Erlang project: v1.1 can be built using Rebar3 and includes an Erlang module aws_rds_castore with the same API as the Elixir module.

One small warning: in order to ensure consistent behavior in Elixir and Erlang projects, this new version relies on the uri_string module from the Erlang/OTP standard library. This module is only available on OTP 21 or later, on older versions the ssl_opts function does not accept URIs, only hostnames.

1 Like