pgjdbc / r2dbc-postgresql

Postgresql R2DBC Driver

Home Page:https://r2dbc.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Enhance ConnectionFactoryOptions to support all available SSL modes

DennisPietruck0001 opened this issue · comments

Feature Request

Currently, when creating a PostgreSQL connection using ConnectionFactoryOptions, we have limited options for configuring the sslmode. The library primarily enforces the use of the verify-full SSL mode or disable

However, PostgreSQL offers a range of SSL modes, including disable, allow, prefer, require, verify-ca, and verify-full, each catering to different security requirements and performance considerations. To accommodate a broader range of use cases, I propose to modify ConnectionFactoryOptions to allow users to specify their preferred SSL mode when establishing a PostgreSQL connection. This enhancement will provide greater flexibility and adaptability for different security and performance needs.

Describe the solution you'd like

I would like to mark the ssl option as deprecated and introduce a new option named sslmode. Which allows to select from all available sslmodes.

Describe alternatives you've considered

The primary alternative I've considered is setting the sslmode directly in the connection string when creating a PostgreSQL connection. While this approach does work and allows for the desired SSL mode configuration, it deviates from our preferred development convention.

I'm not quite sure what you're asking for. Our SSLMode enumeration lists the options you mentioned:

/**
* I don't care about security and don't want to pay the overhead for encryption
*/
DISABLE("disable"),
/**
* I don't care about security but will pay the overhead for encryption if the server insists on it
*/
ALLOW("allow"),
/**
* I don't care about encryption but will pay the overhead of encryption if the server supports it
*/
PREFER("prefer"),
/**
* I want my data to be encrypted, and I accept the overhead. I trust that the network will make sure I always connect to the server I want.
*/
REQUIRE("require"),
/**
* I want my data encrypted, and I accept the overhead. I want to be sure that I connect to a server that I trust.
*/
VERIFY_CA("verify-ca"),
/**
* I want my data encrypted, and I accept the overhead. I want to be sure that I connect to a server I trust, and that it's the one I specify.
*/
VERIFY_FULL("verify-full"),
/**
* I want to use a SSL tunnel instead of following Postgres SSL handshake protocol.
*/
TUNNEL("tunnel");

Care to elaborate?

Maybe I haven't found the right place, but how can I use this enumeration when I want to create new connection?

ConnectionFactories.get(
    ConnectionFactoryOptions
        .builder()
        .from(ConnectionFactoryOptions.parse("r2dbc://localhost:3306/my_database"))
        .option(ConnectionFactoryOptions.SSL, true) // sets sslmode to verify-full
        .option(ConnectionFactoryOptions.SSL, false) // sets sslmode to disable
        .option(ConnectionFactoryOptions.SSL, SSLMode.REQUIRE) // this is not possible
        .option(ConnectionFactoryOptions.SSL_MODE, SSLMode.REQUIRE) // maybe we can add a new option
        .build()
)

Check our the ConnectionFactory options at https://github.com/pgjdbc/r2dbc-postgresql#getting-started

Using an URL r2dbc://localhost:3306/my_database?sslMode=PREFER or programmatically, option(Option.valueOf("sslMode"), SLMode.REQUIRE) (option(Option.valueOf("sslMode"), "require")) will get you there.

ConnectionFactory options are pretty lenient so that you can use either String-based values or the Driver-specific API to enable various ways of configuration.

ConnectionFactoryOptions.SSL is provided by the R2DBC Spec that doesn't go into details of database-specific config details. Some database have binary SSL options only (on, off), some databases use more elaborate settings so it's not possible to cover all of these by the spec.

Each driver comes with its own config interpretation. For Postgres, if you set the SSL flag, then we default to the most secure variant. If you do not configure the SSL option, then you can use sslMode to specify how the SSL functionality should be configured.

I wasn't aware of the Option.valueOf("sslMode") way. Thank you!