Securing Database Traffic with PgBouncer and Amazon RDS

Securing database traffic inside your network can be a great step for defense in depth. It’s also a necessity for Zero Trust Networks.

Both Amazon RDS and PgBouncer have built-in support for TLS, but it’s a little bit of work to get it set up. This tutorial will show you how.

Direct Connections

The first step is to make sure all direct connections are secure. Luckily, Amazon RDS has a parameter named for this. Once it’s applied, you’ll see an error if you try to connect without TLS. You can test this out with:

You’ll see an error like if everything is configured correctly.

There are a number of possible values for , which you can read about here. The most secure (and one we want) is , as it provides protection against both eavesdropping and man-in-the-middle attacks. This mode requires you to provide a root certificate to verify against. AWS makes this certificate available on their website.

To use it with , run:

Once connected, you should see an line before the first prompt.

There’s also an extension you can use (useful for non- connections).

Now direct connections are good, so let’s secure connections from PgBouncer to the database.

PgBouncer to the Database

Follow this guide to set up PgBouncer. Once that’s completed, there are two settings to add to :

Restart the service

And test it

The connection should succeed and the server should report SSL is used.

We’ve now successfully encrypted traffic between the bouncer and the database!

However, you’ll notice the prompt does not have an line as it did before. You can also use to successfully connect, and programs like or tshark will show unencrypted traffic between the client and the bouncer. You can test this out with:

Run commands in and you’ll see plaintext statements printed.

Clients to PgBouncer

This last flow is the trickiest. PgBouncer 1.7+ supports TLS, but we need to create keys and certificates for it. For this, we’ll create a private PKI. Minica and Vault are two ways to do this.

We’ll use Minica. Install the latest version:

And run:

We now have the files we need to connect. Add the key and certificates to :

And restart the service. To connect, we once again use but this time with the root certificate we generated above:

Confirm the line is printed and no longer works.

We’ve now successfully encrypted traffic end-to-end!

July 2018: Changed PKI example to Minica. Here are Vault instructions.