Add support for sslnegotiation=direct (PostgreSQL 17)#3688
Open
Shion1305 wants to merge 1 commit into
Open
Conversation
PostgreSQL 17 added the `sslnegotiation` connection parameter, which
allows clients to start the TLS handshake immediately after the TCP
connection ("direct" negotiation) instead of first sending an SSLRequest
packet and waiting for the server's S/N reply ("postgres" negotiation,
the default and prior behavior). Direct negotiation saves one network
round-trip and works with protocol-agnostic TLS tooling.
- connection.js: extract the TLS upgrade into upgradeToSSL(); in direct
mode upgrade the socket right after connect (skipping the SSLRequest
exchange) and advertise the `postgresql` ALPN protocol as the server
requires.
- client.js: forward sslNegotiation to the Connection and skip
requestSsl() in direct mode.
- connection-parameters.js: read sslnegotiation from config /
PGSSLNEGOTIATION, validate it is `postgres` or `direct`, require SSL to
be enabled for `direct`, and include it in the libpq connection string.
- pg-connection-string: parse the sslnegotiation query param and enable
SSL automatically when `direct` is requested without other SSL config.
- docs: document the new option.
- tests: cover connection-string parsing, connection-parameters
validation, and the direct-vs-traditional connection behavior
(no SSLRequest packet, ALPN set only for direct).
Closes brianc#3346
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds support for PostgreSQL 17's
sslnegotiationconnection parameter. The default,postgres, keeps the existing behavior: the driver sends anSSLRequestpacket and waits for the server'sS/Nreply before starting the TLS handshake. The newdirectvalue starts the TLS handshake immediately after the TCP connection is established, saving a network round-trip and allowing protocol-agnostic TLS tooling. As in libpq,directadvertises thepostgresqlALPN protocol during the handshake and requires SSL to be enabled.Usage mirrors the existing
ssloptions — via config object,PGSSLNEGOTIATION, or connection string:Closes #3346.
A few design notes:
directrequires SSL to be enabled (ConnectionParametersthrows otherwise), matching libpq's rule that direct negotiation is only allowed withsslmode=requireor higher so there's no silent plaintext fallback. In a connection string,sslnegotiation=directenables SSL automatically when no other SSL option is present.connection.jswas extracted intoupgradeToSSL()so both negotiation styles share it; only thedirectpath skips theSSLRequest/S-byte exchange and setsALPNProtocols.sslnegotiationis also added to the libpq connection string for the native (pg-native) path.ConnectionParametersvalidation, and the connection behavior itself (noSSLRequestpacket is written in direct mode, and ALPN is set only for direct). I followed pgjdbc/libpq for the parameter semantics.I've verified this against a personal PostgreSQL 17.5 instance configured to require direct SSL. With
sslnegotiation=direct, the client establishes TLS 1.3, negotiates thepostgresqlALPN protocol, and runs queries successfully;pg_stat_sslconfirms the connection is encrypted server-side. The same server rejects the traditionalsslnegotiation=postgreshandshake withECONNRESET, confirming the two negotiation styles take genuinely different code paths.