sqlx icon indicating copy to clipboard operation
sqlx copied to clipboard

feat(postgres): Support direct SSL connections to Postgres 17+ servers

Open danielfrankcom opened this issue 8 months ago • 4 comments

This PR adds support for the sslnegotiation connection parameter which has been available since Postgres 17.0. See the libpq reference here and the 17.0 release notes.

The motivation for this setting is to allow clients to skip the Postgres-specific preample while establishing a secure connection to the server. The benefits of this are:

  • It is faster, since there are fewer messages required to set up the connection.
  • It make it easier to work with certain proxies. mitmproxy for example doesn't understand the Postgres protocol, but using a direct connection allows it to process Postgres traffic. I have seen corporate proxies that have incompatibilities with the Postgres protocol, and cause issues for clients.

Postgres 17+ servers support this option, and several other drivers support it client side. Users of sqlx can now configure the client to connect directly instead of doing the preamble. For older server versions, there is a sslnegotiation=postgres fallback which uses the traditional preamble.

As part of this change I have started including the postgresql ALPN in the client SSL handshake, since Postgres servers require it when establishing a direct connection. From my testing (and by its design) it should be ignored by servers that do not pay attention to it.

Does your PR solve an issue?

~~There doesn't seem to be an issue for this feature at the moment. I can create one if required. The closest I could find was #3264, but the Postgres 17 feature was just mentioned there, and the actual issue seemed to be unrelated.~~

I created a companion issue, fixes #3880.

Is this a breaking change?

Not as far as I can tell.

Though this feature is only supported in newer Postgres versions (17+), the default of PgSslNegotiation::Postgres maintains existing behaviour used by older library versions. This is shown by the fact that all Postgres 13 Docker integration tests pass in the GitHub workflows.

There are a few changes which could impact this, but I don't have enough context to determine if they constitute breaking changes. Please consider the following:

  • Postgres connections now set a TLS ALPN of postgresql. Servers typically ignore this (the Postgres 13 Docker integration tests show this) if they don't care about the ALPN value. It's possible in some use case the ALPN causes a server to reject the connection, but I haven't seen this in practice.
  • The build_url method now includes the sslnegotiation setting. I'm not sure how this method is used in practice outside of the test suite, but the additional parameter may impact users relying on the structure of that return value.

danielfrankcom avatar May 30 '25 20:05 danielfrankcom

Pushed an update which adds the new parameter to the doc.md file which I missed originally.

danielfrankcom avatar May 30 '25 21:05 danielfrankcom

Hi @abonander. Is there anything we could do to help prioritizing/reviewing/merging this PR?

Thanks!

wcmjunior avatar Jul 22 '25 19:07 wcmjunior

Push is a rebase onto the latest main to pull in changes to the sqlx.yml workflow.

danielfrankcom avatar Aug 21 '25 20:08 danielfrankcom

Hi @abonander, we would really appreciate this feature as well as we have an envoy proxy on top of Postgres which works with direct ssl negotiation only.

Thank you for the amazing library btw :)

WaqasAliAbbasi avatar Nov 26 '25 11:11 WaqasAliAbbasi